1
0
mirror of https://github.com/anope/anope.git synced 2026-07-08 08:43:14 +02:00

Rewrote how commands are handled within Anope.

This allows naming commands and having spaces within command names.
This commit is contained in:
Adam
2011-07-14 02:31:12 -04:00
parent 924f6849fe
commit f858164dee
227 changed files with 8808 additions and 12352 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Only install example.chk and example.conf from this directory
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
set(DATA example.chk example.conf mysql/tables.sql)
set(DATA example.chk commands.example.conf example.conf modules.example.conf mysql/tables.sql)
install(FILES ${DATA}
DESTINATION data
)
+336
View File
@@ -0,0 +1,336 @@
/*
* [RECOMMENDED] Core modules and command configuration
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Sane defaults are below.
*/
module { name = "help" }
command { service = "BotServ"; name = "HELP"; command = "generic/help"; }
command { service = "ChanServ"; name = "HELP"; command = "generic/help"; }
command { service = "Global"; name = "HELP"; command = "generic/help"; }
command { service = "HostServ"; name = "HELP"; command = "generic/help"; }
command { service = "MemoServ"; name = "HELP"; command = "generic/help"; }
command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
command { service = "OperServ"; name = "HELP"; command = "generic/help"; }
module { name = "bs_assign" }
command { service = "BotServ"; name = "ASSIGN"; command = "botserv/assign"; }
command { service = "BotServ"; name = "UNASSIGN"; command = "botserv/unassign"; }
module { name = "bs_badwords" }
command { service = "BotServ"; name = "BADWORDS"; command = "botserv/badwords"; }
module { name = "bs_bot" }
command { service = "BotServ"; name = "BOT"; command = "botserv/bot"; }
module { name = "bs_botlist" }
command { service = "BotServ"; name = "BOTLIST"; command = "botserv/botlist"; }
module { name = "bs_control" }
command { service = "BotServ"; name = "ACT"; command = "botserv/act"; }
command { service = "BotServ"; name = "SAY"; command = "botserv/say"; }
module { name = "bs_info" }
command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
module { name = "bs_kick" }
command { service = "BotServ"; name = "KICK"; command = "botserv/kick"; }
module { name = "bs_set" }
command { service = "BotServ"; name = "SET"; command = "botserv/set"; }
module { name = "cs_access" }
command { service = "ChanServ"; name = "ACCESS"; command = "chanserv/access"; }
command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; }
module { name = "cs_akick" }
command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; }
module { name = "cs_ban" }
command { service = "ChanServ"; name = "BAN"; command = "chanserv/ban"; }
command { service = "ChanServ"; name = "KB"; command = "chanserv/ban"; }
module { name = "cs_clearusers" }
command { service = "ChanServ"; name = "CLEARUSERS"; command = "chanserv/clearusers"; }
module { name = "cs_clone" }
command { service = "ChanServ"; name = "CLONE"; command = "chanserv/clone"; }
module { name = "cs_drop" }
command { service = "ChanServ"; name = "DROP"; command = "chanserv/drop"; }
module { name = "cs_getkey" }
command { service = "ChanServ"; name = "GETKEY"; command = "chanserv/getkey"; }
module { name = "cs_info" }
command { service = "ChanServ"; name = "INFO"; command = "chanserv/info"; }
module { name = "cs_invite" }
command { service = "ChanServ"; name = "INVITE"; command = "chanserv/invite"; }
module { name = "cs_kick" }
command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
command { service = "ChanServ"; name = "K"; command = "chanserv/kick"; }
module { name = "cs_list" }
command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; }
module { name = "cs_mode" }
command { service = "ChanServ"; name = "MODE"; command = "chanserv/mode"; }
module { name = "cs_modes" }
command { service = "ChanServ"; name = "OP"; command = "chanserv/op"; }
command { service = "ChanServ"; name = "DEOP"; command = "chanserv/deop"; }
command { service = "ChanServ"; name = "HALFOP"; command = "chanserv/halfop"; }
command { service = "ChanServ"; name = "DEHALFOP"; command = "chanserv/dehalfop"; }
command { service = "ChanServ"; name = "VOICE"; command = "chanserv/voice"; }
command { service = "ChanServ"; name = "DEVOICE"; command = "chanserv/devoice"; }
command { service = "ChanServ"; name = "PROTECT"; command = "chanserv/protect"; }
command { service = "ChanServ"; name = "DEPROTECT"; command = "chanserv/deprotect"; }
command { service = "ChanServ"; name = "OWNER"; command = "chanserv/owner"; }
command { service = "ChanServ"; name = "DEOWNER"; command = "chanserv/deowner"; }
module { name = "cs_register" }
command { service = "ChanServ"; name = "REGISTER"; command = "chanserv/register"; }
module { name = "cs_set" }
command { service = "ChanServ"; name = "SET"; command = "chanserv/set"; }
module { name = "cs_saset" }
command { service = "ChanServ"; name = "SASET"; command = "chanserv/saset"; }
module { name = "cs_set_bantype" }
command { service = "ChanServ"; name = "SET BANTYPE"; command = "chanserv/set/bantype"; }
command { service = "ChanServ"; name = "SASET BANTYPE"; command = "chanserv/saset/bantype"; }
module { name = "cs_set_description" }
command { service = "ChanServ"; name = "SET DESCRIPTION"; command = "chanserv/set/description"; }
command { service = "ChanServ"; name = "SASET DESCRIPTION"; command = "chanserv/saset/description"; }
module { name = "cs_set_founder" }
command { service = "ChanServ"; name = "SET FOUNDER"; command = "chanserv/set/founder"; }
command { service = "ChanServ"; name = "SASET FOUNDER"; command = "chanserv/saset/founder"; }
module { name = "cs_set_keeptopic" }
command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
command { service = "ChanServ"; name = "SASET KEEPTOPIC"; command = "chanserv/saset/keeptopic"; }
module { name = "cs_set_opnotice" }
command { service = "ChanServ"; name = "SET OPNOTICE"; command = "chanserv/set/opnotice"; }
command { service = "ChanServ"; name = "SASET OPNOTICE"; command = "chanserv/saset/opnotice"; }
module { name = "cs_set_peace" }
command { service = "ChanServ"; name = "SET PEACE"; command = "chanserv/set/peace"; }
command { service = "ChanServ"; name = "SASET PEACE"; command = "chanserv/saset/peace"; }
module { name = "cs_set_persist" }
command { service = "ChanServ"; name = "SET PERSIST"; command = "chanserv/set/persist"; }
command { service = "ChanServ"; name = "SASET PERSIST"; command = "chanserv/saset/persist"; }
module { name = "cs_set_private" }
command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/private"; }
command { service = "ChanServ"; name = "SASET PRIVATE"; command = "chanserv/saset/private"; }
module { name = "cs_set_restricted" }
command { service = "ChanServ"; name = "SET RESITRCTED"; command = "chanserv/set/restricted"; }
command { service = "ChanServ"; name = "SASET RESITRCTED"; command = "chanserv/saset/restricted"; }
module { name = "cs_set_secure" }
command { service = "ChanServ"; name = "SET SECURE"; command = "chanserv/set/secure"; }
command { service = "ChanServ"; name = "SASET SECURE"; command = "chanserv/saset/secure"; }
module { name = "cs_set_securefounder" }
command { service = "ChanServ"; name = "SET SECUREFOUNDER"; command = "chanserv/set/securefounder"; }
command { service = "ChanServ"; name = "SASET SECUREFOUNDER"; command = "chanserv/saset/securefounder"; }
module { name = "cs_set_secureops" }
command { service = "ChanServ"; name = "SET SECUREOPS"; command = "chanserv/set/secureops"; }
command { service = "ChanServ"; name = "SASET SECUREOPS"; command = "chanserv/saset/secureops"; }
module { name = "cs_set_signkick" }
command { service = "ChanServ"; name = "SET SIGNKICK"; command = "chanserv/set/signkick"; }
command { service = "ChanServ"; name = "SASET SIGNKICK"; command = "chanserv/saset/signkick"; }
module { name = "cs_set_successor" }
command { service = "ChanServ"; name = "SET SUCCESSOR"; command = "chanserv/set/successor"; }
command { service = "ChanServ"; name = "SASET SUCCESSOR"; command = "chanserv/saset/successor"; }
module { name = "cs_set_topiclock" }
command { service = "ChanServ"; name = "SET TOPICLOCK"; command = "chanserv/set/topiclock"; }
command { service = "ChanServ"; name = "SASET TOPICLOCK"; command = "chanserv/saset/topiclock"; }
module { name = "cs_set_xop" }
command { service = "ChanServ"; name = "SET XOP"; command = "chanserv/set/xop"; }
command { service = "ChanServ"; name = "SASET XOP"; command = "chanserv/saset/xop"; }
module { name = "cs_saset_noexpire" }
command { service = "ChanServ"; name = "SET NOEXPIRE"; command = "chanserv/set/noexpire"; }
module { name = "cs_status" }
command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
module { name = "cs_suspend" }
command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend"; }
command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; }
module { name = "cs_topic" }
command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; }
module { name = "cs_unban" }
command { service = "ChanServ"; name = "UNBAN"; command = "chanserv/unban"; }
module { name = "cs_xop" }
command { service = "ChanServ"; name = "QOP"; command = "chanserv/qop"; }
command { service = "ChanServ"; name = "SOP"; command = "chanserv/sop"; }
command { service = "ChanServ"; name = "AOP"; command = "chanserv/aop"; }
command { service = "ChanServ"; name = "HOP"; command = "chanserv/hop"; }
command { service = "ChanServ"; name = "VOP"; command = "chanserv/vop"; }
module { name = "gl_global" }
command { service = "Global"; name = "GLOBAL"; command = "global/global"; }
module { name = "hs_del" }
command { service = "HostServ"; name = "DEL"; command = "hostserv/del"; }
command { service = "HostServ"; name = "DELALL"; command = "hostserv/delall"; }
module { name = "hs_group" }
command { service = "HostServ"; name = "GROUP"; command = "hostserv/group"; }
module { name = "hs_list" }
command { service = "HostServ"; name = "LIST"; command = "hostserv/list"; }
module { name = "hs_off" }
command { service = "HostServ"; name = "OFF"; command = "hostserv/off"; }
module { name = "hs_on" }
command { service = "HostServ"; name = "ON"; command = "hostserv/on"; }
module { name = "hs_set" }
command { service = "HostServ"; name = "SET"; command = "hostserv/set"; }
command { service = "HostServ"; name = "SETALL"; command = "hostserv/setall"; }
module { name = "ms_cancel" }
command { service = "MemoServ"; name = "CANCEL"; command = "memoserv/cancel"; }
module { name = "ms_check" }
command { service = "MemoServ"; name = "CHECK"; command = "memoserv/check"; }
module { name = "ms_del" }
command { service = "MemoServ"; name = "DEL"; command = "memoserv/del"; }
module { name = "ms_ignore" }
command { service = "MemoServ"; name = "IGNORE"; command = "memoserv/ignore"; }
module { name = "ms_info" }
command { service = "MemoServ"; name = "INFO"; command = "memoserv/info"; }
module { name = "ms_list" }
command { service = "MemoServ"; name = "LIST"; command = "memoserv/list"; }
module { name = "ms_read" }
command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
module { name = "ms_rsend" }
command { service = "MemoServ"; name = "RSEND"; command = "memoserv/rsend"; }
module { name = "ms_send" }
command { service = "MemoServ"; name = "SEND"; command = "memoserv/send"; }
module { name = "ms_sendall" }
command { service = "MemoServ"; name = "SENDALL"; command = "memoserv/sendall"; }
module { name = "ms_set" }
command { service = "MemoServ"; name = "SET"; command = "memoserv/set"; }
module { name = "ms_staff" }
command { service = "MemoServ"; name = "STAFF"; command = "memoserv/staff"; }
module { name = "ns_access" }
command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
module { name = "ns_ajoin" }
command { service = "NickServ"; name = "AJOIN"; command = "nickserv/ajoin"; }
module { name = "ns_alist" }
command { service = "NickServ"; name = "ALIST"; command = "nickserv/alist"; }
module { name = "ns_cert" }
command { service = "NickServ"; name = "CERT"; command = "nickserv/cert"; }
module { name = "ns_drop" }
command { service = "NickServ"; name = "DROP"; command = "nickserv/drop"; }
module { name = "ns_getemail" }
command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"; }
module { name = "ns_getpass" }
command { service = "NickServ"; name = "GETPASS"; command = "nickserv/getpass"; }
module { name = "ns_ghost" }
command { service = "NickServ"; name = "GHOST"; command = "nickserv/ghost"; }
module { name = "ns_group" }
command { service = "NickServ"; name = "GLIST"; command = "nickserv/glist"; }
command { service = "NickServ"; name = "GROUP"; command = "nickserv/group"; }
command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup"; }
module { name = "ns_identify" }
command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"; }
module { name = "ns_info" }
command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
module { name = "ns_list" }
command { service = "NickServ"; name = "LIST"; command = "nickserv/list"; }
module { name = "ns_logout" }
command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
module { name = "ns_recover" }
command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover"; }
module { name = "ns_register" }
command { service = "NickServ"; name = "CONFIRM"; command = "nickserv/confirm"; }
command { service = "NickServ"; name = "REGISTER"; command = "nickserv/register"; }
command { service = "NickServ"; name = "RESEND"; command = "nickserv/resend"; }
module { name = "ns_release" }
command { service = "NickServ"; name = "RELEASE"; command = "nickserv/release"; }
module { name = "ns_resetpass" }
command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpass"; }
module { name = "ns_saset" }
command { service = "NickServ"; name = "SASET"; command = "nickserv/saset"; }
command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/saset/display"; }
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; }
module { name = "ns_set" }
command { service = "NickServ"; name = "SET"; command = "nickserv/set"; }
command { service = "NickServ"; name = "SET DISPLAY"; command = "nickserv/set/display"; }
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
module { name = "ns_set_autoop" }
command { service = "NickServ"; name = "SET AUTOOP"; command = "nickserv/set/autoop"; }
command { service = "NickServ"; name = "SASET AUTOOP"; command = "nickserv/saset/autoop"; }
module { name = "ns_set_email" }
command { service = "NickServ"; name = "SET EMAIL"; command = "nickserv/set/email"; }
command { service = "NickServ"; name = "SASET EMAIL"; command = "nickserv/saset/email"; }
module { name = "ns_set_greet" }
command { service = "NickServ"; name = "SET GREET"; command = "nickserv/set/greet"; }
command { service = "NickServ"; name = "SASET GREET"; command = "nickserv/saset/greet"; }
module { name = "ns_set_hide" }
command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/hide"; }
module { name = "ns_set_kill" }
command { service = "NickServ"; name = "SET KILL"; command = "nickserv/set/kill"; }
command { service = "NickServ"; name = "SASET KILL"; command = "nickserv/saset/kill"; }
module { name = "ns_set_language" }
command { service = "NickServ"; name = "SET LANGUAGE"; command = "nickserv/set/language"; }
command { service = "NickServ"; name = "SASET LANGUAGE"; command = "nickserv/saset/language"; }
module { name = "ns_set_message" }
command { service = "NickServ"; name = "SET MESSAGE"; command = "nickserv/set/message"; }
command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; }
module { name = "ns_set_private" }
command { service = "NickServ"; name = "SET PRIVATE"; command = "nickserv/set/private"; }
command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/set/private"; }
module { name = "ns_set_secure" }
command { service = "NickServ"; name = "SET SECURE"; command = "nickserv/set/secure"; }
command { service = "NickServ"; name = "SASET SECURE"; command = "nickserv/set/secure"; }
module { name = "ns_saset_noexpire" }
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; }
module { name = "ns_sendpass" }
command { service = "NickServ"; name = "SENDPASS"; command = "nickserv/sendpass"; }
module { name = "ns_status" }
command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
module { name = "ns_suspend" }
command { service = "NickServ"; name = "SUSPEND"; command = "nickserv/suspend"; }
command { service = "NickServ"; name = "UNSUSPEND"; command = "nickserv/unsuspend"; }
module { name = "ns_update" }
command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
module { name = "os_akill" }
command { service = "OperServ"; name = "AKILL"; command = "operserv/akill"; }
module { name = "os_chankill" }
command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"; }
module { name = "os_list" }
command { service = "OperServ"; name = "CHANLIST"; command = "operserv/chanlist"; }
command { service = "OperServ"; name = "USERLIST"; command = "operserv/userlist"; }
module { name = "os_config" }
command { service = "OperServ"; name = "CONFIG"; command = "operserv/config"; }
module { name = "os_forbid" }
command { service = "OperServ"; name = "FORBID"; command = "operserv/forbid"; }
module { name = "os_ignore" }
command { service = "OperServ"; name = "IGNORE"; command = "operserv/ignore"; }
module { name = "os_jupe" }
command { service = "OperServ"; name = "JUPE"; command = "operserv/jupe"; }
module { name = "os_kick" }
command { service = "OperServ"; name = "KICK"; command = "operserv/kick"; }
module { name = "os_login" }
command { service = "OperServ"; name = "LOGIN"; command = "operserv/login"; }
module { name = "os_mode" }
command { service = "OperServ"; name = "MODE"; command = "operserv/mode"; }
module { name = "os_modinfo" }
command { service = "OperServ"; name = "MODINFO"; command = "operserv/modinfo"; }
command { service = "OperServ"; name = "MODLIST"; command = "operserv/modlist"; }
module { name = "os_module" }
command { service = "OperServ"; name = "MODLOAD"; command = "operserv/modload"; }
command { service = "OperServ"; name = "MODRELOAD"; command = "operserv/modreload"; }
command { service = "OperServ"; name = "MODUNLOAD"; command = "operserv/modunload"; }
module { name = "os_news" }
command { service = "OperServ"; name = "LOGONNEWS"; command = "operserv/logonnews"; }
command { service = "OperServ"; name = "OPERNEWS"; command = "operserv/opernews"; }
command { service = "OperServ"; name = "RANDOMNEWS"; command = "operserv/randomnews"; }
module { name = "os_noop" }
command { service = "OperServ"; name = "NOOP"; command = "operserv/noop"; }
module { name = "os_oline" }
command { service = "OperServ"; name = "OLINE"; command = "operserv/oline"; }
module { name = "os_oper" }
command { service = "OperServ"; name = "OPER"; command = "operserv/oper"; }
module { name = "os_reload" }
command { service = "OperServ"; name = "RELOAD"; command = "operserv/reload"; }
module { name = "os_session" }
command { service = "OperServ"; name = "EXCEPTION"; command = "operserv/exception"; }
command { service = "OperServ"; name = "SESSION"; command = "operserv/session"; }
module { name = "os_set" }
command { service = "OperServ"; name = "SET"; command = "operserv/set"; }
module { name = "os_shutdown" }
command { service = "OperServ"; name = "QUIT"; command = "operserv/quit"; }
command { service = "OperServ"; name = "RESTART"; command = "operserv/restart"; }
command { service = "OperServ"; name = "SHUTDOWN"; command = "operserv/shutdown"; }
module { name = "os_stats" }
command { service = "OperServ"; name = "STATS"; command = "operserv/stats"; }
module { name = "os_svsnick" }
command { service = "OperServ"; name = "SVSNICK"; command = "operserv/svsnick"; }
module { name = "os_sxline" }
command { service = "OperServ"; name = "SNLINE"; command = "operserv/snline"; }
command { service = "OperServ"; name = "SQLINE"; command = "operserv/sqline"; }
command { service = "OperServ"; name = "SZLINE"; command = "operserv/szline"; }
module { name = "os_update" }
command { service = "OperServ"; name = "UPDATE"; command = "operserv/update"; }
+743 -1515
View File
File diff suppressed because it is too large Load Diff
+528
View File
@@ -0,0 +1,528 @@
/*
* [OPTIONAL] Non-Core Modules
*
* The following blocks are used to load all non-core modules, including 3rd-party modules.
* Modules can be prevented from loading by commenting out the line, other modules can be added by
* adding a module block. These modules will be loaded prior to Services connecting to your network.
*/
/*
* cs_appendtopic
*
* Adds the APPENDTOPIC command to ChanServ, which allows users to easially append text to
* the end of existing channel topics.
*/
module { name = "cs_appendtopic" }
command { service = "ChanServ"; name = "APPENDTOPIC"; command = "chanserv/appendtopic"; }
/*
* cs_enforce
*
* Adds the ENFORCE commad to ChanServ, which allows enforcing various channel settings like
* SECUREOPS and RESTRICTED.
*/
module { name = "cs_enforce" }
command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce"; }
/*
* cs_entrymsg
*
* Allows you to set entry messages on your channel, which are shown to anyone
* who joins.
*/
module { name = "cs_entrymsg" }
command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; }
cs_entrymsg
{
/* The maximum number of entrymsgs allowed per channel. If not set, defaults to 5. */
maxentries = 5
}
/*
* cs_set_misc
*
* Allows you to create misc /chanserv set commands, and have the data
* show up in /chanserv info
*/
module { name = "cs_set_misc" }
cs_set_misc
{
/* The name of the command */
name = "OINFO"
/* A short description of the command */
desc = "Associate oper only information to this channel"
/* Set to yes if only opers and privileged users can set it and see it */
privileged = yes
}
cs_set_misc
{
name = "URL"
desc = "Associate a URL with the channel"
}
cs_set_misc
{
name = "EMAIL"
desc = "Associate an EMail with the channel"
}
/*
* db_plain
*
* This is the default flatfile database format. You must have at least one database
* module loaded or Anope will not save databases!
*/
module { name = "db_plain" }
db_plain
{
/*
* The database db_plain should use
*/
database = "anope.db"
}
/*
* db_mysql and db_mysql_live
*
* Enables (live) MySQL support.
*
* The db_mysql_live module is an extension to db_mysql, and should only be used if
* db_mysql is being used. This module pulls data in real time from SQL as it is
* requested by the core as a result of someone executing commands.
*
* This effectively allows you to edit your database and have it be immediately
* reflected back in Anope.
*
* For information on how to make db_mysql_live use asynchronous queries see
* m_async_commands.
*
* At this time db_mysql_live only supports pulling data in real time from the three
* main tables: anope_cs_info, anope_ns_alias, and anope_ns_core.
*/
#module { name = "db_mysql" }
#module { name = "db_mysql_live" }
/*
* hs_request
*
* Allows users to request vhosts which opers may then view, accept or deny
*/
module { name = "hs_request" }
command { service = "HostServ"; name = "REQUEST"; command = "hostserv/request"; }
command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/active"; }
command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; }
command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; }
hs_request
{
/*
* If set, Services will send a memo to the user requesting a vHost when it's been
* approved or rejected.
*/
#memouser = yes
/*
* If set, Services will send a memo to all Services staff when a new vHost is requested.
*/
#memooper = yes
}
/*
* m_async_commands
*
* Threads for each command executed by users. You should
* only load this if you are using a module designed to work with this.
*
* If this is loaded with db_mysql_live then Anope will support
* processing multiple commands at once which will negate the "lag"
* issues caused from the overhead of SQL queries by db_mysql_live.
*
* Note that this module is currently EXPERIMENTAL and you should report
* any bugs you find.
*/
#module { name = "m_async_commands" }
/* m_dnsbl
*
* Allows configurable DNS blacklists to check connecting users against. If a user
* is found on the blacklist they will be immediately banned. This is a crucial module
* to prevent bot attacks.
*/
module { name = "m_dnsbl" }
m_dnsbl
{
/*
* If set, Services will check clients against the DNSBLs when services connect to its uplink.
* This is not recommended, and on large networks will open a very large amount of DNS queries.
* Whilst services are not drastically affected by this, your nameserver/DNSBL might care.
*/
check_on_connect = no
/*
* If set, Services will check clients when coming back from a netsplit. This can cause a large number
* of DNS queries open at once. Whilst services are not drastically affected by this, your nameserver/DNSBL
* might care.
*/
check_on_netburst = no
/*
* If set, OperServ will add clients found in the DNSBL to the akill list. Without it, OperServ simply sends
* a timed G/K-line to the IRCd and forgets about it. Can be useful if your akill list is being fill up by bots.
*/
add_to_akill = yes
}
blacklist
{
/* Name of the blacklist */
name = "rbl.efnetrbl.org"
/* How long to set the ban for */
time = 4h
/* Reason for akill.
* %n is the nick of the user
* %u is the ident/username of the user
* %g is the realname of the user
* %h is the hostname of the user
* %i is the IP of the user
* %r is the reason (configured below). Will be nothing if not configured.
* %N is the network name set in networkinfo:networkname
*/
reason = "You are listed in the efnet RBL, visit http://rbl.efnetrbl.org/?i=%i for info"
/* Replies to ban and their reason. If this is totally ommited all replies get banned */
1 = "Open Proxy"
/* Don't ban for result 2 or 3 */
#2 = "spamtrap666"
#3 = "spamtrap50"
4 = "TOR"
5 = "Drones / Flooding"
}
blacklist
{
name = "dnsbl.dronebl.org"
time = 4h
reason = "You have a host listed in the DroneBL. For more information, visit http://dronebl.org/lookup_branded.do?ip=%i&network=%N"
}
/* m_helpchan
*
* Gives users who are op in the specified help channel usermode +h (helpop).
*/
#module { name = "m_helpchan" }
m_helpchan
{
helpchannel = "#help"
}
/*
* m_ldap
*
* This module allows other modules to use LDAP. By itself, this module does nothing useful.
*/
#module { name = "m_ldap" }
ldap
{
server = "ldap://127.0.0.1"
port = 389
admin_binddn = "cn=Manager,dc=anope,dc=org"
admin_password = "secret"
}
/*
* m_ldap_authentication
*
* This module allows many commands such as IDENTIFY, RELEASE, RECOVER, GHOST, etc. use
* LDAP to authenticate users. Requires m_ldap.
*/
#module { name = "m_ldap_authentication" }
m_ldap_authentication
{
/*
* The distinguished name we should bind to when a user tries to identify.
*/
binddn = "ou=users,dc=anope,dc=org"
/*
* The object class used by LDAP to store user account information.
* Used for adding new users to LDAP if disable_ns_register is false
*/
object_class = "anopeUser"
/*
* The attribute value used for account names.
*/
username_attribute = "uid"
/*
* The attribute value used for email addresses.
* This directive is optional.
*/
email_attribute = "email"
/*
* The attribute value used for passwords.
* Used when registering new accounts in LDAP.
*/
password_attribute = "userPassword"
/*
* Enable to have this module disable /nickserv register.
*/
disable_ns_register = false
/*
* The reason to give the users who try to /ns register if
* disable_ns_register is enabled.
*/
#disable_reason = "To register on this network visit http://some.misconfigured.site/register"
}
/*
* m_ldap_oper
*
* This module dynamically ties users to Anope opertypes when they identify
* via LDAP group membership. Requires m_ldap.
*
* Note that this doesn't give the user privileges on the IRCd, only in Services.
*/
#module { name = "m_ldap_oper" }
m_ldap_oper
{
/*
* An optional binddn to use when searching for groups.
* %a is replaced with the account name of the user.
*/
#binddn = "cn=Manager,dc=anope,dc=org"
/*
* An optional password to bind with.
*/
#password = "secret"
/*
* The base DN where the groups are.
*/
basedn = "ou=groups,dc=anope,dc=org"
/*
* The filter to use when searching for users.
* %a is replaced with the account name of the user.
*/
filter = "(member=uid=%a,ou=users,dc=anope,dc=org)"
/*
* The attribute of the group that is the name of the opertype.
* The cn attribute should match a known opertype in the config.
*/
opertype_attribute = "cn"
}
/*
* m_mysql
*
* This module allows other modules (db_mysql/db_mysql_live) to use MySQL.
* Be sure you have imported the table schema with mydbgen before
* trying to use MySQL
*/
#module { name = "m_mysql" }
mysql
{
database = "anope"
server = "127.0.0.1"
username = "anope"
password = "mypassword"
port = 3306
}
/*
* m_ssl
*
* This module uses SSL to connect to the uplink server(s)
*/
module { name = "m_ssl" }
/*
* m_statusupdate
*
* This module automatically updates users status on channels when the
* channel's access list is modified.
*/
module { name = "m_statusupdate" }
/*
* m_xmlrpc
*
* Allows remote applications (websites) to execute queries in real time to retrieve data from Anope.
* By itself this module does nothing, but allows other modules (m_xmlrpc_main) to receive and send XMLRPC queries.
*/
#module { name = "m_xmlrpc" }
m_xmlrpc
{
/* IP to listen on */
bindip = "127.0.0.1"
/* Port to listen on */
port = 26673
/* Enable for IPv6 */
ipv6 = no
/* If enabled, requires m_ssl to be loaded */
ssl = no
/* IPs allowed to connect (separate with spaces), this should be secured. We also recommend you firewall this
* with an outside program to increase security.
*/
allowed = "127.0.0.0/24"
}
/*
* m_xmlrpc_main
*
* Adds the main XMLRPC core functions.
* Requires m_xmlrpc.
*/
#module { name = "m_xmlrpc_main" }
/*
* ns_maxemail
*
* Limits how many times the same email address may be used in Anope
* to register accounts.
*/
module { name = "ns_maxemail" }
ns_maxemail
{
/*
* The limit to how many registered nicks can use the same e-mail address. If set to 0 or left
* commented, there will be no limit enforced when registering new accounts or using
* /msg NickServ SET EMAIL.
*/
#maxemails = 1
}
/*
* ns_set_misc
*
* Allows you to create misc /nickserv set commands, and have the data
* show up in /nickserv info
*/
module { name = "ns_set_misc" }
ns_set_misc
{
name = "OINFO"
desc = "Associate oper only information to this nick"
privileged = yes
}
ns_set_misc
{
name = "URL"
desc = "Associate a URL with the nick"
}
ns_set_misc
{
name = "ICQ"
desc = "Associate an ICQ number with the nick"
}
/*
* os_defcon
*
* Allows you to set services in defcon mode, which can be used to restrict services access
* during bot attacks.
*/
#module { name = "os_defcon" }
command { service = "OperServ"; name = "DEFCON"; command = "operserv/defcon"; }
defcon
{
/*
* Default DefCon level (1-5) to use when starting Services up. Level 5 constitutes normal operation
* while level 1 constitutes the most restrictive operation. If this setting is left out or set to
* 0, DefCon will be disabled and the rest of this block will be ignored.
*/
#defaultlevel = 5
/*
* The following 4 directives define what operations will take place when DefCon is set to levels
* 1 through 4. Each level is a list that must be separated by spaces.
*
* The following operations can be defined at each level:
* - nonewchannels: Disables registering new channels
* - nonewnicks: Disables registering new nicks
* - nomlockchanges: Disables changing MLOCK on registered channels
* - forcechanmodes: Forces all channels to have the modes given in the later chanmodes directive
* - reducedsessions: Reduces the session limit to the value given in the later sessionlimit directive
* - nonewclients: KILL any new clients trying to connect
* - operonly: Services will ignore all non-IRCops
* - silentoperonly: Services will silently ignore all non-IRCops
* - akillnewclients: AKILL any new clients trying to connect
* - nonewmemos: No new memos will be sent to block MemoServ attacks
*/
level4 = "nonewchannels nonewnicks nomlockchanges reducedsessions"
level3 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions"
level2 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions silentoperonly"
level1 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions silentoperonly akillnewclients"
/*
* New session limit to use when a DefCon level is using "reduced" session limiting.
*/
#sessionlimit = 2
/*
* Length of time to add an AKILL for when DefCon is preventing new clients from connecting to the
* network.
*/
#akillexpire = 5m
/*
* The channel modes to set on all channels when the DefCon channel mode system is in use.
*
* Note 1: Choose these modes carefully, because when DefCon switches to a level which does NOT have
* the mode setting selected, Services will set the reverse on all channels, e.g. if this setting
* is +RN when DefCon is used, all channels will be set to +RN, when DefCon is removed, all
* channels will be set to -RN. You don't want to set this to +k for example, because when DefCon
* is removed all channels with -k.
*
* Note 2: MLOCKed modes will not be lost.
*/
#chanmodes = "+R"
/*
* This value can be used to automatically return the network to DefCon level 5 after the specified
* time period, just in case any IRC Operator forgets to remove a DefCon setting.
*
* This directive is optional.
*/
#timeout = 15m
/*
* If set, Services will send a global message on DefCon level changes.
*
* This directive is optional.
*/
#globalondefcon = yes
/*
* If set, Services will send the global message defined in the message directive on DefCon level
* changes.
*
* This directive is optional.
*/
#globalondefconmore = yes
/*
* Defines the message that will be sent on DefCon level changes when globalondefconmore is set.
*
* This directive is required only when globalondefconmore is set.
*/
#message = "Put your message to send your users here. Dont forget to uncomment globalondefconmore"
/*
* Defines the message that will be sent when DefCon is returned to level 5. This directive is optional,
* and will also override globalondefcon and globalondefconmore when set.
*/
#offmessage = "Services are now back to normal, sorry for any inconvenience"
/*
* Defines the reason to use when clients are KILLed or AKILLed from the network while the proper
* DefCon operation is in effect.
*/
#akillreason = "This network is currently not accepting connections, please try again later"
}
+1 -20
View File
@@ -300,21 +300,6 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` (
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_akills`
--
CREATE TABLE IF NOT EXISTS `anope_os_akills` (
`user` varchar(255) NOT NULL,
`host` varchar(255) NOT NULL,
`xby` text NOT NULL,
`reason` text NOT NULL,
`seton` int(10) unsigned NOT NULL DEFAULT '0',
`expire` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_core`
--
@@ -322,10 +307,6 @@ CREATE TABLE IF NOT EXISTS `anope_os_akills` (
CREATE TABLE IF NOT EXISTS `anope_os_core` (
`maxusercnt` int(11) NOT NULL DEFAULT '0',
`maxusertime` int(10) unsigned NOT NULL DEFAULT '0',
`akills_count` int(11) NOT NULL DEFAULT '0',
`snlines_count` int(11) NOT NULL DEFAULT '0',
`sqlines_count` int(11) NOT NULL DEFAULT '0',
`szlines_count` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
@@ -350,7 +331,7 @@ CREATE TABLE IF NOT EXISTS `anope_os_exceptions` (
--
CREATE TABLE IF NOT EXISTS `anope_os_xlines` (
`type` varchar(20) NOT NULL,
`type` varchar(1) NOT NULL,
`mask` varchar(255) NOT NULL,
`xby` text NOT NULL,
`reason` text NOT NULL,
+1 -25
View File
@@ -1,30 +1,6 @@
Anope Version 1.9.5
-------------------
** ADDED CONFIGURATION DIRECTIVES **
global:modules
global:globaloncycle
global:globaloncycledown
global:globaloncycleup
global:anonymousglobal
operserv:modules added os_forbid
** MODIFIED CONFIGURATION DIRECTIVES **
opertype:permissions added memoserv/no-limit
operserv:modules removed os_global
operserv:modules renamed os_staff to os_oper
** DELETED CONFIGURATION DIRECTIVES **
memoserv:notifyall
options:globaloncycle
options:globaloncycledown
options:globaloncycleup
options:anonymousglobal
options:socketengine
options:encryption
options:database
serverinfo:protocol
chanserv:modules removed cs_forbid
nickserv:modules removed ns_forbid
Don't even try it, get a new config and start over.
Anope Version 1.9.4
-------------------
+8 -4
View File
@@ -8,12 +8,12 @@
#ifndef BOTS_H
#define BOTS_H
#include "commands.h"
class BotInfo;
extern CoreExport Anope::insensitive_map<BotInfo *> BotListByNick;
extern CoreExport Anope::map<BotInfo *> BotListByUID;
typedef Anope::insensitive_map<BotInfo *> botinfo_map;
typedef Anope::insensitive_map<Anope::string> command_map;
/** Flags settable on a bot
*/
@@ -25,11 +25,13 @@ enum BotFlag
BI_CORE,
/* This bot can only be assigned by IRCops */
BI_PRIVATE,
/* This bot is defined in the config */
BI_CONF,
BI_END
};
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "" };
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "CONF", "" };
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
{
@@ -37,7 +39,7 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
uint32 chancount;
time_t created; /* Birth date ;) */
time_t lastmsg; /* Last time we said something */
CommandMap Commands; /* Commands on this bot */
command_map commands; /* Commands, actual name to service name */
/** Create a new bot.
* @param nick The nickname to assign to the bot.
@@ -51,6 +53,8 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
*/
virtual ~BotInfo();
void GenerateUID();
/** Change the nickname for the bot.
* @param newnick The nick to change to
*/
+14 -50
View File
@@ -18,36 +18,15 @@ class Module;
class BotInfo;
class Command;
typedef std::map<Anope::string, Command *, std::less<ci::string> > CommandMap;
/** The return value from commands.
*/
enum CommandReturn
{
MOD_CONT,
MOD_STOP
};
extern CoreExport Command *FindCommand(BotInfo *bi, const Anope::string &cmd);
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
{
CFLAG_ALLOW_UNREGISTERED,
CFLAG_ALLOW_SUSPENDED,
CFLAG_ALLOW_UNREGISTEREDCHANNEL,
CFLAG_STRIP_CHANNEL,
CFLAG_DISABLE_FANTASY
CFLAG_STRIP_CHANNEL
};
const Anope::string CommandFlagStrings[] = {
"CFLAG_ALLOW_UNREGISTERED",
"CFLAG_ALLOW_SUSPENDED",
"CFLAG_ALLOW_UNREGISTEREDCHANNEL",
"CFLAG_STRIP_CHANNEL",
"CFLAG_DISABLE_FANTASY",
""
};
@@ -56,14 +35,14 @@ struct CoreExport CommandSource
{
/* User executing the command */
User *u;
/* Channel (if applicable) */
ChannelInfo *ci;
/* Channel the command was executed on (fantasy) */
Channel *c;
/* 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;
/* The actual name of the command being executed */
Anope::string command;
std::list<Anope::string> reply;
@@ -75,38 +54,40 @@ struct CoreExport CommandSource
/** Every services command is a class, inheriting from Command.
*/
class CoreExport Command : public Flags<CommandFlag>, public Base
class CoreExport Command : public Service, public Flags<CommandFlag>
{
Anope::string desc;
std::vector<Anope::string> syntax;
public:
/* Maximum paramaters accepted by this command */
size_t MaxParams;
/* Minimum parameters required to use this command */
size_t MinParams;
/* Command name */
Anope::string name;
/* Permission needed to use this comand */
Anope::string permission;
/* Module which owns us */
Module *module;
/* Service this command is on */
BotInfo *service;
/** Create a new command.
* @param owner The owner of the command
* @param sname The command name
* @param min_params The minimum number of parameters the parser will require to execute this command
* @param max_params The maximum number of parameters the parser will create, after max_params, all will be combined into the last argument.
* NOTE: If max_params is not set (default), there is no limit to the max number of params.
*/
Command(const Anope::string &sname, size_t min_params, size_t max_params = 0, const Anope::string &spermission = "");
Command(Module *owner, const Anope::string &sname, size_t min_params, size_t max_params = 0, const Anope::string &spermission = "");
virtual ~Command();
protected:
void SetDesc(const Anope::string &d);
void ClearSyntax();
void SetSyntax(const Anope::string &s);
void SendSyntax(CommandSource &);
void SendSyntax(CommandSource &, const Anope::string &syntax);
public:
/** Get the command description
* @return The commands description
@@ -117,7 +98,7 @@ class CoreExport Command : public Flags<CommandFlag>, public Base
* @param source The source
* @param params Command parameters
*/
virtual CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
/** Called when HELP is requsted for the client this command is on.
* @param source The source
@@ -141,23 +122,6 @@ class CoreExport Command : public Flags<CommandFlag>, public Base
* @param reststr The permission required to successfully execute this command
*/
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(Module *creator, Command *c);
/** Delete a subcommand from this command
* @param c The command
*/
virtual bool DelSubcommand(Command *c);
/** Find a subcommand
* @param name The subcommand name
* @return The subcommand
*/
virtual Command *FindSubcommand(const Anope::string &subcommand);
};
#endif // COMMANDS_H
+9 -43
View File
@@ -342,7 +342,7 @@ class CoreExport ServerConfig
/** Below here is a list of variables which contain the config files values
*/
/* Host to connect to **/
/* Host to bind to */
Anope::string LocalHost;
/* List of uplink servers to try and connect to */
std::vector<Uplink *> Uplinks;
@@ -351,10 +351,6 @@ class CoreExport ServerConfig
Anope::string ServerName;
/* Our servers description */
Anope::string ServerDesc;
/* The username/ident of services clients */
Anope::string ServiceUser;
/* The hostname if services clients */
Anope::string ServiceHost;
/* Name of the network were on */
Anope::string NetworkName;
@@ -368,49 +364,19 @@ class CoreExport ServerConfig
/* Max length of passwords */
unsigned PassLen;
/* NickServ Name */
Anope::string s_NickServ;
/* ChanServ Name */
Anope::string s_ChanServ;
/* MemoServ Name */
Anope::string s_MemoServ;
/* BotServ Name */
Anope::string s_BotServ;
/* OperServ name */
Anope::string s_OperServ;
/* Global name */
Anope::string s_Global;
/* NickServs realname */
Anope::string desc_NickServ;
/* ChanServ realname */
Anope::string desc_ChanServ;
/* MemoServ realname */
Anope::string desc_MemoServ;
/* BotServ realname */
Anope::string desc_BotServ;
/* OperServ realname */
Anope::string desc_OperServ;
/* Global realname */
Anope::string desc_Global;
/* HostServ Name */
Anope::string s_HostServ;
/* HostServ realname */
Anope::string desc_HostServ;
/* Core HostServ modules */
Anope::string HostCoreModules;
/* Filename for the PID file */
Anope::string PIDFilename;
/* MOTD filename */
Anope::string MOTDFilename;
/* Core MemoServ Modules */
Anope::string MemoCoreModules;
/* Core OperServ Modules */
Anope::string OperCoreModules;
/* Core Global Modules */
Anope::string GlobalCoreModules;
Anope::string BotServ;
Anope::string ChanServ;
Anope::string Global;
Anope::string HostServ;
Anope::string NickServ;
Anope::string OperServ;
Anope::string MemoServ;
/* True if its ok to not be able to save backs */
bool NoBackupOkay;
/* Do password checking when new people register */
-1
View File
@@ -99,7 +99,6 @@ E const char *translate(const char *string);
E const char *translate(User *u, const char *string);
E const char *translate(NickCore *nc, const char *string);
E const char *anope_gettext(const char *lang, const char *string);
E void SyntaxError(CommandSource &source, const Anope::string &command, const Anope::string &message);
/**** main.c ****/
+2 -11
View File
@@ -25,8 +25,7 @@
#define CHAN_X_SUSPENDED _("Channel %s is currently suspended.")
#define CHAN_X_NOT_REGISTERED _("Channel \002%s\002 isn't registered.")
#define CHAN_X_NOT_IN_USE _("Channel \002%s\002 doesn't exist.")
#define NICK_IDENTIFY_REQUIRED _("Password authentication required for that command.\n" \
"Retry after typing \002%s%s IDENTIFY \037password\037\002.")
#define NICK_IDENTIFY_REQUIRED _("Password authentication required for that command.")
#define MAIL_X_INVALID _("\002%s\002 is not a valid e-mail address.")
#define NO_REASON _("No reason")
#define UNKNOWN _("<unknown>")
@@ -47,11 +46,6 @@
#define NICK_SET_DISABLED _("Sorry, nickname option setting is temporarily disabled.")
#define NICK_SET_UNKNOWN_OPTION _("Unknown SET option \002%s%s\002.")
#define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.")
#define NICK_SASET_SYNTAX _("SASET \037nickname\037 \037option\037 \037parameters\037")
#define NICK_SASET_DISPLAY_INVALID _("The new display for \002%s\002 MUST be a nickname of the nickname group!")
#define NICK_SASET_PASSWORD_FAILED _("Sorry, couldn't change password for \002%s\002.")
#define NICK_SASET_PASSWORD_CHANGED _("Password for \002%s\002 changed.")
#define NICK_SASET_PASSWORD_CHANGED_TO _("Password for \002%s\002 changed to \002%s\002.")
#define NICK_INFO_OPTIONS _(" Options: %s")
#define NICK_LIST_SYNTAX _("LIST \037pattern\037")
#define LIST_HEADER _("List of entries matching \002%s\002:")
@@ -64,8 +58,6 @@
#define CHAN_REACHED_CHANNEL_LIMIT _("Sorry, you have already reached your limit of \002%d\002 channels.")
#define CHAN_EXCEEDED_CHANNEL_LIMIT _("Sorry, you have already exceeded your limit of \002%d\002 channels.")
#define CHAN_SYMBOL_REQUIRED _("Please use the symbol of \002#\002 when attempting to register")
#define CHAN_SASET_SYNTAX _("SASET \002channel\002 \037option\037 \037parameters\037")
#define CHAN_SET_SYNTAX _("SET \037channel\037 \037option\037 \037parameters\037")
#define CHAN_SET_DISABLED _("Sorry, channel option setting is temporarily disabled.")
#define CHAN_SETTING_CHANGED _("%s for %s set to %s.")
#define CHAN_SETTING_UNSET _("%s for %s unset.")
@@ -94,8 +86,7 @@
#define MEMO_HAVE_NO_NEW_MEMOS _("You have no new memos.")
#define MEMO_X_HAS_NO_NEW_MEMOS _("%s has no new memos.")
#define BOT_DOES_NOT_EXIST _("Bot \002%s\002 does not exist.")
#define BOT_NOT_ASSIGNED _("You must assign a bot to the channel before using this command.\n" \
"Type %s%s HELP ASSIGN for more information.")
#define BOT_NOT_ASSIGNED _("You must assign a bot to the channel before using this command.")
#define BOT_NOT_ON_CHANNEL _("Bot is not on channel \002%s\002.")
#define BOT_ASSIGN_READONLY _("Sorry, bot assignment is temporarily disabled.")
#define ENABLED _("Enabled")
+2
View File
@@ -29,6 +29,8 @@ struct LogFile
Anope::string GetName() const;
};
class Command;
class CoreExport Log
{
public:
-2
View File
@@ -295,8 +295,6 @@ class CoreExport ChannelModeBan : public ChannelModeList
{
public:
ChannelModeBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { }
void OnAdd(Channel *chan, const Anope::string &mask);
};
/** Channel mode +k (key)
+2 -1
View File
@@ -2,7 +2,8 @@
#define MODULE_H
#include "services.h"
#include "commands.h"
#include "modules.h"
#include "oper.h"
#include "commands.h"
#endif // MODULE_H
+47 -52
View File
@@ -17,7 +17,6 @@
#include <stdio.h>
#include "timers.h"
#include "hashcomp.h"
#include "commands.h"
/* Cross OS compatibility macros */
#ifdef _WIN32
@@ -187,8 +186,9 @@ class Version
int GetBuild() const;
};
/* Forward declaration of CallBack class for the Module class */
class CallBack;
class XLineManager;
class CommandSource;
/** Every module in Anope is actually a class.
*/
@@ -270,22 +270,6 @@ class CoreExport Module : public Extensible
*/
Version GetVersion() const;
/**
* Add a module provided command to the given service.
* @param bi The service to add the command to
* @param c The command to add
* @return MOD_ERR_OK on successfully adding the command
*/
int AddCommand(BotInfo *bi, Command *c);
/**
* Delete a command from the service given.
* @param bi The service to remove the command from
* @param c Thec command to delete
* @return returns MOD_ERR_OK on success
*/
int DelCommand(BotInfo *bi, Command *c);
/** Called when the ircd notifies that a user has been kicked from a channel.
* @param c The channel the user has been kicked from.
* @param target The user that has been kicked.
@@ -330,15 +314,17 @@ class CoreExport Module : public Extensible
*/
virtual void OnUserNickChange(User *u, const Anope::string &oldnick) { }
/** Called immediatly when a user tries to run a command
* @param u The user
* @param bi The bot the command is being run from
* @param command The command
* @param message The parameters used for the command
* @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
/** Called when someone uses the generic/help command
* @param source Command source
* @param params Params
*/
virtual EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci) { return EVENT_CONTINUE; }
virtual void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) { }
/** Called when someone uses the generic/help command
* @param source Command source
* @param params Params
*/
virtual void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) { }
/** Called before a command is due to be executed.
* @param source The source of the command
@@ -346,7 +332,7 @@ class CoreExport Module : public Extensible
* @param params The parameters the user is sending
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called after a command has been executed.
* @param source The source of the command
@@ -445,6 +431,13 @@ class CoreExport Module : public Extensible
*/
virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) { }
/** Called when a user leaves a channel.
* From either parting, being kicked, or quitting/killed!
* @param u The user
* @param c The channel
*/
virtual void OnLeaveChannel(User *u, Channel *c) { }
/** Called before a user joins a channel
* @param u The user
* @param c The channel
@@ -582,18 +575,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnDefconLevel(int level) { }
/** Called before an akill is added
* @param ak The akill
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnAddAkill(XLine *ak) { return EVENT_CONTINUE; }
/** Called before an akill is deleted
* @param u The user removing the akill
* @param ak The akill, can be NULL for all akills!
*/
virtual void OnDelAkill(User *u, XLine *ak) { }
/** Called after an exception has been added
* @param ex The exception
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
@@ -607,18 +588,19 @@ class CoreExport Module : public Extensible
virtual void OnExceptionDel(User *u, Exception *ex) { }
/** Called before a XLine is added
* @param sx The XLine
* @param Type The type of XLine this is
* @param u The user adding the XLine
* @param x The XLine
* @param xlm The xline manager it was added to
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnAddXLine(XLine *x, XLineType Type) { return EVENT_CONTINUE; }
virtual EventReturn OnAddXLine(User *u, XLine *x, XLineManager *xlm) { return EVENT_CONTINUE; }
/** Called before a XLine is deleted
* @param u The user deleting the XLine
* @param sx The XLine, can be NULL for all XLines
* @param Type The type of XLine this is
* @param x The XLine, can be NULL for all XLines
* @param xlm The xline manager it was deleted from
*/
virtual void OnDelXLine(User *u, XLine *x, XLineType Type) { }
virtual void OnDelXLine(User *u, XLine *x, XLineManager *xlm) { }
/** Called when a user is checked for whether they are a services oper
* @param u The user
@@ -746,6 +728,14 @@ class CoreExport Module : public Extensible
*/
virtual void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) { }
/** Called after a user join a channel when we decide whether to kick them or not
* @param u The user
* @param ci The channel
* @param kick Set to true to kick
* @return EVENT_ALLOW to stop processing immediatly
*/
virtual EventReturn OnCheckKick(User *u, ChannelInfo *ci, bool &kick) { return EVENT_CONTINUE; }
/** Called when a user requests info for a channel
* @param source The user requesting info
* @param ci The channel the user is requesting info for
@@ -877,7 +867,7 @@ class CoreExport Module : public Extensible
* @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> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
virtual EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
/** Called when a user does /ns update
* @param u The user
@@ -1013,10 +1003,10 @@ class CoreExport Module : public Extensible
/** 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 c The channel
* @param msg The message
*/
virtual void OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg) { }
virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg) { }
/** Called when any object is deleted
* @param b The object
@@ -1041,7 +1031,7 @@ enum Implementation
/* 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_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick,
I_OnChanInfo, I_OnFindChan,
/* BotServ */
@@ -1056,7 +1046,7 @@ enum Implementation
/* Users */
I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnFingerprint, I_OnUserAway,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnLeaveChannel, I_OnFingerprint, I_OnUserAway,
/* OperServ */
I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
@@ -1070,8 +1060,8 @@ enum Implementation
I_OnModuleLoad, I_OnModuleUnload,
/* Other */
I_OnReload, I_OnNewServer, I_OnPreServerConnect, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun,
I_OnPreCommand, I_OnPostCommand, I_OnRestart, I_OnShutdown,
I_OnReload, I_OnNewServer, I_OnPreServerConnect, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect,
I_OnPreHelp, I_OnPostHelp, I_OnPreCommand, I_OnPostCommand, I_OnRestart, I_OnShutdown,
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
@@ -1218,6 +1208,11 @@ class CoreExport ModuleManager
*/
static Service *GetService(const Anope::string &name);
/** Get the existing service key names
* @return The keys
*/
static std::vector<Anope::string> GetServiceKeys();
private:
/** Call the module_delete function to safely delete the module
* @param m the module to delete
+11 -78
View File
@@ -10,17 +10,6 @@
#define OPER_H
class XLineManager;
extern CoreExport XLineManager *SGLine;
extern CoreExport XLineManager *SZLine;
extern CoreExport XLineManager *SQLine;
extern CoreExport XLineManager *SNLine;
enum XLineType
{
X_SNLINE,
X_SQLINE,
X_SZLINE
};
class CoreExport XLine
{
@@ -40,24 +29,29 @@ class CoreExport XLine
Anope::string GetHost() const;
};
class CoreExport XLineManager
class CoreExport XLineManager : public Service
{
private:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
char type;
protected:
/* List of XLines in this XLineManager */
std::vector<XLine *> XLines;
public:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
/** Constructor
*/
XLineManager();
XLineManager(Module *creator, const Anope::string &name, char t);
/** Destructor
*/
virtual ~XLineManager();
/** The type of xline provided by this service
* @return The type
*/
const char &Type();
/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
* It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
* clients and one handing them free olines, you would want the akilling one first. This way if a client
@@ -165,65 +159,4 @@ class CoreExport XLineManager
virtual void Send(User *u, XLine *x) = 0;
};
/* This is for AKILLS */
class SGLineManager : public XLineManager
{
public:
XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
class SNLineManager : public XLineManager
{
public:
XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
XLine *Check(User *u);
};
class SQLineManager : public XLineManager
{
public:
XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
static bool Check(Channel *c);
};
class SZLineManager : public XLineManager
{
public:
XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
#endif // OPER_H
+2 -4
View File
@@ -660,8 +660,6 @@ enum BotServFlag
BS_DONTKICKVOICES,
/* BotServ bot accepts fantasy commands */
BS_FANTASY,
/* BotServ bot sets modes etc instead of ChanServ */
BS_SYMBIOSIS,
/* BotServ should show greets */
BS_GREET,
/* BotServ bots are not allowed to be in this channel */
@@ -696,7 +694,7 @@ enum BotServFlag
};
const Anope::string BotServFlagStrings[] = {
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "SYMBIOSIS", "GREET", "NOBOT",
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "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", ""
@@ -817,10 +815,10 @@ class IRCdMessage;
struct Uplink;
class ServerConfig;
class ConfigurationFile;
class XLine;
#include "extern.h"
#include "language.h"
#include "oper.h"
#include "mail.h"
#include "servers.h"
#include "logger.h"
+1 -1
View File
@@ -77,7 +77,7 @@ class CoreExport User : public Extensible
* @param shost The hostname of the user
* @param suid The unique identifier of the user.
*/
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid);
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid = "");
/** Destroy a user.
*/
-2
View File
@@ -52,8 +52,6 @@ class BotServService : public Service
public:
BotServService(Module *m) : Service(m, "BotServ") { }
virtual BotInfo *Bot() = 0;
virtual UserData *GetUserData(User *u, Channel *c) = 0;
virtual BanData *GetBanData(User *u, Channel *c) = 0;
-93
View File
@@ -1,93 +0,0 @@
/* BotServ 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"
#include "botserv.h"
class CommandBSAct : public Command
{
public:
CommandBSAct() : Command("ACT", 2, 2)
{
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string message = params[1];
if (!check_access(u, ci, CA_SAY))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (!ci->bi)
{
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
return MOD_CONT;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
return MOD_CONT;
}
size_t i = 0;
while ((i = message.find(1)) && i != Anope::string::npos)
message.erase(i, 1);
ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX Need to be able to find if someone is overriding this.
Log(LOG_COMMAND, u, this, ci) << message;
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "ACT", _("ACT \037channel\037 \037text\037"));
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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;
}
};
class BSAct : public Module
{
CommandBSAct commandbsact;
public:
BSAct(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsact);
}
};
MODULE_INIT(BSAct)
+91 -26
View File
@@ -12,52 +12,59 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSAssign : public Command
{
public:
CommandBSAssign() : Command("ASSIGN", 2, 2)
CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2)
{
this->SetDesc(_("Assigns a bot to a channel"));
this->SetSyntax(_("\037channel\037 \037nick\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &nick = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
source.Reply(_(BOT_ASSIGN_READONLY));
return MOD_CONT;
source.Reply(BOT_ASSIGN_READONLY);
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
BotInfo *bi = findbot(nick);
if (!bi)
{
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration")))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private"))
if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/botserv/assign/private"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (ci->bi && nick.equals_ci(ci->bi->nick))
if (ci->bi == bi)
{
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;
return;
}
bool override = !check_access(u, ci, CA_ASSIGN);
@@ -65,38 +72,96 @@ class CommandBSAssign : public Command
bi->Assign(u, ci);
source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str());
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002ASSIGN \037chan\037 \037nick\037\002\n"
" \n"
"Assigns a bot pointed out by nick to the channel chan. You\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
class CommandBSUnassign : public Command
{
public:
CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1)
{
SyntaxError(source, "ASSIGN", _("ASSIGN \037chan\037 \037nick\037"));
this->SetDesc(_("Unassigns a bot from a channel"));
this->SetSyntax(_("\037channel\037 \037nick\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
if (readonly)
{
source.Reply(BOT_ASSIGN_READONLY);
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (ci->HasFlag(CI_PERSIST) && !ModeManager::FindChannelModeByName(CMODE_PERM))
{
source.Reply(_("You can not unassign bots while persist is set on the channel."));
return;
}
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);
source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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;
}
};
class BSAssign : public Module
{
CommandBSAssign commandbsassign;
CommandBSUnassign commandbsunassign;
public:
BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsassign(this), commandbsunassign(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsassign);
ModuleManager::RegisterService(&commandbsassign);
ModuleManager::RegisterService(&commandbsunassign);
}
};
+63 -67
View File
@@ -12,36 +12,36 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class BadwordsListCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
BadwordsListCallback(CommandSource &_source, const Anope::string &list) : NumberList(list, false), source(_source), SentHeader(false)
BadwordsListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), source(_source), ci(_ci), SentHeader(false)
{
}
~BadwordsListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetBadWordCount())
if (!Number || Number > ci->GetBadWordCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), source.ci->name.c_str());
" Num Word Type"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetBadWord(Number - 1));
DoList(source, Number - 1, ci->GetBadWord(Number - 1));
}
static void DoList(CommandSource &source, unsigned Number, BadWord *bw)
@@ -53,43 +53,43 @@ class BadwordsListCallback : public NumberList
class BadwordsDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
bool override;
public:
BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false)
BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0), override(false)
{
if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
if (!check_access(source.u, ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
this->override = true;
}
~BadwordsDelCallback()
{
if (!Deleted)
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
else if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s bad words list."), source.ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s bad words list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, source.ci->name.c_str());
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetBadWordCount())
if (!Number || Number > ci->GetBadWordCount())
return;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "DEL " << source.ci->GetBadWord(Number - 1)->word;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "DEL " << ci->GetBadWord(Number - 1)->word;
++Deleted;
source.ci->EraseBadWord(Number - 1);
ci->EraseBadWord(Number - 1);
}
};
class CommandBSBadwords : public Command
{
private:
CommandReturn DoList(CommandSource &source, const Anope::string &word)
void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
bool override = !check_access(source.u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
@@ -97,7 +97,7 @@ class CommandBSBadwords : public Command
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(source, word);
BadwordsListCallback list(source, ci, word);
list.Process();
}
else
@@ -126,12 +126,11 @@ class CommandBSBadwords : public Command
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoAdd(CommandSource &source, const Anope::string &word)
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
size_t pos = word.rfind(' ');
BadWordType type = BW_ANY;
Anope::string realword = word;
@@ -154,7 +153,7 @@ class CommandBSBadwords : public Command
if (ci->GetBadWordCount() >= Config->BSBadWordsMax)
{
source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax);
return MOD_CONT;
return;
}
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
@@ -164,7 +163,7 @@ class CommandBSBadwords : public Command
if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word))))
{
source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
}
@@ -174,16 +173,15 @@ class CommandBSBadwords : public Command
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
CommandReturn DoDelete(CommandSource &source, const Anope::string &word)
void DoDelete(CommandSource &source, ChannelInfo *ci, 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(source, this, word);
BadwordsDelCallback list(source, ci, this, word);
list.Process();
}
else
@@ -202,7 +200,7 @@ class CommandBSBadwords : public Command
if (i == end)
{
source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
bool override = !check_access(source.u, ci, CA_BADWORDS);
@@ -213,78 +211,83 @@ class CommandBSBadwords : public Command
ci->EraseBadWord(i);
}
return MOD_CONT;
return;
}
CommandReturn DoClear(CommandSource &source)
void DoClear(CommandSource &source, ChannelInfo *ci)
{
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();
source.Reply(_("Bad words list is now empty."));
return MOD_CONT;
return;
}
public:
CommandBSBadwords() : Command("BADWORDS", 2, 3)
CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3)
{
this->SetDesc(_("Maintains bad words list"));
this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
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(source, cmd);
return MOD_CONT;
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (readonly)
{
source.Reply(_("Sorry, channel bad words list modification is temporarily disabled."));
return MOD_CONT;
return;
}
if (cmd.equals_ci("ADD"))
return this->DoAdd(source, word);
return this->DoAdd(source, ci, word);
else if (cmd.equals_ci("DEL"))
return this->DoDelete(source, word);
return this->DoDelete(source, ci, word);
else if (cmd.equals_ci("LIST"))
return this->DoList(source, word);
return this->DoList(source, ci, word);
else if (cmd.equals_ci("CLEAR"))
return this->DoClear(source);
return this->DoClear(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002bad words list\002 for a channel. The bad\n"
"words list determines which words are to be kicked\n"
"when the bad words kicker is enabled. For more information,\n"
"type \002%s%s HELP KICK BADWORDS\002.\n"
"type \002%s%s HELP KICK %s\002.\n"
" \n"
"The \002BADWORDS ADD\002 command adds the given word to the\n"
"The \002ADD\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"
@@ -292,28 +295,23 @@ class CommandBSBadwords : public Command
"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(), Config->s_BotServ.c_str());
source.Reply(_("The \002BADWORDS DEL\002 command removes the given word from the\n"
" \n"), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), source.command.c_str());
source.Reply(_("The \002DEL\002 command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
" \n"
"The \002BADWORDS LIST\002 command displays the bad words list. If\n"
"The \002LIST\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"
" \002#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"
"The \002CLEAR\002 command clears all entries of the\n"
"bad words list."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "BADWORDS", _("BADWORDS \037channel\037 {ADD|DEL|LIST|CLEAR} [\037word\037 | \037entry-list\037] [SINGLE|START|END]"));
}
};
class BSBadwords : public Module
@@ -321,14 +319,12 @@ class BSBadwords : public Module
CommandBSBadwords commandbsbadwords;
public:
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbadwords(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsbadwords);
ModuleManager::RegisterService(&commandbsbadwords);
}
};
+67 -82
View File
@@ -12,12 +12,11 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSBot : public Command
{
private:
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[1];
const Anope::string &user = params[2];
@@ -28,60 +27,60 @@ class CommandBSBot : public Command
if (findbot(nick))
{
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
return;
}
if (nick.length() > Config->NickLen)
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (user.length() > Config->UserLen)
{
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (host.length() > Config->HostLen)
{
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
return;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* Check the host is valid re RFC 2812 */
if (!isValidHost(host, 3))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
if (!isalnum(user[i]))
{
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
return;
}
/* We check whether the nick is registered, and inform the user
@@ -90,26 +89,21 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
return;
}
if (!(bi = new BotInfo(nick, user, host, real)))
{
// XXX this cant happen?
source.Reply(_("Sorry, bot creation failed."));
return MOD_CONT;
}
bi = new BotInfo(nick, user, host, real);
Log(LOG_ADMIN, source.u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
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;
return;
}
CommandReturn DoChange(CommandSource &source, const std::vector<Anope::string> &params)
void DoChange(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &oldnick = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
@@ -121,43 +115,43 @@ class CommandBSBot : public Command
if (oldnick.empty() || nick.empty())
{
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
return;
}
if (!(bi = findbot(oldnick)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
if (!oldnick.equals_ci(nick) && nickIsServices(oldnick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
if (nick.length() > Config->NickLen)
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (!user.empty() && user.length() > Config->UserLen)
{
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (!host.empty() && host.length() > Config->HostLen)
{
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
return;
}
if (!oldnick.equals_ci(nick) && nickIsServices(nick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
/* Checks whether there *are* changes.
@@ -168,34 +162,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))
{
source.Reply(_("Old info is equal to the new one."));
return MOD_CONT;
return;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (!host.empty() && !isValidHost(host, 3))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
return;
}
if (!user.empty())
@@ -203,13 +197,13 @@ class CommandBSBot : public Command
if (!isalnum(user[i]))
{
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (!nick.equals_ci(bi->nick) && findbot(nick))
{
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
return;
}
if (!nick.equals_ci(bi->nick))
@@ -220,8 +214,8 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
return;
}
/* The new nick is really different, so we remove the Q line for the old nick. */
@@ -263,10 +257,10 @@ class CommandBSBot : public Command
Log(LOG_ADMIN, source.u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
FOREACH_MOD(I_OnBotChange, OnBotChange(bi));
return MOD_CONT;
return;
}
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[1];
BotInfo *bi;
@@ -274,19 +268,19 @@ class CommandBSBot : public Command
if (nick.empty())
{
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
return;
}
if (!(bi = findbot(nick)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
if (nickIsServices(nick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
@@ -295,16 +289,18 @@ class CommandBSBot : public Command
source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str());
delete bi;
return MOD_CONT;
return;
}
public:
CommandBSBot() : Command("BOT", 1, 6)
CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Maintains network bot list"));
this->SetSyntax(_("\002ADD \037nick\037 \037user\037 \037host\037 \037real\037\002"));
this->SetSyntax(_("\002CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002"));
this->SetSyntax(_("\002DEL \037nick\037\002"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[0];
User *u = source.u;
@@ -312,22 +308,22 @@ class CommandBSBot : public Command
if (readonly)
{
source.Reply(_("Sorry, bot modification is temporarily disabled."));
return MOD_CONT;
return;
}
if (cmd.equals_ci("ADD"))
{
// ADD nick user host real - 5
if (!u->HasCommand("botserv/bot/add"))
if (!u->HasCommand("botserv/botserv/bot/add"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 5)
{
this->OnSyntaxError(source, "ADD");
return MOD_CONT;
return;
}
std::vector<Anope::string> tempparams = params;
@@ -341,16 +337,16 @@ class CommandBSBot : public Command
{
// CHANGE oldn newn user host real - 6
// but only oldn and newn are required
if (!u->HasCommand("botserv/bot/change"))
if (!u->HasCommand("botserv/botserv/bot/change"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 3)
{
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
return;
}
return this->DoChange(source, params);
@@ -358,16 +354,16 @@ class CommandBSBot : public Command
else if (cmd.equals_ci("DEL"))
{
// DEL nick
if (!u->HasCommand("botserv/bot/del"))
if (!u->HasCommand("botserv/botserv/bot/del"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 1)
{
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
return;
}
return this->DoDel(source, params);
@@ -375,16 +371,14 @@ class CommandBSBot : public Command
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
"channels.\n"
" \n"
@@ -401,13 +395,6 @@ class CommandBSBot : public Command
"using the nick, they will be killed."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
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"));
}
};
class BSBot : public Module
@@ -415,14 +402,12 @@ class BSBot : public Module
CommandBSBot commandbsbot;
public:
BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbot(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsbot);
ModuleManager::RegisterService(&commandbsbot);
}
};
+11 -13
View File
@@ -12,17 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSBotList : public Command
{
public:
CommandBSBotList() : Command("BOTLIST", 0, 0)
CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
{
this->SetDesc(_("Lists available bots"));
this->SetSyntax("");
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
unsigned count = 0;
@@ -40,7 +40,7 @@ class CommandBSBotList : public Command
}
}
if (u->HasCommand("botserv/botlist") && count < BotListByNick.size())
if (u->HasCommand("botserv/botserv/botlist") && count < BotListByNick.size())
{
source.Reply(_("Bots reserved to IRC operators:"));
@@ -62,14 +62,14 @@ class CommandBSBotList : public Command
else
source.Reply(_("%d bots available."), count);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BOTLIST\002\n"
" \n"
"Lists all available bots on this network."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists all available bots on this network."));
return true;
}
};
@@ -79,14 +79,12 @@ class BSBotList : public Module
CommandBSBotList commandbsbotlist;
public:
BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbotlist(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsbotlist);
ModuleManager::RegisterService(&commandbsbotlist);
}
};
+158
View File
@@ -0,0 +1,158 @@
/* BotServ 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 CommandBSSay : public Command
{
public:
CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2)
{
this->SetDesc(_("Makes the bot say the given text on the given channel"));
this->SetSyntax(_("\037channel\037 \037text\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &text = params[1];
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!check_access(u, ci, CA_SAY))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
return;
}
if (text[0] == '\001')
{
this->OnSyntaxError(source, "");
return;
}
ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", text.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX need a way to find if someone is overriding this
Log(LOG_COMMAND, u, this, ci) << text;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Makes the bot say the given text on the given channel."));
return true;
}
};
class CommandBSAct : public Command
{
public:
CommandBSAct(Module *creator) : Command(creator, "botserv/act", 2, 2)
{
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
this->SetSyntax(_("\037channel\037 \037text\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string message = params[1];
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!check_access(u, ci, CA_SAY))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
return;
}
size_t i = 0;
while ((i = message.find(1)) && i != Anope::string::npos)
message.erase(i, 1);
ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX Need to be able to find if someone is overriding this.
Log(LOG_COMMAND, u, this, ci) << message;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n"
"on the given channel using the given text."));
return true;
}
};
class BSControl : public Module
{
CommandBSSay commandbssay;
CommandBSAct commandbsact;
public:
BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbssay(this), commandbsact(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbssay);
ModuleManager::RegisterService(&commandbsact);
}
};
MODULE_INIT(BSControl)
-72
View File
@@ -1,72 +0,0 @@
/* BotServ 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"
#include "botserv.h"
class CommandBSHelp : public Command
{
public:
CommandBSHelp() : Command("HELP", 1, 1)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(botserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
// Abuse syntax error to display general list 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."),
Config->s_BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
for (CommandMap::const_iterator it = botserv->Bot()->Commands.begin(), it_end = botserv->Bot()->Commands.end(); it != it_end; ++it)
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]);
}
};
class BSHelp : public Module
{
CommandBSHelp commandbshelp;
public:
BSHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbshelp);
}
};
MODULE_INIT(BSHelp)
+44 -57
View File
@@ -13,7 +13,6 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSInfo : public Command
{
@@ -41,13 +40,13 @@ class CommandBSInfo : public Command
return;
}
public:
CommandBSInfo() : Command("INFO", 1, 1)
CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Allows you to see BotServ information about a channel or a bot"));
this->SetSyntax(_("\002INFO {\037chan\037 | \037nick\037}\002"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &query = params[0];
@@ -73,11 +72,11 @@ class CommandBSInfo : public Command
{
if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
source.Reply(_(CHAN_INFO_HEADER), ci->name.c_str());
source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
if (ci->bi)
source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str());
else
@@ -86,93 +85,93 @@ class CommandBSInfo : public Command
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
if (ci->ttb[TTB_BADWORDS])
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BADWORDS]);
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BADWORDS]);
else
source.Reply(_(" Bad words kicker : %s"), _(ENABLED));
source.Reply(_(" Bad words kicker : %s"), ENABLED);
}
else
source.Reply(_(" Bad words kicker : %s"), _(DISABLED));
source.Reply(_(" Bad words kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_BOLDS))
{
if (ci->ttb[TTB_BOLDS])
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BOLDS]);
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BOLDS]);
else
source.Reply(_(" Bolds kicker : %s"), _(ENABLED));
source.Reply(_(" Bolds kicker : %s"), ENABLED);
}
else
source.Reply(_(" Bolds kicker : %s"), _(DISABLED));
source.Reply(_(" Bolds kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_CAPS))
{
if (ci->ttb[TTB_CAPS])
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), _(ENABLED), 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
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), _(ENABLED), ci->capsmin, ci->capspercent);
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), ENABLED, ci->capsmin, ci->capspercent);
}
else
source.Reply(_(" Caps kicker : %s"), _(DISABLED));
source.Reply(_(" Caps kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_COLORS))
{
if (ci->ttb[TTB_COLORS])
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_COLORS]);
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_COLORS]);
else
source.Reply(_(" Colors kicker : %s"), _(ENABLED));
source.Reply(_(" Colors kicker : %s"), ENABLED);
}
else
source.Reply(_(" Colors kicker : %s"), _(DISABLED));
source.Reply(_(" Colors kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
if (ci->ttb[TTB_FLOOD])
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), _(ENABLED), 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
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), _(ENABLED), ci->floodlines, ci->floodsecs);
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), ENABLED, ci->floodlines, ci->floodsecs);
}
else
source.Reply(_(" Flood kicker : %s"), _(DISABLED));
source.Reply(_(" Flood kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (ci->ttb[TTB_REPEAT])
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), _(ENABLED), 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
source.Reply(_(" Repeat kicker : %s (%d times)"), _(ENABLED), ci->repeattimes);
source.Reply(_(" Repeat kicker : %s (%d times)"), ENABLED, ci->repeattimes);
}
else
source.Reply(_(" Repeat kicker : %s"), _(DISABLED));
source.Reply(_(" Repeat kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_REVERSES))
{
if (ci->ttb[TTB_REVERSES])
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_REVERSES]);
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_REVERSES]);
else
source.Reply(_(" Reverses kicker : %s"), _(ENABLED));
source.Reply(_(" Reverses kicker : %s"), ENABLED);
}
else
source.Reply(_(" Reverses kicker : %s"), _(DISABLED));
source.Reply(_(" Reverses kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES))
{
if (ci->ttb[TTB_UNDERLINES])
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_UNDERLINES]);
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_UNDERLINES]);
else
source.Reply(_(" Underlines kicker : %s"), _(ENABLED));
source.Reply(_(" Underlines kicker : %s"), ENABLED);
}
else
source.Reply(_(" Underlines kicker : %s"), _(DISABLED));
source.Reply(_(" Underlines kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_ITALICS))
{
if (ci->ttb[TTB_ITALICS])
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_ITALICS]);
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_ITALICS]);
else
source.Reply(_(" Italics kicker : %s"), _(ENABLED));
source.Reply(_(" Italics kicker : %s"), ENABLED);
}
else
source.Reply(_(" Italics kicker : %s"), _(DISABLED));
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]);
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_AMSGS]);
else
source.Reply(_(" AMSG kicker : %s"), _(ENABLED));
source.Reply(_(" AMSG kicker : %s"), ENABLED);
}
else
source.Reply(_(" AMSG kicker : %s"), _(DISABLED));
source.Reply(_(" AMSG kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_MSG_PRIVMSG))
source.Reply(_(" Fantasy reply : %s"), "PRIVMSG");
@@ -208,34 +207,24 @@ class CommandBSInfo : public Command
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 ? ", " : "", _("Symbiosis"));
need_comma = true;
}
source.Reply(_(" Options : %s"), *buf ? buf : _("None"));
}
else
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INFO {\037chan\037 | \037nick\037}\002\n"
" \n"
"Allows you to see %s information about a channel or a bot.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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."), Config->s_NickServ.c_str());
"time or number of channels it is on."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INFO", _("INFO {\037chan\037 | \037nick\037}"));
}
};
class BSInfo : public Module
@@ -243,14 +232,12 @@ class BSInfo : public Module
CommandBSInfo commandbsinfo;
public:
BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsinfo(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsinfo);
ModuleManager::RegisterService(&commandbsinfo);
}
};
+171 -52
View File
@@ -13,17 +13,17 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSKick : public Command
{
public:
CommandBSKick() : Command("KICK", 3, 6)
CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 3, 6)
{
this->SetDesc(_("Configures kickers"));
this->SetSyntax(_("\037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
@@ -31,18 +31,20 @@ class CommandBSKick : public Command
const Anope::string &ttb = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (readonly)
source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
else if (ci == NULL)
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
else if (chan.empty() || option.empty() || value.empty())
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
this->OnSyntaxError(source, "");
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
this->OnSyntaxError(source, "");
else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!ci->bi)
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
source.Reply(BOT_NOT_ASSIGNED);
else
{
bool override = !check_access(u, ci, CA_SET);
@@ -65,7 +67,7 @@ class CommandBSKick : public Command
/* reset the value back to 0 - TSL */
ci->ttb[TTB_BADWORDS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -102,7 +104,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_BOLDS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -138,7 +140,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_CAPS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -193,7 +195,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_COLORS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -230,7 +232,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_FLOOD] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -286,7 +288,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_REPEAT] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -332,7 +334,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_REVERSES] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -365,7 +367,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_UNDERLINES] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -399,7 +401,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_ITALICS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -433,7 +435,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_AMSGS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -452,17 +454,18 @@ class CommandBSKick : public Command
}
}
else
source.Reply(_(UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
source.Reply(UNKNOWN_OPTION, Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
source.Reply(_("Syntax: \002KICK \037channel\037 \037option\037 \037parameters\037\002\n"
" \n"
"Configures bot kickers. \037option\037 can be one of:\n"
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -480,9 +483,10 @@ class CommandBSKick : public Command
"on a specific option.\n"
" \n"
"Note: access to this command is controlled by the\n"
"level SET."), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
"level SET."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
else if (subcommand.equals_ci("BADWORDS"))
source.Reply(_("Syntax: \002KICK \037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"
@@ -491,16 +495,16 @@ class CommandBSKick : public Command
"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(), Config->s_BotServ.c_str());
"the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
else if (subcommand.equals_ci("BOLDS"))
source.Reply(_("Syntax: \002KICK \037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"))
source.Reply(_("Syntax: \002KICK \037channel\037 CAPS {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002\n"
source.Reply(_("Syntax: \002\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"
@@ -512,14 +516,14 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("COLORS"))
source.Reply(_("Syntax: \002KICK \037channel\037 COLORS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"))
source.Reply(_("Syntax: \002KICK \037channel\037 FLOOD {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002\n"
source.Reply(_("Syntax: \002\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"
@@ -529,7 +533,7 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REPEAT"))
source.Reply(_("Syntax: \002KICK \037#channel\037 REPEAT {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002\n"
source.Reply(_("Syntax: \002\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"
@@ -538,28 +542,28 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REVERSES"))
source.Reply(_("Syntax: \002KICK \037channel\037 REVERSES {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"))
source.Reply(_("Syntax: \002KICK \037channel\037 UNDERLINES {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"))
source.Reply(_("Syntax: \002KICK \037channel\037 ITALICS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\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"
source.Reply(_("Syntax: \002\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"
@@ -571,16 +575,121 @@ class CommandBSKick : public Command
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
struct BanData
{
Anope::string mask;
time_t last_use;
int16 ttb[TTB_SIZE];
BanData()
{
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
this->Clear();
}
void Clear()
{
last_use = 0;
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
}
};
struct UserData
{
UserData()
{
this->Clear();
}
void Clear()
{
last_use = last_start = Anope::CurTime;
lines = times = 0;
lastline.clear();
}
/* Data validity */
time_t last_use;
/* for flood kicker */
int16 lines;
time_t last_start;
/* for repeat kicker */
Anope::string lastline;
Anope::string lasttarget;
int16 times;
};
class BanDataPurger : public CallBack
{
public:
BanDataPurger(Module *owner) : CallBack(owner, 300, Anope::CurTime, true) { }
void Tick(time_t)
{
Log(LOG_DEBUG) << "bs_main: Running bandata purger";
for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
std::map<Anope::string, BanData> bandata;
if (c->GetExtRegular("bs_main_bandata", bandata))
{
for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end;)
{
const Anope::string &user = it->first;
BanData *bd = &it2->second;
++it2;
if (Anope::CurTime - bd->last_use > Config->BSKeepData)
{
bandata.erase(user);
continue;
}
}
if (bandata.empty())
c->Shrink("bs_main_bandata");
}
}
}
};
class BSKick : public Module
{
CommandBSKick commandbskick;
BanDataPurger purger;
BanData *GetBanData(User *u, Channel *c)
{
std::map<Anope::string, BanData> bandatamap;
if (!c->GetExtRegular("bs_main_bandata", bandatamap));
c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
c->GetExtRegular("bs_main_bandata", bandatamap);
BanData *bd = &bandatamap[u->GetMask()];
if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
bd->Clear();
bd->last_use = Anope::CurTime;
return bd;
}
UserData *GetUserData(User *u, Channel *c)
{
UserData *ud = NULL;
UserContainer *uc = c->FindUser(u);
if (uc != NULL && !uc->GetExtPointer("bs_main_userdata", ud))
{
ud = new UserData();
uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
}
return ud;
}
void check_ban(ChannelInfo *ci, User *u, int ttbtype)
{
@@ -588,7 +697,7 @@ class BSKick : public Module
if (u->server->IsULined())
return;
BanData *bd = botserv->GetBanData(u, ci->c);
BanData *bd = this->GetBanData(u, ci->c);
++bd->ttb[ttbtype];
if (ci->ttb[ttbtype] && bd->ttb[ttbtype] >= ci->ttb[ttbtype])
@@ -625,19 +734,26 @@ class BSKick : public Module
}
public:
BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbskick(this), purger(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbskick);
ModuleManager::RegisterService(&commandbskick);
ModuleManager::Attach(I_OnPrivmsg, this);
}
void OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg)
~BSKick()
{
for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
{
cit->second->Shrink("bs_main_userdata");
cit->second->Shrink("bs_main_bandata");
}
}
void OnPrivmsg(User *u, Channel *c, Anope::string &msg)
{
/* Now we can make kicker stuff. We try to order the checks
* from the fastest one to the slowest one, since there's
@@ -647,13 +763,16 @@ class BSKick : public Module
* But FIRST we check whether the user is protected in any
* way.
*/
ChannelInfo *ci = c->ci;
if (ci == NULL)
return;
bool Allow = true;
if (check_access(u, ci, CA_NOKICK))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (ci->c->HasUserStatus(u, CMODE_HALFOP) || ci->c->HasUserStatus(u, CMODE_OP) || ci->c->HasUserStatus(u, CMODE_PROTECT) || ci->c->HasUserStatus(u, CMODE_OWNER)))
else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (c->HasUserStatus(u, CMODE_HALFOP) || c->HasUserStatus(u, CMODE_OP) || c->HasUserStatus(u, CMODE_PROTECT) || c->HasUserStatus(u, CMODE_OWNER)))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE))
else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && c->HasUserStatus(u, CMODE_VOICE))
Allow = false;
if (Allow)
@@ -819,7 +938,7 @@ class BSKick : public Module
/* Flood kicker */
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
ud = botserv->GetUserData(u, ci->c);
ud = GetUserData(u, c);
if (ud)
{
if (Anope::CurTime - ud->last_start > ci->floodsecs)
@@ -842,7 +961,7 @@ class BSKick : public Module
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (!ud)
ud = botserv->GetUserData(u, ci->c);
ud = GetUserData(u, c);
if (ud)
{
@@ -871,13 +990,13 @@ class BSKick : public Module
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *c = (*it)->chan;
Channel *chan = (*it)->chan;
++it;
if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS) && !check_access(u, c->ci, CA_NOKICK))
if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !check_access(u, chan->ci, CA_NOKICK))
{
check_ban(c->ci, u, TTB_AMSGS);
bot_kick(c->ci, u, _("Don't use AMSGs!"));
check_ban(chan->ci, u, TTB_AMSGS);
bot_kick(chan->ci, u, _("Don't use AMSGs!"));
}
}
}
+127 -179
View File
@@ -12,179 +12,28 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
#include "chanserv.h"
static BotInfo *BotServ = NULL;
class BotServBotInfo : public BotInfo
{
public:
BotServBotInfo(const Anope::string &bnick, const Anope::string &user = "", const Anope::string &bhost = "", const Anope::string &real = "") : BotInfo(bnick, user, bhost, real) { }
void OnMessage(User *u, const Anope::string &message)
{
spacesepstream sep(message);
Anope::string command, param;
if (sep.GetToken(command) && sep.GetToken(param))
{
Command *c = FindCommand(this, command);
if (c && !c->HasFlag(CFLAG_STRIP_CHANNEL))
{
if (ircdproto->IsChannelValid(param))
{
ChannelInfo *ci = cs_findchan(param);
if (ci)
{
if (ci->HasFlag(CI_SUSPENDED) && !c->HasFlag(CFLAG_ALLOW_SUSPENDED))
{
u->SendMessage(this, CHAN_X_SUSPENDED, ci->name.c_str());
Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of SUSPENDED channel " << ci->name;
return;
}
}
else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL))
{
u->SendMessage(this, CHAN_X_NOT_REGISTERED, param.c_str());
return;
}
}
/* A user not giving a channel name for a param that should be a channel */
else
{
u->SendMessage(this, CHAN_X_INVALID, param.c_str());
return;
}
}
}
BotInfo::OnMessage(u, message);
}
};
class MyBotServService : public BotServService
{
public:
MyBotServService(Module *m) : BotServService(m) { }
BotInfo *Bot()
{
return BotServ;
}
UserData *GetUserData(User *u, Channel *c)
{
UserData *ud = NULL;
UserContainer *uc = c->FindUser(u);
if (uc != NULL)
{
if (!uc->GetExtPointer("bs_main_userdata", ud))
{
ud = new UserData();
uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
}
}
return ud;
}
BanData *GetBanData(User *u, Channel *c)
{
std::map<Anope::string, BanData> bandatamap;
if (!c->GetExtRegular("bs_main_bandata", bandatamap));
c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
c->GetExtRegular("bs_main_bandata", bandatamap);
BanData *bd = &bandatamap[u->GetMask()];
if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
bd->Clear();
bd->last_use = Anope::CurTime;
return bd;
}
};
class BanDataPurger : public CallBack
{
public:
BanDataPurger(Module *owner) : CallBack(owner, 300, Anope::CurTime, true) { }
void Tick(time_t)
{
Log(LOG_DEBUG) << "bs_main: Running bandata purger";
for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
std::map<Anope::string, BanData> bandata;
if (c->GetExtRegular("bs_main_bandata", bandata))
{
for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end;)
{
const Anope::string &user = it->first;
BanData *bd = &it2->second;
++it2;
if (Anope::CurTime - bd->last_use > Config->BSKeepData)
{
bandata.erase(user);
continue;
}
}
if (bandata.empty())
c->Shrink("bs_main_bandata");
}
}
}
};
class BotServCore : public Module
{
MyBotServService mybotserv;
BanDataPurger bdpurger;
Channel *fantasy_channel;
public:
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), mybotserv(this), bdpurger(this)
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), fantasy_channel(NULL)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&this->mybotserv);
BotInfo *BotServ = findbot(Config->BotServ);
if (BotServ == NULL)
throw ModuleException("No bot named " + Config->BotServ);
BotServ = new BotServBotInfo(Config->s_BotServ, Config->ServiceUser, Config->ServiceHost, Config->desc_BotServ);
BotServ->SetFlag(BI_CORE);
Implementation i[] = { I_OnPrivmsg, I_OnPreCommand, I_OnJoinChannel, I_OnLeaveChannel,
I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet };
ModuleManager::Attach(i, this, 7);
Implementation i[] = { I_OnPrivmsg };
ModuleManager::Attach(i, this, 1);
spacesepstream coreModules(Config->BotCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
ModuleManager::LoadModule(module, NULL);
}
~BotServCore()
void OnPrivmsg(User *u, Channel *c, Anope::string &msg)
{
for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
{
cit->second->Shrink("bs_main_userdata");
cit->second->Shrink("bs_main_bandata");
}
spacesepstream coreModules(Config->BotCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
{
Module *m = ModuleManager::FindModule(module);
if (m != NULL)
ModuleManager::UnloadModule(m, NULL);
}
delete BotServ;
}
void OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg)
{
if (!u || !ci || !ci->c || !ci->bi || msg.empty())
if (!u || !c || !c->ci || !c->ci->bi || msg.empty())
return;
/* Answer to ping if needed */
@@ -193,7 +42,7 @@ class BotServCore : public Module
Anope::string ctcp = msg;
ctcp.erase(ctcp.begin());
ctcp.erase(ctcp.length() - 1);
ircdproto->SendCTCP(ci->bi, u->nick, "%s", ctcp.c_str());
ircdproto->SendCTCP(c->ci->bi, u->nick, "%s", ctcp.c_str());
}
@@ -211,7 +60,7 @@ class BotServCore : public Module
return;
/* Fantaisist commands */
if (ci->botflags.HasFlag(BS_FANTASY) && realbuf[0] == Config->BSFantasyCharacter[0] && !was_action && chanserv)
if (c->ci->botflags.HasFlag(BS_FANTASY) && realbuf[0] == Config->BSFantasyCharacter[0] && !was_action)
{
/* Strip off the fantasy character */
realbuf.erase(realbuf.begin());
@@ -226,30 +75,129 @@ class BotServCore : public Module
rest = realbuf.substr(space + 1);
}
if (check_access(u, ci, CA_FANTASIA))
{
Command *cmd = FindCommand(chanserv->Bot(), command);
BotInfo *bi = findbot(Config->ChanServ);
if (bi == NULL)
bi = findbot(Config->BotServ);
if (bi == NULL || !bi->commands.count(command))
return;
/* Command exists and can be called by fantasy */
if (cmd && !cmd->HasFlag(CFLAG_DISABLE_FANTASY))
{
Anope::string params = rest;
/* Some commands don't need the channel name added.. eg !help */
if (!cmd->HasFlag(CFLAG_STRIP_CHANNEL))
params = ci->name + " " + params;
params = command + " " + params;
if (check_access(u, c->ci, CA_FANTASIA))
{
this->fantasy_channel = c;
bi->OnMessage(u, realbuf);
this->fantasy_channel = NULL;
mod_run_cmd(chanserv->Bot(), u, ci, params);
}
FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(command, u, ci, rest));
FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(command, u, c->ci, rest));
}
else
{
FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(command, u, ci, rest));
FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(command, u, c->ci, rest));
}
}
}
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params)
{
if (this->fantasy_channel != NULL)
{
if (!command->HasFlag(CFLAG_STRIP_CHANNEL))
params.insert(params.begin(), this->fantasy_channel->name);
source.c = this->fantasy_channel;
}
return EVENT_CONTINUE;
}
void OnJoinChannel(User *user, Channel *c)
{
if (c->ci && c->ci->bi)
{
/**
* We let the bot join even if it was an ignored user, as if we don't,
* and the ignored user doesnt just leave, the bot will never
* make it into the channel, leaving the channel botless even for
* legit users - Rob
**/
if (c->users.size() >= Config->BSMinUsers && !c->FindUser(c->ci->bi))
c->ci->bi->Join(c, &Config->BotModeList);
/* Only display the greet if the main uplink we're connected
* to has synced, or we'll get greet-floods when the net
* recovers from a netsplit. -GD
*/
if (c->FindUser(c->ci->bi) && c->ci->botflags.HasFlag(BS_GREET) && user->Account() && !user->Account()->greet.empty() && check_access(user, c->ci, CA_GREET) && user->server->IsSynced())
{
ircdproto->SendPrivmsg(c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), user->Account()->greet.c_str());
c->ci->bi->lastmsg = Anope::CurTime;
}
}
}
void OnLeaveChannel(User *u, Channel *c)
{
/* Channel is persistant, it shouldn't be deleted and the service bot should stay */
if (c->HasFlag(CH_PERSIST) || (c->ci && c->ci->HasFlag(CI_PERSIST)))
return;
/* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
* We also don't part the bot here either, if necessary we will part it after the sync
*/
if (c->HasFlag(CH_SYNCING))
return;
/* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
if (c->HasFlag(CH_INHABIT))
return;
if (c->ci && c->ci->bi && c->users.size() - 1 <= Config->BSMinUsers && c->FindUser(c->ci->bi))
{
bool persist = c->HasFlag(CH_PERSIST);
c->SetFlag(CH_PERSIST);
c->ci->bi->Part(c->ci->c);
if (!persist)
c->UnsetFlag(CH_PERSIST);
}
}
void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (!params.empty() || source.owner->nick != Config->BotServ)
return;
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 %s \037command\037\002.\n "),
Config->BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), source.command.c_str());
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (!params.empty() || source.owner->nick != Config->BotServ)
return;
source.Reply(_(" \n"
"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->ChanServ.c_str(), Config->BSFantasyCharacter[0]);
}
EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
{
if (Config->BSSmartJoin && Name == CMODE_BAN && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
{
BotInfo *bi = c->ci->bi;
Entry ban(CMODE_BAN, param);
if (ban.Matches(bi))
c->RemoveMode(bi, CMODE_BAN, param);
}
return EVENT_CONTINUE;
}
};
MODULE_INIT(BotServCore)
-95
View File
@@ -1,95 +0,0 @@
/* BotServ 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"
#include "botserv.h"
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(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &text = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_SAY))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (!ci->bi)
{
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
return MOD_CONT;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
return MOD_CONT;
}
if (text[0] == '\001')
{
this->OnSyntaxError(source, "");
return MOD_CONT;
}
ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", text.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX need a way to find if someone is overriding this
Log(LOG_COMMAND, u, this, ci) << text;
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SAY", _("SAY \037channel\037 \037text\037"));
}
};
class BSSay : public Module
{
CommandBSSay commandbssay;
public:
BSSay(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbssay);
}
};
MODULE_INIT(BSSay)
+42 -53
View File
@@ -12,18 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "botserv.h"
class CommandBSSet : public Command
{
public:
CommandBSSet() : Command("SET", 3, 3)
CommandBSSet(Module *creator) : Command(creator, "botserv/set", 3, 3)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Configures bot options"));
this->SetSyntax(_("\037(channel | bot)\037 \037option\037 \037settings\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
@@ -34,14 +33,14 @@ class CommandBSSet : public Command
if (readonly)
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
else if (u->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE"))
else if (u->HasCommand("botserv/botserv/set/private") && option.equals_ci("PRIVATE"))
{
BotInfo *bi;
if (!(bi = findbot(chan)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), chan.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, chan.c_str());
return;
}
if (value.equals_ci("ON"))
@@ -55,13 +54,13 @@ class CommandBSSet : public Command
source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
}
else
SyntaxError(source, "SET PRIVATE", _("SET \037botname\037 PRIVATE {\037ON|\037}"));
return MOD_CONT;
this->OnSyntaxError(source, "PRIVATE");
return;
}
else if (!(ci = cs_findchan(chan)))
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
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));
source.Reply(ACCESS_DENIED);
else
{
bool override = !check_access(u, ci, CA_SET);
@@ -80,7 +79,7 @@ class CommandBSSet : public Command
source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET DONTKICKOPS", _("SET \037channel\037 DONTKICKOPS {\037ON|\037}"));
this->OnSyntaxError(source, "DONTKICKOPS");
}
else if (option.equals_ci("DONTKICKVOICES"))
{
@@ -95,7 +94,7 @@ class CommandBSSet : public Command
source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET DONTKICKVOICES", _("SET \037channel\037 DONTKICKVOICES {\037ON|\037}"));
this->OnSyntaxError(source, "DONTKICKVOICE");
}
else if (option.equals_ci("FANTASY"))
{
@@ -110,7 +109,7 @@ class CommandBSSet : public Command
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET FANTASY", _("SET \037channel\037 FANTASY {\037ON|\037}"));
this->OnSyntaxError(source, "FANTASY");
}
else if (option.equals_ci("GREET"))
{
@@ -125,9 +124,9 @@ class CommandBSSet : public Command
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}"));
this->OnSyntaxError(source, "GREET");
}
else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
else if (u->HasCommand("botserv/botserv/set/nobot") && option.equals_ci("NOBOT"))
{
if (value.equals_ci("ON"))
{
@@ -142,22 +141,7 @@ class CommandBSSet : public Command
source.Reply(_("No Bot mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
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);
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);
source.Reply(_("Symbiosis mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET SYMBIOSIS", _("SET \037channel\037 SYMBIOSIS {\037ON|\037}"));
this->OnSyntaxError(source, "NOBOT");
}
else if (option.equals_ci("MSG"))
{
@@ -190,34 +174,33 @@ class CommandBSSet : public Command
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}"));
this->OnSyntaxError(source, "MSG");
}
else
source.Reply(_(UNKNOWN_OPTION), option.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str(), this->name.c_str());
source.Reply(UNKNOWN_OPTION, option.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), this->name.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(), Config->s_BotServ.c_str());
"level SET."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
User *u = source.u;
if (u->IsServicesOper())
source.Reply(_("These options are reserved to Services Operators:\n"
@@ -261,13 +244,6 @@ class CommandBSSet : public Command
"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"))
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"))
source.Reply(_("Syntax: \002SET \037channel\037 NOBOT {\037ON|OFF\037}\002\n"
" \n"
@@ -295,7 +271,22 @@ class CommandBSSet : public Command
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SET", _("SET \037(channel | bot)\037 \037option\037 \037settings\037"));
if (subcommand.empty())
Command::OnSyntaxError(source, "");
else if (subcommand.equals_ci("PRIVATE"))
this->SendSyntax(source, "\037botname\037 PRIVATE {\037ON|OFF\037}");
else if (subcommand.equals_ci("DONTKICKOPS"))
this->SendSyntax(source, "\037channel\037 DONTKICKOPS {\037ON|OFF\037}");
else if (subcommand.equals_ci("DONTKICKVOICES"))
this->SendSyntax(source, "\037channel\037 DONTKICKVOICES {\037ON|OFF\037}");
else if (subcommand.equals_ci("FANTASY"))
this->SendSyntax(source, "\037channel\037 FANTASY {\037ON|OFF\037}");
else if (subcommand.equals_ci("GREET"))
this->SendSyntax(source, "\037channel\037 GREET {\037ON|OFF\037}");
else if (subcommand.equals_ci("MSG"))
this->SendSyntax(source, "\037botname\037 NOBOT {\037ON|OFF\037}");
else if (subcommand.equals_ci("NOBOT"))
this->SendSyntax(source, "\037botname\037 NOBOT {\037ON|OFF\037}");
}
};
@@ -304,14 +295,12 @@ class BSSet : public Module
CommandBSSet commandbsset;
public:
BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsset(this)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsset);
ModuleManager::RegisterService(&commandbsset);
}
};
-85
View File
@@ -1,85 +0,0 @@
/* BotServ 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"
#include "botserv.h"
class CommandBSUnassign : public Command
{
public:
CommandBSUnassign() : Command("UNASSIGN", 1, 1)
{
this->SetDesc(_("Unassigns a bot from a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
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)
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
else if (ci->HasFlag(CI_PERSIST) && !cm)
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);
source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
}
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "UNASSIGN", _("UNASSIGN \037chan\037"));
}
};
class BSUnassign : public Module
{
CommandBSUnassign commandbsunassign;
public:
BSUnassign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!botserv)
throw ModuleException("BotServ is not loaded!");
this->AddCommand(botserv->Bot(), &commandbsunassign);
}
};
MODULE_INIT(BSUnassign)
-15
View File
@@ -1,15 +0,0 @@
#ifndef CHANSERV_H
#define CHANSERV_H
class ChanServService : public Service
{
public:
ChanServService(Module *m) : Service(m, "ChanServ") { }
virtual BotInfo *Bot() = 0;
};
static service_reference<ChanServService> chanserv("ChanServ");
#endif // CHANSERV_H
+133 -144
View File
@@ -12,43 +12,43 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class AccessListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AccessListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
AccessListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AccessListCallback()
{
if (SentHeader)
source.Reply(_("End of access list."), source.ci->name.c_str());
source.Reply(_("End of access list."), ci->name.c_str());
else
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAccessCount())
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
if (source.ci->HasFlag(CI_XOP))
if (ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
source.Reply(_(" %3d %s %s"), Number + 1, xop.c_str(), access->GetMask().c_str());
@@ -61,27 +61,26 @@ class AccessListCallback : public NumberList
class AccessViewCallback : public AccessListCallback
{
public:
AccessViewCallback(CommandSource &_source, const Anope::string &numlist) : AccessListCallback(_source, numlist)
AccessViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAccessCount())
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
ChannelInfo *ci = source.ci;
Anope::string timebuf;
if (ci->c && nc_on_chan(ci->c, access->nc))
timebuf = "Now";
@@ -93,52 +92,52 @@ class AccessViewCallback : public AccessListCallback
if (ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
source.Reply(_(CHAN_ACCESS_VIEW_XOP_FORMAT), Number + 1, xop.c_str(), access->GetMask().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
source.Reply(_(CHAN_ACCESS_VIEW_AXS_FORMAT), Number + 1, access->level, access->GetMask().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
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool Denied;
bool override;
public:
AccessDelCallback(CommandSource &_source, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), Denied(false)
AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false)
{
if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
if (!check_access(source.u, ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
this->override = true;
}
~AccessDelCallback()
{
if (Denied && !Deleted)
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!Deleted)
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s access list."), source.ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s access list."), Deleted, source.ci->name.c_str());
source.Reply(_("Deleted %d entries from %s access list."), Deleted, ci->name.c_str());
}
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAccessCount())
if (!Number || Number > ci->GetAccessCount())
return;
User *u = source.u;
ChannelInfo *ci = source.ci;
ChanAccess *access = ci->GetAccess(Number - 1);
@@ -164,10 +163,9 @@ class AccessDelCallback : public NumberList
class CommandCSAccess : public Command
{
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string mask = params[2];
int level = ACCESS_INVALID;
@@ -182,19 +180,19 @@ class CommandCSAccess : public Command
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;
source.Reply(ACCESS_DENIED);
return;
}
if (!level)
{
source.Reply(_("Access level must be non-zero."));
return MOD_CONT;
return;
}
else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
{
source.Reply(_(CHAN_ACCESS_LEVEL_RANGE), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
return MOD_CONT;
source.Reply(CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
return;
}
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= u_level;
@@ -209,13 +207,13 @@ class CommandCSAccess : public Command
/* Don't allow lowering from a level >= u_level */
if (access->level >= u_level && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (access->level == 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;
return;
}
access->level = level;
@@ -223,13 +221,13 @@ class CommandCSAccess : public Command
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;
return;
}
if (ci->GetAccessCount() >= Config->CSAccessMax)
{
source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
return MOD_CONT;
return;
}
access = ci->AddAccess(mask, level, u->nick);
@@ -239,13 +237,12 @@ class CommandCSAccess : public Command
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;
return;
}
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params[2];
@@ -253,7 +250,7 @@ class CommandCSAccess : public Command
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(source, this, mask);
AccessDelCallback list(source, ci, this, mask);
list.Process();
}
else
@@ -264,7 +261,7 @@ class CommandCSAccess : public Command
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));
source.Reply(ACCESS_DENIED);
else
{
source.Reply(_("\002%s\002 deleted from %s access list."), access->GetMask().c_str(), ci->name.c_str());
@@ -277,20 +274,18 @@ class CommandCSAccess : public Command
}
}
return MOD_CONT;
return;
}
CommandReturn DoList(CommandSource &source, const std::vector<Anope::string> &params)
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
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(source, nick);
AccessListCallback list(source, ci, nick);
list.Process();
}
else
@@ -307,10 +302,10 @@ class CommandCSAccess : public Command
if (!SentHeader)
{
SentHeader = true;
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
AccessListCallback::DoList(source, i, access);
AccessListCallback::DoList(source, ci, i, access);
}
if (SentHeader)
@@ -319,20 +314,18 @@ class CommandCSAccess : public Command
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoView(CommandSource &source, const std::vector<Anope::string> &params)
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
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(source, nick);
AccessViewCallback list(source, ci, nick);
list.Process();
}
else
@@ -349,10 +342,10 @@ class CommandCSAccess : public Command
if (!SentHeader)
{
SentHeader = true;
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
AccessViewCallback::DoList(source, i, access);
AccessViewCallback::DoList(source, ci, i, access);
}
if (SentHeader)
@@ -361,16 +354,15 @@ class CommandCSAccess : public Command
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoClear(CommandSource &source)
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else
{
ci->ClearAccess();
@@ -383,23 +375,33 @@ class CommandCSAccess : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
}
return MOD_CONT;
return;
}
public:
CommandCSAccess() : Command("ACCESS", 2, 4)
CommandCSAccess(Module *creator) : Command(creator, "chanserv/access", 2, 4)
{
this->SetDesc(_("Modify the list of privileged users"));
this->SetSyntax(_("\037channel\037 ADD \037mask\037 \037level\037"));
this->SetSyntax(_("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 CLEAR\002"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
bool is_clear = cmd.equals_ci("CLEAR");
@@ -425,54 +427,49 @@ class CommandCSAccess : public Command
if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
this->OnSyntaxError(source, cmd);
else if (!has_access)
source.Reply(_(ACCESS_DENIED));
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))
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());
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
else
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());
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
else if (readonly && !is_list)
source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
else if (cmd.equals_ci("ADD"))
this->DoAdd(source, params);
this->DoAdd(source, ci, params);
else if (cmd.equals_ci("DEL"))
this->DoDel(source, params);
this->DoDel(source, ci, params);
else if (cmd.equals_ci("LIST"))
this->DoList(source, params);
this->DoList(source, ci, params);
else if (cmd.equals_ci("VIEW"))
this->DoView(source, params);
this->DoView(source, ci, params);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(source);
this->DoClear(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
"privileges. Any nick not on the access list has\n"
"a user level of 0."));
source.Reply(" ");
source.Reply(_("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"
@@ -481,15 +478,15 @@ class CommandCSAccess : public Command
"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."));
source.Reply(" ");
source.Reply(_("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"
"do not have access to modify that list otherwise."));
source.Reply(" ");
source.Reply(_("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"
@@ -502,7 +499,7 @@ class CommandCSAccess : public Command
" \n"
"The \002ACCESS CLEAR\002 command clears all entries of the\n"
"access list."),
Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
source.owner->nick.c_str());
source.Reply(_("\002User access levels\002\n"
" \n"
"By default, the following access levels are defined:\n"
@@ -521,22 +518,16 @@ class CommandCSAccess : public Command
" \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."), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
"information."), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "ACCESS", _("ACCESS \037channel\037 {ADD|DEL|LIST|VIEW|CLEAR} [\037mask\037 [\037level\037] | \037entry-list\037]"));
}
};
class CommandCSLevels : public Command
{
CommandReturn DoSet(CommandSource &source, const std::vector<Anope::string> &params)
void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &what = params[2];
const Anope::string &lev = params[3];
@@ -555,7 +546,7 @@ class CommandCSLevels : public Command
catch (const ConvertException &)
{
this->OnSyntaxError(source, "SET");
return MOD_CONT;
return;
}
}
@@ -577,20 +568,19 @@ class CommandCSLevels : public Command
source.Reply(_("Level for %s on channel %s changed to founder only."), levelinfo[i].name.c_str(), ci->name.c_str());
else
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;
return;
}
}
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.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(), source.owner->nick.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoDisable(CommandSource &source, const std::vector<Anope::string> &params)
void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &what = params[2];
@@ -607,19 +597,17 @@ class CommandCSLevels : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << levelinfo[i].name;
source.Reply(_("\002%s\002 disabled on channel %s."), levelinfo[i].name.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
}
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.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(), source.owner->nick.c_str());
return MOD_CONT;
return;
}
CommandReturn DoList(CommandSource &source)
void DoList(CommandSource &source, ChannelInfo *ci)
{
ChannelInfo *ci = source.ci;
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
if (!levelinfo_maxwidth)
@@ -646,13 +634,12 @@ class CommandCSLevels : public Command
source.Reply(_(" %-*s %d"), levelinfo_maxwidth, levelinfo[i].name.c_str(), j);
}
return MOD_CONT;
return;
}
CommandReturn DoReset(CommandSource &source)
void DoReset(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
reset_levels(ci);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
@@ -661,23 +648,33 @@ class CommandCSLevels : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
return MOD_CONT;
return;
}
public:
CommandCSLevels() : Command("LEVELS", 2, 4)
CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4)
{
this->SetDesc(_("Redefine the meanings of access levels"));
this->SetSyntax(_("\037channel\037 SET \037type\037 \037level\037"));
this->SetSyntax(_("\037channel\037 {DIS | DISABLE} \037type\037"));
this->SetSyntax(_("\037channel\037 LIST"));
this->SetSyntax(_("\037channel\037 RESET"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[1];
const Anope::string &what = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
/* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
* one; else, we want none.
@@ -687,19 +684,19 @@ class CommandCSLevels : public Command
else if (ci->HasFlag(CI_XOP))
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));
source.Reply(ACCESS_DENIED);
else if (cmd.equals_ci("SET"))
this->DoSet(source, params);
this->DoSet(source, ci, params);
else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
this->DoDisable(source, params);
this->DoDisable(source, ci, params);
else if (cmd.equals_ci("LIST"))
this->DoList(source);
this->DoList(source, ci);
else if (cmd.equals_ci("RESET"))
this->DoReset(source);
this->DoReset(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -721,12 +718,10 @@ class CommandCSLevels : public Command
source.Reply(_(" %-*s %s"), levelinfo_maxwidth, levelinfo[i].name.c_str(), translate(source.u, levelinfo[i].desc));
}
else
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"
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -744,14 +739,10 @@ class CommandCSLevels : public Command
"\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."), Config->s_ChanServ.c_str());
"set, see \002HELP LEVELS DESC\002."), source.owner->nick.c_str());
}
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "LEVELS", _("LEVELS \037channel\037 {SET | DIS[ABLE] | LIST | RESET} [\037item\037 [\037level\037]]"));
}
};
class CSAccess : public Module
@@ -760,15 +751,13 @@ class CSAccess : public Module
CommandCSLevels commandcslevels;
public:
CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsaccess(this), commandcslevels(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsaccess);
this->AddCommand(chanserv->Bot(), &commandcslevels);
ModuleManager::RegisterService(&commandcsaccess);
ModuleManager::RegisterService(&commandcslevels);
}
};
+67 -78
View File
@@ -12,12 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
/* Split a usermask up into its constitutent parts. Returned strings are
* malloc()'d, and should be free()'d when done with. Returns "*" for
* missing parts.
*/
static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope::string &user, Anope::string &host)
{
@@ -56,69 +50,70 @@ class AkickListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AkickListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
AkickListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AkickListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s autokick list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
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));
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(CommandSource &_source, const Anope::string &numlist) : AkickListCallback(_source, numlist)
AkickViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
Anope::string timebuf;
if (akick->addtime)
timebuf = do_strftime(akick->addtime);
else
timebuf = _(UNKNOWN);
timebuf = UNKNOWN;
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));
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)
source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str());
@@ -128,17 +123,17 @@ class AkickViewCallback : public AkickListCallback
class AkickDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
public:
AkickDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0)
AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), 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";
@@ -152,20 +147,19 @@ class AkickDelCallback : public NumberList
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
++Deleted;
source.ci->EraseAkick(Number - 1);
ci->EraseAkick(Number - 1);
}
};
class CommandCSAKick : public Command
{
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string mask = params[2];
Anope::string reason = params.size() > 3 ? params[3] : "";
@@ -191,7 +185,7 @@ class CommandCSAKick : public Command
{
if (Anope::Match(modes.first->second, mask))
{
source.Reply(_(CHAN_EXCEPTED), mask.c_str(), ci->name.c_str());
source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
return;
}
}
@@ -205,7 +199,7 @@ class CommandCSAKick : public Command
int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0;
if (nc == ci->GetFounder() || nc_level >= u_level)
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -223,7 +217,7 @@ class CommandCSAKick : public Command
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && entry_mask.Matches(u2))
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -241,7 +235,7 @@ class CommandCSAKick : public Command
Anope::string buf = na->nick + "!" + na->last_usermask;
if (Anope::Match(buf, mask))
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -276,13 +270,12 @@ class CommandCSAKick : public Command
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
this->DoEnforce(source);
this->DoEnforce(source, ci);
}
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params[2];
AutoKick *akick;
@@ -297,7 +290,7 @@ class CommandCSAKick : public Command
/* 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(source, this, mask);
AkickDelCallback list(source, ci, this, mask);
list.Process();
}
else
@@ -328,10 +321,9 @@ class CommandCSAKick : public Command
}
}
void DoList(CommandSource &source, const std::vector<Anope::string> &params)
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
@@ -346,7 +338,7 @@ class CommandCSAKick : public Command
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickListCallback list(source, mask);
AkickListCallback list(source, ci, mask);
list.Process();
}
else
@@ -371,7 +363,7 @@ class CommandCSAKick : public Command
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickListCallback::DoList(source, i, akick);
AkickListCallback::DoList(source, ci, i, akick);
}
if (!SentHeader)
@@ -379,10 +371,9 @@ class CommandCSAKick : public Command
}
}
void DoView(CommandSource &source, const std::vector<Anope::string> &params)
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
@@ -397,7 +388,7 @@ class CommandCSAKick : public Command
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickViewCallback list(source, mask);
AkickViewCallback list(source, ci, mask);
list.Process();
}
else
@@ -422,7 +413,7 @@ class CommandCSAKick : public Command
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickViewCallback::DoList(source, i, akick);
AkickViewCallback::DoList(source, ci, i, akick);
}
if (!SentHeader)
@@ -430,16 +421,15 @@ class CommandCSAKick : public Command
}
}
void DoEnforce(CommandSource &source)
void DoEnforce(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
int count = 0;
if (!c)
{
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
return;
}
@@ -457,10 +447,9 @@ class CommandCSAKick : public Command
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
}
void DoClear(CommandSource &source)
void DoClear(CommandSource &source, ChannelInfo *ci)
{
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";
@@ -469,54 +458,61 @@ class CommandCSAKick : public Command
}
public:
CommandCSAKick() : Command("AKICK", 2, 4)
CommandCSAKick(Module *creator) : Command(creator, "chanserv/akick", 2, 4)
{
this->SetDesc(_("Maintain the AutoKick list"));
this->SetSyntax(_("\037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 ENFORCE"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string cmd = params[1];
Anope::string mask = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
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));
source.Reply(ACCESS_DENIED);
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
else if (cmd.equals_ci("ADD"))
this->DoAdd(source, params);
this->DoAdd(source, ci, params);
else if (cmd.equals_ci("DEL"))
this->DoDel(source, params);
this->DoDel(source, ci, params);
else if (cmd.equals_ci("LIST"))
this->DoList(source, params);
this->DoList(source, ci, params);
else if (cmd.equals_ci("VIEW"))
this->DoView(source, params);
this->DoView(source, ci, params);
else if (cmd.equals_ci("ENFORCE"))
this->DoEnforce(source);
this->DoEnforce(source, ci);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(source);
this->DoClear(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -529,7 +525,7 @@ class CommandCSAKick : public Command
"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"),
Config->s_ChanServ.c_str());
source.owner->nick.c_str());
source.Reply(_(
" \n"
"The \002AKICK DEL\002 command removes the given nick or mask\n"
@@ -549,14 +545,9 @@ class CommandCSAKick : public Command
"AKICK mask.\n"
" \n"
"The \002AKICK CLEAR\002 command clears all entries of the\n"
"akick list."), Config->s_ChanServ.c_str());
"akick list."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "AKICK", _("AKICK \037channel\037 {ADD | DEL | LIST | VIEW | ENFORCE | CLEAR} [\037nick-or-usermask\037] [\037reason\037]"));
}
};
class CSAKick : public Module
@@ -564,14 +555,12 @@ class CSAKick : public Module
CommandCSAKick commandcsakick;
public:
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsakick(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsakick);
ModuleManager::RegisterService(&commandcsakick);
}
};
+23 -25
View File
@@ -12,24 +12,30 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSBan : public Command
{
public:
CommandCSBan(const Anope::string &cname) : Command("BAN", 2, 3)
CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 3)
{
this->SetDesc(_("Bans a selected nick on a channel"));
this->SetSyntax(_("\037#channel\037 \037nick\037 [\037reason\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
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);
@@ -38,21 +44,21 @@ class CommandCSBan : public Command
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.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());
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))
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
/*
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
source.Reply(_(CHAN_EXCEPTED), u2->nick.c_str(), ci->name.c_str());
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else
{
Anope::string mask;
@@ -65,7 +71,7 @@ class CommandCSBan : public Command
/* We still allow host banning while not allowing to kick */
if (!c->FindUser(u2))
return MOD_CONT;
return;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
@@ -73,24 +79,19 @@ class CommandCSBan : public Command
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BAN \037#channel\037 \037nick\037 [\037reason\037]\002\n"
" \n"
"Bans a selected nick on a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "BAN", _("BAN \037#channel\037 \037nick\037 [\037reason\037]"));
}
};
class CSBan : public Module
@@ -98,14 +99,11 @@ class CSBan : public Module
CommandCSBan commandcsban;
public:
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsban("BAN")
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsban(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsban);
ModuleManager::RegisterService(&commandcsban);
}
};
+18 -25
View File
@@ -12,30 +12,30 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSClearUsers : public Command
{
public:
CommandCSClearUsers() : Command("CLEARUSERS", 1, 1)
CommandCSClearUsers(Module *creator) : Command(creator, "chanserv/clearusers", 1, 1)
{
this->SetDesc(Anope::printf(_("Tells %s to kick all users on a channel"), Config->s_ChanServ.c_str()));
this->SetDesc(_("Kicks all users on a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(chan);
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));
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!check_access(u, c->ci, CA_FOUNDER))
source.Reply(ACCESS_DENIED);
Anope::string buf = "CLEARUSERS command from " + u->nick + " (" + u->Account()->display + ")";
@@ -48,24 +48,19 @@ class CommandCSClearUsers : public Command
source.Reply(_("All users have been kicked from \2%s\2."), chan.c_str());
return MOD_CONT;
return;
}
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."
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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."), Config->s_ChanServ.c_str());
"channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CLEAR", _("CLEARUSERS \037channel\037"));
}
};
class CSClearUsers : public Module
@@ -73,14 +68,12 @@ class CSClearUsers : public Module
CommandCSClearUsers commandcsclearusers;
public:
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsclearusers(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsclearusers);
ModuleManager::RegisterService(&commandcsclearusers);
}
};
+25 -28
View File
@@ -12,46 +12,51 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSClone : public Command
{
public:
CommandCSClone() : Command("CLONE", 2, 3)
CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3)
{
this->SetDesc(_("Copy all settings from one channel to another"));
this->SetSyntax(_("\037channel\037 \037target\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
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;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!check_access(u, ci, CA_SET))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
ChannelInfo *target_ci = cs_findchan(target);
if (!target_ci)
{
source.Reply(_(CHAN_X_NOT_REGISTERED), target.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
return;
}
if (!IsFounder(u, ci) || !IsFounder(u, target_ci))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
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;
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return;
}
if (what.equals_ci("ALL"))
@@ -98,7 +103,7 @@ public:
target_ci->last_topic_time = target_ci->c->topic_time;
}
else
target_ci->last_topic_setter = Config->s_ChanServ;
target_ci->last_topic_setter = source.owner->nick;
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci));
@@ -143,29 +148,24 @@ public:
else
{
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name;
return MOD_CONT;
return;
}
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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
@@ -173,14 +173,11 @@ class CSClone : public Module
CommandCSClone commandcsclone;
public:
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsclone(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsclone);
ModuleManager::RegisterService(&commandcsclone);
}
};
+24 -29
View File
@@ -12,42 +12,47 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSDrop : public Command
{
public:
CommandCSDrop() : Command("DROP", 1, 1)
CommandCSDrop(Module *creator) : Command(creator, "chanserv/drop", 1, 1)
{
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetDesc(_("Cancel the registration of a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
return MOD_CONT;
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
ci = cs_findchan(chan);
if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop"))
if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/chanserv/drop"))
{
source.Reply(_(CHAN_X_SUSPENDED), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_SUSPENDED, chan.c_str());
return;
}
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/chanserv/drop"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (ci->c && ModeManager::FindChannelModeByName(CMODE_REGISTERED))
@@ -62,30 +67,23 @@ class CommandCSDrop : public Command
FOREACH_MOD(I_OnChanDrop, OnChanDrop(chan));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
this->SendSyntax(source);
source.Reply(" ");
if (u->IsServicesOper())
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Only \002Services Operators\002\n"
source.Reply(_("Unregisters the named channel. Only \002Services Operators\002\n"
"can drop a channel for which they have not identified."));
else
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Can only be used by\n"
source.Reply(_("Unregisters the named channel. Can only be used by\n"
"\002channel founder\002."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DROP", _("DROP \037channel\037"));
}
};
class CSDrop : public Module
@@ -93,14 +91,11 @@ class CSDrop : public Module
CommandCSDrop commandcsdrop;
public:
CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsdrop(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsdrop);
ModuleManager::RegisterService(&commandcsdrop);
}
};
+21 -23
View File
@@ -12,55 +12,56 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSGetKey : public Command
{
public:
CommandCSGetKey() : Command("GETKEY", 1, 1)
CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
{
this->SetDesc(_("Returns the key of the given channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/chanserv/getkey"))
{
source.Reply(ACCESS_DENIED);
return;
}
Anope::string key;
if (!ci->c || !ci->c->GetParam(CMODE_KEY, key))
{
source.Reply(_("The channel \002%s\002 has no key."), chan.c_str());
return MOD_CONT;
return;
}
bool override = !check_access(u, ci, CA_GETKEY);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002GETKEY \037channel\037\002\n"
" \n"
"Returns the key of the given channel."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Returns the key of the given channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "GETKEY", _("GETKEY \037channel\037"));
}
};
class CSGetKey : public Module
@@ -68,14 +69,11 @@ class CSGetKey : public Module
CommandCSGetKey commandcsgetkey;
public:
CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsgetkey(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsgetkey);
ModuleManager::RegisterService(&commandcsgetkey);
}
};
-76
View File
@@ -1,76 +0,0 @@
/* 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"
#include "chanserv.h"
class CommandCSHelp : public Command
{
public:
CommandCSHelp() : Command("HELP", 1, 1)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(chanserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
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."),
Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str());
for (CommandMap::const_iterator it = chanserv->Bot()->Commands.begin(); it != chanserv->Bot()->Commands.end(); ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
if (Config->CSExpire >= 86400)
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."));
}
};
class CSHelp : public Module
{
CommandCSHelp commandcshelp;
public:
CSHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcshelp);
}
};
MODULE_INIT(CSHelp)
+19 -22
View File
@@ -12,7 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSInfo : public Command
{
@@ -28,19 +27,24 @@ class CommandCSInfo : public Command
}
public:
CommandCSInfo() : Command("INFO", 1, 2)
CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetDesc(_("Lists information about the named registered channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex");
bool show_all = false;
@@ -49,7 +53,7 @@ class CommandCSInfo : public Command
if (has_auspex || check_access(u, ci, CA_INFO))
show_all = true;
source.Reply(_(CHAN_INFO_HEADER), chan.c_str());
source.Reply(CHAN_INFO_HEADER, chan.c_str());
if (ci->GetFounder())
source.Reply(_(" Founder: %s"), ci->GetFounder()->display.c_str());
@@ -89,7 +93,7 @@ class CommandCSInfo : public Command
CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, u->Account());
CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, u->Account());
source.Reply(_(NICK_INFO_OPTIONS), optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(NICK_INFO_OPTIONS, optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(_(" Mode lock: %s"), ci->GetMLockAsString(true).c_str());
if (!ci->HasFlag(CI_NO_EXPIRE))
@@ -100,30 +104,25 @@ class CommandCSInfo : public Command
Anope::string by, reason;
ci->GetExtRegular("suspend_by", by);
ci->GetExtRegular("suspend_reason", reason);
source.Reply(_(" Suspended: [%s] %s"), by.c_str(), !reason.empty() ? reason.c_str() : _(NO_REASON));
source.Reply(_(" Suspended: [%s] %s"), by.c_str(), !reason.empty() ? reason.c_str() : NO_REASON);
}
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INFO \037channel\037\002\n"
" \n"
"Lists information about the named registered channel,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INFO", _("INFO \037channel\037"));
}
};
class CSInfo : public Module
@@ -131,14 +130,12 @@ class CSInfo : public Module
CommandCSInfo commandcsinfo;
public:
CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsinfo(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsinfo);
ModuleManager::RegisterService(&commandcsinfo);
}
};
+25 -29
View File
@@ -12,36 +12,40 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSInvite : public Command
{
public:
CommandCSInvite() : Command("INVITE", 1, 3)
CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
{
this->SetDesc(Anope::printf(_("Tells %s to invite you into a channel"), Config->s_ChanServ.c_str()));
this->SetDesc(_("Invites you into a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(chan);
if (!(c = findchan(chan)))
if (!c)
{
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
ci = c->ci;
ChannelInfo *ci = c->ci;
if (!ci)
{
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
if (!check_access(u, ci, CA_INVITE))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
User *u2;
@@ -51,8 +55,8 @@ class CommandCSInvite : public Command
{
if (!(u2 = finduser(params[1])))
{
source.Reply(_(NICK_X_NOT_IN_USE), params[1].c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
return;
}
}
@@ -67,24 +71,19 @@ class CommandCSInvite : public Command
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INVITE \037channel\037\002\n"
" \n"
"Tells %s to invite you into the given channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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."), Config->s_ChanServ.c_str());
"on the channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INVITE", _("INVITE \037channel\037"));
}
};
class CSInvite : public Module
@@ -92,14 +91,11 @@ class CSInvite : public Module
CommandCSInvite commandcsinvite;
public:
CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsinvite(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsinvite);
ModuleManager::RegisterService(&commandcsinvite);
}
};
+19 -25
View File
@@ -12,25 +12,25 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSKick : public Command
{
public:
CommandCSKick() : Command("KICK", 2, 3)
CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
{
this->SetDesc(_("Kicks a selected nick from a channel"));
this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
ChannelInfo *ci = cs_findchan(params[0]);
Channel *c = findchan(params[0]);
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
@@ -38,17 +38,19 @@ class CommandCSKick : public Command
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
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), target.c_str());
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))
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (u2->IsProtected())
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(_(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
@@ -59,24 +61,19 @@ class CommandCSKick : public Command
else
ci->c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002KICK \037#channel\037 \037nick\037 [\037reason\037]\002\n"
" \n"
"Kicks a selected nick on a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "KICK", _("KICK \037#channel\037 \037nick\037 [\037reason\037]"));
}
};
class CSKick : public Module
@@ -84,14 +81,11 @@ class CSKick : public Module
CommandCSKick commandcskick;
public:
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcskick(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcskick);
ModuleManager::RegisterService(&commandcskick);
}
};
+15 -23
View File
@@ -12,31 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSList : public Command
{
public:
CommandCSList() : Command("LIST", 1, 2)
CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Lists all registered channels matching the given pattern"));
this->SetSyntax(_("\037pattern\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string pattern = params[0];
unsigned nchans;
bool is_servadmin = u->HasCommand("chanserv/list");
bool is_servadmin = u->HasCommand("chanserv/chanserv/list");
int count = 0, from = 0, to = 0;
bool suspended = false, channoexpire = false;
if (Config->CSListOpersOnly && !u->HasMode(UMODE_OPER))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (pattern[0] == '#')
@@ -51,10 +51,10 @@ class CommandCSList : public Command
}
catch (const ConvertException &)
{
source.Reply(_(LIST_INCORRECT_RANGE));
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;
return;
}
pattern = "*";
@@ -77,7 +77,7 @@ class CommandCSList : public Command
Anope::string spattern = "#" + pattern;
source.Reply(_(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)
{
@@ -111,24 +111,19 @@ class CommandCSList : public Command
}
source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002LIST \037pattern\037\002\n"
" \n"
"Lists all registered channels matching the given pattern.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX));
}
};
class CSList : public Module
@@ -136,14 +131,11 @@ class CSList : public Module
CommandCSList commandcslist;
public:
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcslist(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcslist);
ModuleManager::RegisterService(&commandcslist);
}
};
+33 -143
View File
@@ -12,154 +12,20 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
static BotInfo *ChanServ = NULL;
class ChanServBotInfo : public BotInfo
{
public:
ChanServBotInfo(const Anope::string &bnick, const Anope::string &user = "", const Anope::string &bhost = "", const Anope::string &real = "") : BotInfo(bnick, user, bhost, real) { }
void OnMessage(User *u, const Anope::string &message)
{
if (!u->HasMode(UMODE_OPER) && Config->CSOpersOnly)
{
u->SendMessage(ChanServ, ACCESS_DENIED);
return;
}
spacesepstream sep(message);
Anope::string command, param;
if (sep.GetToken(command) && sep.GetToken(param))
{
Command *c = FindCommand(this, command);
if (c && !c->HasFlag(CFLAG_STRIP_CHANNEL))
{
if (ircdproto->IsChannelValid(param))
{
ChannelInfo *ci = cs_findchan(param);
if (ci)
{
if (ci->HasFlag(CI_SUSPENDED) && !c->HasFlag(CFLAG_ALLOW_SUSPENDED))
{
u->SendMessage(this, CHAN_X_SUSPENDED, ci->name.c_str());
Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of SUSPENDED channel " << ci->name;
return;
}
}
else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL))
{
u->SendMessage(this, CHAN_X_NOT_REGISTERED, param.c_str());
return;
}
}
/* A user not giving a channel name for a param that should be a channel */
else
{
u->SendMessage(this, CHAN_X_INVALID, param.c_str());
return;
}
}
}
BotInfo::OnMessage(u, message);
}
};
class MyChanServService : public ChanServService
{
public:
MyChanServService(Module *m) : ChanServService(m) { }
BotInfo *Bot()
{
return ChanServ;
}
};
class ExpireCallback : public CallBack
{
public:
ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
void Tick(time_t)
{
if (!Config->CSExpire || noexpire || readonly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; )
{
ChannelInfo *ci = it->second;
++it;
bool expire = false;
if (ci->HasFlag(CI_SUSPENDED))
{
if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire)
expire = true;
}
else if (!ci->c && Anope::CurTime - ci->last_used >= Config->CSExpire)
expire = true;
if (ci->HasFlag(CI_NO_EXPIRE))
expire = false;
if (expire)
{
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
if (MOD_RESULT == EVENT_STOP)
continue;
Anope::string extra;
if (ci->HasFlag(CI_SUSPENDED))
extra = "suspended ";
Log(LOG_NORMAL, "chanserv/expire", ChanServ) << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci));
delete ci;
}
}
}
};
class ChanServCore : public Module
{
MyChanServService mychanserv;
ExpireCallback expires;
public:
ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), mychanserv(this), expires(this)
ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&this->mychanserv);
BotInfo *ChanServ = findbot(Config->ChanServ);
if (ChanServ == NULL)
throw ModuleException("No bot named " + Config->ChanServ);
ChanServ = new ChanServBotInfo(Config->s_ChanServ, Config->ServiceUser, Config->ServiceHost, Config->desc_ChanServ);
ChanServ->SetFlag(BI_CORE);
Implementation i[] = { I_OnDelCore, I_OnDelChan };
ModuleManager::Attach(i, this, 2);
spacesepstream coreModules(Config->ChanCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
ModuleManager::LoadModule(module, NULL);
}
~ChanServCore()
{
spacesepstream coreModules(Config->ChanCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
{
Module *m = ModuleManager::FindModule(module);
if (m != NULL)
ModuleManager::UnloadModule(m, NULL);
}
delete ChanServ;
Implementation i[] = { I_OnDelChan, I_OnPreHelp, I_OnPostHelp };
ModuleManager::Attach(i, this, 3);
}
void OnDelCore(NickCore *nc)
@@ -222,10 +88,34 @@ class ChanServCore : public Module
}
}
void OnDelChan(ChannelInfo *ci)
void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
if (!params.empty() || source.owner->nick != Config->ChanServ)
return;
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.\n "),
Config->ChanServ.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->ChanServ.c_str(), source.command.c_str());
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (!params.empty() || source.owner->nick != Config->ChanServ)
return;
if (Config->CSExpire >= 86400)
source.Reply(_(" \n"
"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 (source.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."));
}
};
+19 -28
View File
@@ -12,7 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSMode : public Command
{
@@ -37,10 +36,9 @@ class CommandCSMode : public Command
return false;
}
void DoLock(CommandSource &source, const std::vector<Anope::string> &params)
void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &subcommand = params[2];
const Anope::string &param = params.size() > 3 ? params[3] : "";
@@ -159,10 +157,9 @@ class CommandCSMode : public Command
this->OnSyntaxError(source, subcommand);
}
void DoSet(CommandSource &source, const std::vector<Anope::string> &params)
void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
spacesepstream sep(params.size() > 3 ? params[3] : "");
Anope::string modes = params[2], param;
@@ -301,38 +298,39 @@ class CommandCSMode : public Command
}
public:
CommandCSMode() : Command("MODE", 3, 4)
CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 3, 4)
{
this->SetDesc(_("Control modes and mode locks on a channel"));
this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]"));
this->SetSyntax(_("\037channel\037 SET \037modes\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &subcommand = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
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));
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/chanserv/mode"))
source.Reply(ACCESS_DENIED);
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, params);
this->DoLock(source, ci, params);
else if (subcommand.equals_ci("SET"))
this->DoSet(source, params);
this->DoSet(source, ci, params);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -350,11 +348,6 @@ class CommandCSMode : public Command
" 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
@@ -362,14 +355,12 @@ class CSMode : public Module
CommandCSMode commandcsmode;
public:
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsmode(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsmode);
ModuleManager::RegisterService(&commandcsmode);
}
};
+85 -163
View File
@@ -12,7 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandModeBase : public Command
{
@@ -28,7 +27,7 @@ class CommandModeBase : public Command
* @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)
void do_util(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;
@@ -38,7 +37,7 @@ class CommandModeBase : public Command
else
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself, notice);
return MOD_CONT;
return;
}
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)
@@ -54,19 +53,19 @@ class CommandModeBase : public Command
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!ci)
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str());
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));
source.Reply(ACCESS_DENIED);
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!set && u2->IsProtected() && !is_same)
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(_(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
{
if (set)
@@ -82,18 +81,21 @@ class CommandModeBase : public Command
public:
CommandModeBase(const Anope::string &cname) : Command(cname, 0, 2) { }
CommandModeBase(Module *creator, const Anope::string &cname) : Command(creator, cname, 0, 2)
{
this->SetSyntax(_("[\037#channel\037] [\037nick\037]"));
}
};
class CommandCSOp : public CommandModeBase
{
public:
CommandCSOp() : CommandModeBase("OP")
CommandCSOp(Module *creator) : CommandModeBase(creator, "chanserv/op")
{
this->SetDesc(_("Gives Op status to a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
@@ -102,9 +104,9 @@ class CommandCSOp : public CommandModeBase
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -112,22 +114,17 @@ class CommandCSOp : public CommandModeBase
"and above on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "OP", _("OP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeOp : public CommandModeBase
{
public:
CommandCSDeOp() : CommandModeBase("DEOP")
CommandCSDeOp(Module *creator) : CommandModeBase(creator, "chanserv/deop")
{
this->SetDesc(_("Deops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
@@ -136,32 +133,27 @@ class CommandCSDeOp : public CommandModeBase
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply("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."));
"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")
CommandCSVoice(Module *creator) : CommandModeBase(creator, "chanserv/voice")
{
this->SetDesc(_("Voices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
@@ -170,9 +162,9 @@ class CommandCSVoice : public CommandModeBase
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -181,22 +173,17 @@ class CommandCSVoice : public CommandModeBase
"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")
CommandCSDeVoice(Module *creator) : CommandModeBase(creator, "chanserv/devoice")
{
this->SetDesc(_("Devoices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
@@ -205,9 +192,9 @@ class CommandCSDeVoice : public CommandModeBase
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -216,36 +203,31 @@ class CommandCSDeVoice : public CommandModeBase
"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")
CommandCSHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/halfop")
{
this->SetDesc(_("Halfops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -253,36 +235,31 @@ class CommandCSHalfOp : public CommandModeBase
"and above on the channel, or to HOPs or those with level 4 \n"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "HALFOP", _("HALFOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeHalfOp : public CommandModeBase
{
public:
CommandCSDeHalfOp() : CommandModeBase("DEHALFOP")
CommandCSDeHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/dehalfop")
{
this->SetDesc(_("Dehalfops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return;
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -291,36 +268,31 @@ class CommandCSDeHalfOp : public CommandModeBase
"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")
CommandCSProtect(Module *creator) : CommandModeBase(creator, "chanserv/protect")
{
this->SetDesc(_("Protects a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -328,119 +300,99 @@ class CommandCSProtect : public CommandModeBase
"level 10 and above on the channel for self protecting."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "PROTECT", _("PROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeProtect : public CommandModeBase
{
public:
CommandCSDeProtect() : CommandModeBase("DEPROTECT")
CommandCSDeProtect(Module *creator) : CommandModeBase(creator, "chanserv/deprotect")
{
this->SetDesc(_("Deprotects a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEPROTECT", _("DEROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSOwner : public CommandModeBase
{
public:
CommandCSOwner() : CommandModeBase("OWNER")
CommandCSOwner(Module *creator) : CommandModeBase(module, "chanserv/owner")
{
this->SetDesc(_("Gives you owner status on channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "OWNER", _("OWNER [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeOwner : public CommandModeBase
{
public:
CommandCSDeOwner() : CommandModeBase("DEOWNER")
CommandCSDeOwner(Module *creator) : CommandModeBase(creator, "chanserv/deowner")
{
this->SetDesc(_("Removes your owner status on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEOWNER", _("DEOWNER [\037#channel\037] [\037nick\037]\002"));
}
};
class CSModes : public Module
@@ -457,54 +409,24 @@ class CSModes : public Module
CommandCSDeVoice commandcsdevoice;
public:
CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsowner(this), commandcsdeowner(this), commandcsprotect(this), commandcsdeprotect(this),
commandcsop(this), commandcsdeop(this), commandcshalfop(this), commandcsdehalfop(this),
commandcsvoice(this), commandcsdevoice(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsop);
this->AddCommand(chanserv->Bot(), &commandcsdeop);
this->AddCommand(chanserv->Bot(), &commandcsvoice);
this->AddCommand(chanserv->Bot(), &commandcsdevoice);
if (Me && Me->IsSynced())
OnUplinkSync(NULL);
Implementation i[] = {I_OnUplinkSync, I_OnServerDisconnect};
ModuleManager::Attach(i, this, 2);
}
void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
{
this->AddCommand(chanserv->Bot(), &commandcsowner);
this->AddCommand(chanserv->Bot(), &commandcsdeowner);
}
if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
{
this->AddCommand(chanserv->Bot(), &commandcsprotect);
this->AddCommand(chanserv->Bot(), &commandcsdeprotect);
}
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
{
this->AddCommand(chanserv->Bot(), &commandcshalfop);
this->AddCommand(chanserv->Bot(), &commandcsdehalfop);
}
}
void OnServerDisconnect()
{
this->DelCommand(chanserv->Bot(), &commandcsowner);
this->DelCommand(chanserv->Bot(), &commandcsdeowner);
this->DelCommand(chanserv->Bot(), &commandcsprotect);
this->DelCommand(chanserv->Bot(), &commandcsdeprotect);
this->DelCommand(chanserv->Bot(), &commandcshalfop);
this->DelCommand(chanserv->Bot(), &commandcsdehalfop);
ModuleManager::RegisterService(&commandcsop);
ModuleManager::RegisterService(&commandcsdeop);
ModuleManager::RegisterService(&commandcsvoice);
ModuleManager::RegisterService(&commandcsdevoice);
ModuleManager::RegisterService(&commandcsowner);
ModuleManager::RegisterService(&commandcsdeowner);
ModuleManager::RegisterService(&commandcsprotect);
ModuleManager::RegisterService(&commandcsdeprotect);
ModuleManager::RegisterService(&commandcshalfop);
ModuleManager::RegisterService(&commandcsdehalfop);
}
};
+67 -21
View File
@@ -12,25 +12,24 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSRegister : public Command
{
public:
CommandCSRegister() : Command("REGISTER", 2, 2)
CommandCSRegister(Module *creator) : Command(creator, "chanserv/register", 2, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
this->SetDesc(_("Register a channel"));
this->SetSyntax(_("\037channel\037 \037description\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &chdesc = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = findchan(chan);
Channel *c = findchan(params[0]);
ChannelInfo *ci = cs_findchan(params[0]);
if (readonly)
source.Reply(_("Sorry, channel registration is temporarily disabled."));
@@ -39,15 +38,15 @@ class CommandCSRegister : public Command
else if (chan[0] == '&')
source.Reply(_("Local channels cannot be registered."));
else if (chan[0] != '#')
source.Reply(_(CHAN_SYMBOL_REQUIRED));
source.Reply(CHAN_SYMBOL_REQUIRED);
else if (!ircdproto->IsChannelValid(chan))
source.Reply(_(CHAN_X_INVALID), 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))
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);
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
else
{
ci = new ChannelInfo(chan);
@@ -61,7 +60,7 @@ class CommandCSRegister : public Command
ci->last_topic_time = c->topic_time;
}
else
ci->last_topic_setter = Config->s_ChanServ;
ci->last_topic_setter = source.owner->nick;
ci->bi = NULL;
Log(LOG_COMMAND, u, this, ci);
@@ -92,14 +91,14 @@ class CommandCSRegister : public Command
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci));
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002REGISTER \037channel\037 \037description\037\002\n"
" \n"
"Registers a channel in the %s database. In order\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -117,29 +116,76 @@ class CommandCSRegister : public Command
"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."),
Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
source.owner->nick.c_str(), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
class ExpireCallback : public CallBack
{
public:
ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
void Tick(time_t)
{
SyntaxError(source, "REGISTER", _("REGISTER \037channel\037 \037description\037"));
if (!Config->CSExpire || noexpire || readonly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; )
{
ChannelInfo *ci = it->second;
++it;
bool expire = false;
if (ci->HasFlag(CI_SUSPENDED))
{
if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire)
expire = true;
}
else if (!ci->c && Anope::CurTime - ci->last_used >= Config->CSExpire)
expire = true;
if (ci->HasFlag(CI_NO_EXPIRE))
expire = false;
if (expire)
{
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
if (MOD_RESULT == EVENT_STOP)
continue;
Anope::string extra;
if (ci->HasFlag(CI_SUSPENDED))
extra = "suspended ";
Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci));
delete ci;
}
}
}
};
class CSRegister : public Module
{
CommandCSRegister commandcsregister;
ExpireCallback ecb;
public:
CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsregister(this), ecb(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
ModuleManager::RegisterService(&commandcsregister);
ModuleManager::Attach(I_OnDelChan, this);
}
this->AddCommand(chanserv->Bot(), &commandcsregister);
void OnDelChan(ChannelInfo *ci)
{
if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
}
};
+28 -97
View File
@@ -12,113 +12,46 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSASet : public Command
{
typedef std::map<Anope::string, Command *, std::less<ci::string> > subcommand_map;
subcommand_map subcommands;
public:
CommandCSSASet() : Command("SASET", 2, 3)
CommandCSSASet(Module *creator) : Command(creator, "chanserv/saset", 2, 3, "chanserv/saset")
{
this->SetDesc(_("Forcefully set channel options and information"));
this->SetSyntax(_("\002channel\002 \037option\037 \037parameters\037"));
}
~CommandCSSASet()
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
this->subcommands.clear();
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
if (readonly)
{
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;
}
Command *c = this->FindCommand(params[1]);
if (c)
{
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->Bot(), u, NULL, c, params[1], cmdparams);
}
else
{
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;
this->OnSyntaxError(source, "");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows Services Operators to forcefully change settings\n"
"on channels.\n"
" \n"
"Available options:"));
Anope::string this_name = source.command;
for (command_map::iterator it = source.owner->commands.begin(), it_end = source.owner->commands.end(); it != it_end; ++it)
{
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(source);
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
if (it->first.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(it->second);
if (command)
{
source.command = it->first;
command->OnServHelp(source);
}
}
}
else
{
Command *c = this->FindCommand(subcommand);
if (c)
return c->OnHelp(source, subcommand);
}
return false;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
bool AddSubcommand(Module *creator, Command *c)
{
c->module = creator;
c->service = this->service;
return this->subcommands.insert(std::make_pair(c->name, c)).second;
}
bool DelSubcommand(Command *c)
{
return this->subcommands.erase(c->name);
}
Command *FindCommand(const Anope::string &subcommand)
{
subcommand_map::const_iterator it = this->subcommands.find(subcommand);
if (it != this->subcommands.end())
return it->second;
return NULL;
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
@@ -127,14 +60,12 @@ class CSSASet : public Module
CommandCSSASet commandcssaset;
public:
CSSASet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSASet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssaset(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcssaset);
ModuleManager::RegisterService(&commandcssaset);
}
};
+23 -29
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSASetNoexpire : public Command
{
public:
CommandCSSASetNoexpire() : Command("NOEXPIRE", 2, 2, "chanserv/saset/noexpire")
CommandCSSASetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2, "chanserv/saset/noexpire")
{
this->SetDesc(_("Prevent the channel from expiring"));
this->SetDesc(_("\037channel\037 NOEXPIRE {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSASetNoexpire");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,22 +51,17 @@ class CommandCSSASetNoexpire : public Command
else
this->OnSyntaxError(source, "NOEXPIRE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002SET \037channel\037 NOEXPIRE {ON | OFF}\002\n"
" \n"
"Sets whether the given channel will expire. Setting this\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Sets whether the given channel will expire. Setting this\n"
"to ON prevents the channel from expiring."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET NOEXPIRE", _("SET \037channel\037 NOEXPIRE {ON | OFF}"));
}
};
class CSSetNoexpire : public Module
@@ -64,23 +69,12 @@ class CSSetNoexpire : public Module
CommandCSSASetNoexpire commandcssasetnoexpire;
public:
CSSetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssasetnoexpire(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetnoexpire);
}
~CSSetNoexpire()
{
Command *c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetnoexpire);
ModuleManager::RegisterService(&commandcssasetnoexpire);
}
};
+28 -101
View File
@@ -12,117 +12,46 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSet : public Command
{
typedef std::map<Anope::string, Command *, std::less<ci::string> > subcommand_map;
subcommand_map subcommands;
public:
CommandCSSet() : Command("SET", 2, 3)
CommandCSSet(Module *creator) : Command(creator, "chanserv/set", 2, 3)
{
this->SetDesc(_("Set channel options and information"));
this->SetSyntax(_("\037channel\037 \037option\037 \037parameters\037"));
}
~CommandCSSet()
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
this->subcommands.clear();
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
if (readonly)
{
source.Reply(_(CHAN_SET_DISABLED));
return MOD_CONT;
}
if (!check_access(u, cs_findchan(params[0]), CA_SET))
{
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;
}
Command *c = this->FindCommand(params[1]);
if (c)
{
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->Bot(), u, NULL, c, params[1], cmdparams);
}
else
{
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;
this->OnSyntaxError(source, "");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows the channel founder to set various channel options\n"
"and other information.\n"
" \n"
"Available options:"));
Anope::string this_name = source.command;
for (command_map::iterator it = source.owner->commands.begin(), it_end = source.owner->commands.end(); it != it_end; ++it)
{
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(source);
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
if (it->first.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(it->second);
if (command)
{
source.command = it->first;
command->OnServHelp(source);
}
}
}
else
{
Command *c = this->FindCommand(subcommand);
if (c)
return c->OnHelp(source, subcommand);
}
return false;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
bool AddSubcommand(Module *creator, Command *c)
{
c->module = creator;
c->service = this->service;
return this->subcommands.insert(std::make_pair(c->name, c)).second;
}
bool DelSubcommand(Command *c)
{
return this->subcommands.erase(c->name);
}
Command *FindCommand(const Anope::string &subcommand)
{
subcommand_map::const_iterator it = this->subcommands.find(subcommand);
if (it != this->subcommands.end())
return it->second;
return NULL;
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
@@ -131,14 +60,12 @@ class CSSet : public Module
CommandCSSet commandcsset;
public:
CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsset(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
this->AddCommand(chanserv->Bot(), &commandcsset);
ModuleManager::RegisterService(&commandcsset);
}
};
+29 -46
View File
@@ -12,25 +12,38 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetBanType : public Command
{
public:
CommandCSSetBanType(const Anope::string &cpermission = "") : Command("BANTYPE", 2, 2, cpermission)
CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Set how Services make bans on the channel"));
this->SetSyntax(_("\037channel\037 BANTYPE \037bantype\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetBanType");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
try
{
ci->bantype = convertTo<int16>(params[1]);
int16 new_type = convertTo<int16>(params[1]);
if (new_type < 0 || new_type > 3)
throw ConvertException("Invalid range");
ci->bantype = new_type;
source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
}
catch (const ConvertException &)
@@ -38,14 +51,14 @@ class CommandCSSetBanType : public Command
source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
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"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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"
@@ -56,26 +69,14 @@ class CommandCSSetBanType : public Command
"3: ban in the form *!*user@*.domain"), this->name.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
class CommandCSSASetBanType : public CommandCSSetBanType
{
public:
CommandCSSASetBanType() : CommandCSSetBanType("chanserv/saset/bantype")
CommandCSSASetBanType(Module *creator) : CommandCSSetBanType(creator, "chanserv/saset/bantype", "chanserv/saset/bantype")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
class CSSetBanType : public Module
@@ -84,31 +85,13 @@ class CSSetBanType : public Module
CommandCSSASetBanType commandcssasetbantype;
public:
CSSetBanType(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetBanType(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetbantype(this), commandcssasetbantype(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetbantype);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetbantype);
}
~CSSetBanType()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetbantype);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetbantype);
ModuleManager::RegisterService(&commandcssetbantype);
ModuleManager::RegisterService(&commandcssasetbantype);
}
};
+25 -45
View File
@@ -12,57 +12,55 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetDescription : public Command
{
public:
CommandCSSetDescription(const Anope::string &cpermission = "") : Command("DESC", 2, 2, cpermission)
CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Set the channel description"));
this->SetSyntax(_("\037channel\037 DESC \037description\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetDescription");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
ci->desc = params[1];
source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 DESC \037description\037\002\n"
" \n"
"Sets the description for the channel, which shows up with\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("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(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
class CommandCSSASetDescription : public CommandCSSetDescription
{
public:
CommandCSSASetDescription() : CommandCSSetDescription("chanserv/saset/description")
CommandCSSASetDescription(Module *creator) : CommandCSSetDescription(creator, "chanserv/saset/description", "chanserv/saset/description")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
class CSSetDescription : public Module
@@ -71,31 +69,13 @@ class CSSetDescription : public Module
CommandCSSASetDescription commandcssasetdescription;
public:
CSSetDescription(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetDescription(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetdescription(this), commandcssasetdescription(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetdescription);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetdescription);
}
~CSSetDescription()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetdescription);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetdescription);
ModuleManager::RegisterService(&commandcssetdescription);
ModuleManager::RegisterService(&commandcssasetdescription);
}
};
+29 -50
View File
@@ -12,42 +12,51 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetFounder : public Command
{
public:
CommandCSSetFounder(const Anope::string &cpermission = "") : Command("FOUNDER", 2, 2, cpermission)
CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder", const Anope::string &cpermission = "") : Command(creator, "chanserv/founder", 2, 2, cpermission)
{
this->SetDesc(_("Set the founder of a channel"));
this->SetSyntax(_("\037channel\037 FOUNDER \037nick\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetFounder");
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (this->permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
NickAlias *na = findnick(params[1]);
if (!na)
{
source.Reply(_(NICK_X_NOT_REGISTERED), params[1].c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
return;
}
NickCore *nc = na->nc;
if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
return MOD_CONT;
return;
}
Log(!this->permission.empty() ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << "to change the founder to " << nc->display;
@@ -56,37 +65,25 @@ class CommandCSSetFounder : public Command
source.Reply(_("Founder of %s changed to \002%s\002."), ci->name.c_str(), na->nick.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 FOUNDER \037nick\037\002\n"
" \n"
"Changes the founder of a channel. The new nickname must\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the founder of a channel. The new nickname must\n"
"be a registered one."), this->name.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
class CommandCSSASetFounder : public CommandCSSetFounder
{
public:
CommandCSSASetFounder() : CommandCSSetFounder("chanserv/saset/founder")
CommandCSSASetFounder(Module *creator) : CommandCSSetFounder(creator, "chanserv/saset/founder", "chanserv/saset/founder")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
class CSSetFounder : public Module
@@ -95,31 +92,13 @@ class CSSetFounder : public Module
CommandCSSASetFounder commandcssasetfounder;
public:
CSSetFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetfounder(this), commandcssasetfounder(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetfounder);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetfounder);
}
~CSSetFounder()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetfounder);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetfounder);
ModuleManager::RegisterService(&commandcssetfounder);
ModuleManager::RegisterService(&commandcssasetfounder);
}
};
+26 -44
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetKeepTopic : public Command
{
public:
CommandCSSetKeepTopic(const Anope::string &cpermission = "") : Command("KEEPTOPIC", 2, 2, cpermission)
CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Retain topic when channel is not in use"));
this->SetSyntax(_("\037channel\037 KEEPTOPIC {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetKeepTopic");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,38 +51,28 @@ class CommandCSSetKeepTopic : public Command
else
this->OnSyntaxError(source, "KEEPTOPIC");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 KEEPTOPIC {ON | OFF}\002\n"
" \n"
"Enables or disables the \002topic retention\002 option for a \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002topic retention\002 option for a \n"
"channel. When \002topic retention\002 is set, the topic for the\n"
"channel will be remembered by %s even after the\n"
"last user leaves the channel, and will be restored the\n"
"next time the channel is created."), this->name.c_str(), Config->s_ChanServ.c_str());
"next time the channel is created."), this->name.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET KEEPTOPIC", _("SET \037channel\037 KEEPTOPIC {ON | OFF}"));
}
};
class CommandCSSASetKeepTopic : public CommandCSSetKeepTopic
{
public:
CommandCSSASetKeepTopic() : CommandCSSetKeepTopic("chanserv/saset/keeptopic")
CommandCSSASetKeepTopic(Module *creator) : CommandCSSetKeepTopic(creator, "chanserv/saset/keeptopic", "chanserv/saset/keeptopic")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET KEEPTOPIC", _("SASET \002channel\002 KEEPTOPIC {ON | OFF}"));
}
};
class CSSetKeepTopic : public Module
@@ -81,31 +81,13 @@ class CSSetKeepTopic : public Module
CommandCSSASetKeepTopic commandcssasetkeeptopic;
public:
CSSetKeepTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetKeepTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetkeeptopic(this), commandcssasetkeeptopic(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetkeeptopic);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetkeeptopic);
}
~CSSetKeepTopic()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetkeeptopic);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetkeeptopic);
ModuleManager::RegisterService(&commandcssetkeeptopic);
ModuleManager::RegisterService(&commandcssasetkeeptopic);
}
};
+26 -44
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetOpNotice : public Command
{
public:
CommandCSSetOpNotice(const Anope::string &cpermission = "") : Command("OPNOTICE", 2, 2, cpermission)
CommandCSSetOpNotice(Module *creator, const Anope::string &cname = "chanserv/set/notice", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Send a notice when OP/DEOP commands are used"));
this->SetSyntax(_("\037channel\037 OPNOTICE {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetOpNotice");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,37 +51,27 @@ class CommandCSSetOpNotice : public Command
else
this->OnSyntaxError(source, "OPNOTICE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 OPNOTICE {ON | OFF}\002\n"
" \n"
"Enables or disables the \002op-notice\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002op-notice\002 option for a channel.\n"
"When \002op-notice\002 is set, %s will send a notice to the\n"
"channel whenever the \002OP\002 or \002DEOP\002 commands are used for a user\n"
"in the channel."), this->name.c_str(), Config->s_ChanServ.c_str());
"in the channel."), this->name.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET OPNOTICE", _("SET \037channel\037 OPNOTICE {ON | OFF}"));
}
};
class CommandCSSASetOpNotice : public CommandCSSetOpNotice
{
public:
CommandCSSASetOpNotice() : CommandCSSetOpNotice("chanserv/saset/opnotice")
CommandCSSASetOpNotice(Module *creator) : CommandCSSetOpNotice(creator, "chanserv/saset/opnotice", "chanserv/saset/opnotice")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET OPNOTICE", _("SASET \002channel\002 OPNOTICE {ON | OFF}"));
}
};
class CSSetOpNotice : public Module
@@ -80,31 +80,13 @@ class CSSetOpNotice : public Module
CommandCSSASetOpNotice commandcssasetopnotice;
public:
CSSetOpNotice(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetOpNotice(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetopnotice(this), commandcssasetopnotice(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetopnotice);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetopnotice);
}
~CSSetOpNotice()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetopnotice);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetopnotice);
ModuleManager::RegisterService(&commandcssetopnotice);
ModuleManager::RegisterService(&commandcssasetopnotice);
}
};
+26 -44
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetPeace : public Command
{
public:
CommandCSSetPeace(const Anope::string &cpermission = "") : Command("PEACE", 2, 2, cpermission)
CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Regulate the use of critical commands"));
this->SetSyntax(_("\037channel\037 PEACE {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetPeace");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,37 +51,27 @@ class CommandCSSetPeace : public Command
else
this->OnSyntaxError(source, "PEACE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 PEACE {ON | OFF}\002\n"
" \n"
"Enables or disables the \002peace\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002peace\002 option for a channel.\n"
"When \002peace\002 is set, a user won't be able to kick,\n"
"ban or remove a channel status of a user that has\n"
"a level superior or equal to his via %s commands."), this->name.c_str(), Config->s_ChanServ.c_str());
"a level superior or equal to his via %s commands."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET PEACE", _("SET \037channel\037 PEACE {ON | OFF}"));
}
};
class CommandCSSASetPeace : public CommandCSSetPeace
{
public:
CommandCSSASetPeace() : CommandCSSetPeace("chanserv/saset/peace")
CommandCSSASetPeace(Module *creator) : CommandCSSetPeace(creator, "chanserv/saset/peace", "chanserv/saset/peace")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET PEACE", _("SASET \002channel\002 PEACE {ON | OFF}"));
}
};
class CSSetPeace : public Module
@@ -80,31 +80,13 @@ class CSSetPeace : public Module
CommandCSSASetPeace commandcssasetpeace;
public:
CSSetPeace(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetPeace(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetpeace(this), commandcssasetpeace(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetpeace);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetpeace);
}
~CSSetPeace()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetpeace);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetpeace);
ModuleManager::RegisterService(&commandcssetpeace);
ModuleManager::RegisterService(&commandcssasetpeace);
}
};
+45 -48
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetPersist : public Command
{
public:
CommandCSSetPersist(const Anope::string &cpermission = "") : Command("PERSIST", 2, 2, cpermission)
CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Set the channel as permanent"));
this->SetSyntax(_("\037channel\037 PERSIST {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetPersist");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
@@ -52,9 +62,15 @@ class CommandCSSetPersist : public Command
*/
if (!ci->bi && !cm)
{
chanserv->Bot()->Assign(NULL, ci);
if (!ci->c->FindUser(chanserv->Bot()))
chanserv->Bot()->Join(ci->c);
BotInfo *bi = findbot(Config->ChanServ);
if (!bi)
{
source.Reply(_("ChanServ is required to enable persist on this network."));
return;
}
bi->Assign(NULL, ci);
if (!ci->c->FindUser(bi))
bi->Join(ci->c);
}
/* Set the perm mode */
@@ -89,9 +105,17 @@ class CommandCSSetPersist : public Command
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
* which was assigned when persist was set on
*/
if (!cm && Config->s_BotServ.empty() && ci->bi)
if (!cm && Config->BotServ.empty() && ci->bi)
{
BotInfo *bi = findbot(Config->ChanServ);
if (!bi)
{
source.Reply(_("ChanServ is required to enable persist on this network."));
return;
}
/* Unassign bot */
chanserv->Bot()->UnAssign(NULL, ci);
bi->UnAssign(NULL, ci);
}
}
source.Reply(_("Channel \002%s\002 is no longer persistant."), ci->name.c_str());
@@ -99,13 +123,14 @@ class CommandCSSetPersist : public Command
else
this->OnSyntaxError(source, "PERSIST");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 PERSIST {ON | OFF}\002\n"
"Enables or disables the persistant channel setting.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the persistant channel setting.\n"
"When persistant is set, the service bot will remain\n"
"in the channel when it has emptied of users.\n"
" \n"
@@ -123,27 +148,17 @@ class CommandCSSetPersist : public Command
"and is is set or unset (for any reason, including MLOCK),\n"
"persist is automatically set and unset for the channel aswell.\n"
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."), this->name.c_str());
"set persist on or off."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET PERSIST", _("SET \037channel\037 PERSIST {ON | OFF}"));
}
};
class CommandCSSASetPersist : public CommandCSSetPersist
{
public:
CommandCSSASetPersist() : CommandCSSetPersist("chanserv/saset/persist")
CommandCSSASetPersist(Module *creator) : CommandCSSetPersist(creator, "chanserv/saset/persist", "chanserv/saset/persist")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET PERSIST", _("SASET \002channel\002 PERSIST {ON | OFF}"));
}
};
class CSSetPersist : public Module
@@ -152,31 +167,13 @@ class CSSetPersist : public Module
CommandCSSASetPersist commandcssasetpeace;
public:
CSSetPersist(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetPersist(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetpeace(this), commandcssasetpeace(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetpeace);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetpeace);
}
~CSSetPersist()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetpeace);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetpeace);
ModuleManager::RegisterService(&commandcssetpeace);
ModuleManager::RegisterService(&commandcssasetpeace);
}
};
+27 -44
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetPrivate : public Command
{
public:
CommandCSSetPrivate(const Anope::string &cpermission = "") : Command("PRIVATE", 2, 2, cpermission)
CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Hide channel from LIST command"));
this->SetSyntax(_("\037channel\037 PRIVATE {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetPrivate");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,36 +51,27 @@ class CommandCSSetPrivate : public Command
else
this->OnSyntaxError(source, "PRIVATE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 PRIVATE {ON | OFF}\002\n"
" \n"
"Enables or disables the \002private\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002private\002 option for a channel.\n"
"When \002private\002 is set, a \002%s%s LIST\002 will not\n"
"include the channel in any lists."), this->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
"include the channel in any lists."),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET PRIVATE", _("SET \037channel\037 PRIVATE {ON | OFF}"));
}
};
class CommandCSSASetPrivate : public CommandCSSetPrivate
{
public:
CommandCSSASetPrivate() : CommandCSSetPrivate("chanserv/saset/private")
CommandCSSASetPrivate(Module *creator) : CommandCSSetPrivate(creator, "chanserv/saset/private", "chanserv/saset/private")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET PRIVATE", _("SASET \002channel\002 PRIVATE {ON | OFF}"));
}
};
class CSSetPrivate : public Module
@@ -79,31 +80,13 @@ class CSSetPrivate : public Module
CommandCSSASetPrivate commandcssasetprivate;
public:
CSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetprivate(this), commandcssasetprivate(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetprivate);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetprivate);
}
~CSSetPrivate()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetprivate);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetprivate);
ModuleManager::RegisterService(&commandcssetprivate);
ModuleManager::RegisterService(&commandcssasetprivate);
}
};
+26 -44
View File
@@ -11,21 +11,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetRestricted : public Command
{
public:
CommandCSSetRestricted(const Anope::string &cpermission = "") : Command("RESTRICTED", 2, 2, cpermission)
CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Restrict access to the channel"));
this->SetSyntax(_("\037channel\037 RESTRICTED {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetRestricted");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -44,36 +54,26 @@ class CommandCSSetRestricted : public Command
else
this->OnSyntaxError(source, "RESTRICTED");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 RESTRICTED {ON | OFF}\002\n"
" \n"
"Enables or disables the \002restricted access\002 option for a\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002restricted access\002 option for a\n"
"channel. When \002restricted access\002 is set, users not on the access list will\n"
"instead be kicked and banned from the channel."), this->name.c_str());
"instead be kicked and banned from the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET RESTRICTED", _("SET \037channel\037 RESTRICTED {ON | OFF}"));
}
};
class CommandCSSASetRestricted : public CommandCSSetRestricted
{
public:
CommandCSSASetRestricted() : CommandCSSetRestricted("chanserv/saset/restricted")
CommandCSSASetRestricted(Module *creator) : CommandCSSetRestricted(creator, "chanserv/saset/restricted", "chanserv/saset/restricted")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET RESTRICTED", _("SASET \002channel\002 RESTRICTED {ON | OFF}"));
}
};
class CSSetRestricted : public Module
@@ -82,31 +82,13 @@ class CSSetRestricted : public Module
CommandCSSASetRestricted commandcssasetrestricted;
public:
CSSetRestricted(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetRestricted(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetrestricted(this), commandcssasetrestricted(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetrestricted);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetrestricted);
}
~CSSetRestricted()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetrestricted);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetrestricted);
ModuleManager::RegisterService(&commandcssetrestricted);
ModuleManager::RegisterService(&commandcssasetrestricted);
}
};
+29 -47
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetSecure : public Command
{
public:
CommandCSSetSecure(const Anope::string &cpermission = "") : Command("SECURE", 2, 2, cpermission)
CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(Anope::printf(_("Activate %s's security features"), Config->s_ChanServ.c_str()));
this->SetDesc(_("Activate security features"));
this->SetSyntax(_("\037channel\037 SECURE {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetSecure");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,38 +51,28 @@ class CommandCSSetSecure : public Command
else
this->OnSyntaxError(source, "SECURE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 SECURE {ON | OFF}\002\n"
" \n"
"Enables or disables %s's security features for a\n"
"channel. When \002SECURE\002 is set, only users who have\n"
"registered their nicknames with %s and IDENTIFY'd\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables security features for a\n"
"channel. When \002%s\002 is set, only users who have\n"
"registered their nicknames and IDENTIFY'd\n"
"with their password will be given access to the channel\n"
"as controlled by the access list."), this->name.c_str(), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
"as controlled by the access list."), this->name.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET SECURE", _("SET \037channel\037 SECURE {ON | OFF}"));
}
};
class CommandCSSASetSecure : public CommandCSSetSecure
{
public:
CommandCSSASetSecure() : CommandCSSetSecure("chanserv/saset/secure")
CommandCSSASetSecure(Module *creator) : CommandCSSetSecure(creator, "chanserv/saset/secure", "chanserv/saset/secure")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET SECURE", _("SASET \002channel\002 SECURE {ON | OFF}"));
}
};
class CSSetSecure : public Module
@@ -81,31 +81,13 @@ class CSSetSecure : public Module
CommandCSSASetSecure commandcssasetsecure;
public:
CSSetSecure(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetSecure(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetsecure(this), commandcssasetsecure(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecure);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecure);
}
~CSSetSecure()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecure);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecure);
ModuleManager::RegisterService(&commandcssetsecure);
ModuleManager::RegisterService(&commandcssasetsecure);
}
};
+22 -46
View File
@@ -12,27 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetSecureFounder : public Command
{
public:
CommandCSSetSecureFounder(const Anope::string &cpermission = "") : Command("SECUREFOUNDER", 2, 2, cpermission)
CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Stricter control of channel founder status"));
this->SetDesc(_("\037channel\037 SECUREFOUNDER {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetSecureFounder");
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
@@ -48,38 +52,28 @@ class CommandCSSetSecureFounder : public Command
else
this->OnSyntaxError(source, "SECUREFOUNDER");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 SECUREFOUNDER {ON | OFF}\002\n"
" \n"
"Enables or disables the \002secure founder\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002secure founder\002 option for a channel.\n"
"When \002secure founder\002 is set, only the real founder will be\n"
"able to drop the channel, change its password, its founder and its\n"
"successor, and not those who have founder level access through\n"
"the access/qop command."), this->name.c_str());
"the access/qop command."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET SECUREFOUNDER", _("SET \037channel\037 SECUREFOUNDER {ON | OFF}"));
}
};
class CommandCSSASetSecureFounder : public CommandCSSetSecureFounder
{
public:
CommandCSSASetSecureFounder() : CommandCSSetSecureFounder("chanserv/saset/securefounder")
CommandCSSASetSecureFounder(Module *creator) : CommandCSSetSecureFounder(creator, "chanserv/saset/securefounder", "chanserv/saset/securefounder")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET SECUREFOUNDER", _("SASET \002channel\002 SECUREFOUNDER {ON | OFF}"));
}
};
class CSSetSecureFounder : public Module
@@ -88,31 +82,13 @@ class CSSetSecureFounder : public Module
CommandCSSASetSecureFounder commandcssasetsecurefounder;
public:
CSSetSecureFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetSecureFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetsecurefounder(this), commandcssasetsecurefounder(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecurefounder);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecurefounder);
}
~CSSetSecureFounder()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecurefounder);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecurefounder);
ModuleManager::RegisterService(&commandcssetsecurefounder);
ModuleManager::RegisterService(&commandcssasetsecurefounder);
}
};
+26 -44
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetSecureOps : public Command
{
public:
CommandCSSetSecureOps(const Anope::string &cpermission = "") : Command("SECUREOPS", 2, 2, cpermission)
CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Stricter control of chanop status"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetSecureIos");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,36 +51,26 @@ class CommandCSSetSecureOps : public Command
else
this->OnSyntaxError(source, "SECUREOPS");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002SET \037%s\037 SECUREOPS {ON | OFF}\002\n"
" \n"
"Enables or disables the \002secure ops\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002secure ops\002 option for a channel.\n"
"When \002secure ops\002 is set, users who are not on the userlist\n"
"will not be allowed chanop status."), this->name.c_str());
"will not be allowed chanop status."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET SECUREOPS", _("SET \037channel\037 SECUREOPS {ON | OFF}"));
}
};
class CommandCSSASetSecureOps : public CommandCSSetSecureOps
{
public:
CommandCSSASetSecureOps() : CommandCSSetSecureOps("chanserv/saset/secureops")
CommandCSSASetSecureOps(Module *creator) : CommandCSSetSecureOps(creator, "chanserv/saset/secureops", "chanserv/saset/secureops")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET SECUREOPS", _("SASET \002channel\002 SECUREOPS {ON | OFF}"));
}
};
class CSSetSecureOps : public Module
@@ -79,31 +79,13 @@ class CSSetSecureOps : public Module
CommandCSSASetSecureOps commandcssasetsecureops;
public:
CSSetSecureOps(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetSecureOps(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetsecureops(this), commandcssasetsecureops(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecureops);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecureops);
}
~CSSetSecureOps()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecureops);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecureops);
ModuleManager::RegisterService(&commandcssetsecureops);
ModuleManager::RegisterService(&commandcssasetsecureops);
}
};
+26 -47
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetSignKick : public Command
{
public:
CommandCSSetSignKick(const Anope::string &cpermission = "") : Command("SIGNKICK", 2, 2, cpermission)
CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Sign kicks that are done with KICK command"));
this->SetSyntax(_("\037channel\037 SIGNKICK {ON | LEVEL | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetSignKick");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -49,43 +59,30 @@ class CommandCSSetSignKick : public Command
}
else
this->OnSyntaxError(source, "SIGNKICK");
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002SET \037%s\037 SIGNKICK {ON | LEVEL | OFF}\002\n"
" \n"
"Enables or disables signed kicks for a\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables signed kicks for a\n"
"channel. When \002SIGNKICK\002 is set, kicks issued with\n"
"%s KICK command will have the nick that used the\n"
"KICK command will have the nick that used the\n"
"command in their reason.\n"
" \n"
"If you use \002LEVEL\002, those who have a level that is superior \n"
"or equal to the SIGNKICK level on the channel won't have their \n"
"kicks signed. See \002%s%s HELP LEVELS\002 for more information."), this->name.c_str(),
Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
"kicks signed."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET SIGNKICK", _("SET \037channel\037 SIGNKICK {ON | LEVEL | OFF}"));
}
};
class CommandCSSASetSignKick : public CommandCSSetSignKick
{
public:
CommandCSSASetSignKick() : CommandCSSetSignKick("chanserv/saset/signkick")
CommandCSSASetSignKick(Module *creator) : CommandCSSetSignKick(creator, "chanserv/saset/signkick", "chanserv/saset/signkick")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET SIGNKICK", _("SASET \002channel\002 SIGNKICK {ON | OFF}"));
}
};
class CSSetSignKick : public Module
@@ -94,31 +91,13 @@ class CSSetSignKick : public Module
CommandCSSASetSignKick commandcssasetsignkick;
public:
CSSetSignKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetSignKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetsignkick(this), commandcssasetsignkick(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsignkick);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsignkick);
}
~CSSetSignKick()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsignkick);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsignkick);
ModuleManager::RegisterService(&commandcssetsignkick);
ModuleManager::RegisterService(&commandcssasetsignkick);
}
};
+30 -51
View File
@@ -12,27 +12,36 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetSuccessor : public Command
{
public:
CommandCSSetSuccessor(const Anope::string &cpermission = "") : Command("SUCCESSOR", 1, 2, cpermission)
CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor", const Anope::string &cpermission = "") : Command(creator, cname, 1, 2, cpermission)
{
this->SetDesc(_("Set the successor for a channel"));
this->SetSyntax(_("\037channel\037 SUCCESSOR \037nick\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetSuccessor");
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
NickCore *nc;
@@ -43,13 +52,13 @@ class CommandCSSetSuccessor : public Command
if (!na)
{
source.Reply(_(NICK_X_NOT_REGISTERED), params[1].c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
return;
}
if (na->nc == ci->GetFounder())
{
source.Reply(_("%s cannot be the successor on channel %s they are the founder."), na->nick.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
nc = na->nc;
}
@@ -65,42 +74,30 @@ class CommandCSSetSuccessor : public Command
else
source.Reply(_("Successor for \002%s\002 unset."), ci->name.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 SUCCESSOR \037nick\037\002\n"
" \n"
"Changes the successor of a channel. If the founder's\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the successor of a channel. If the founder's\n"
"nickname expires or is dropped while the channel is still\n"
"registered, the successor will become the new founder of the\n"
"channel. However, if the successor already has too many\n"
"channels registered (%d), the channel will be dropped\n"
"instead, just as if no successor had been set. The new\n"
"nickname must be a registered one."), this->name.c_str());
"nickname must be a registered one."), Config->CSMaxReg);
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
class CommandCSSASetSuccessor : public CommandCSSetSuccessor
{
public:
CommandCSSASetSuccessor() : CommandCSSetSuccessor("chanserv/saset/successor")
CommandCSSASetSuccessor(Module *creator) : CommandCSSetSuccessor(creator, "chanserv/saset/successor", "chanserv/saset/successor")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
class CSSetSuccessor : public Module
@@ -109,31 +106,13 @@ class CSSetSuccessor : public Module
CommandCSSASetSuccessor commandcssasetsuccessor;
public:
CSSetSuccessor(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetSuccessor(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetsuccessor(this), commandcssasetsuccessor(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsuccessor);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsuccessor);
}
~CSSetSuccessor()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsuccessor);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsuccessor);
ModuleManager::RegisterService(&commandcssetsuccessor);
ModuleManager::RegisterService(&commandcssasetsuccessor);
}
};
+25 -47
View File
@@ -12,21 +12,31 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSetTopicLock : public Command
{
public:
CommandCSSetTopicLock(const Anope::string &cpermission = "") : Command("TOPICLOCK", 2, 2, cpermission)
CommandCSSetTopicLock(Module *creator, const Anope::string &cname = "chanserv/set/topiclock", const Anope::string &cpermission = "") : Command(creator, cname, 2, 2, cpermission)
{
this->SetDesc(_("Topic can only be changed with TOPIC"));
this->SetSyntax(_("\037channel\037 TOPICLOCK {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetTopicLock");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -41,37 +51,26 @@ class CommandCSSetTopicLock : public Command
else
this->OnSyntaxError(source, "TOPICLOCK");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 TOPICLOCK {ON | OFF}\002\n"
" \n"
"Enables or disables the \002topic lock\002 option for a channel.\n"
"When \002topic lock\002 is set, %s will not allow the\n"
"channel topic to be changed except via the \002TOPIC\002\n"
"command."), this->name.c_str(), Config->s_ChanServ.c_str());
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002topic lock\002 option for a channel.\n"
"When \002topic lock\002 is set, the channel topic will be unchangable\n"
" except via the \002TOPIC\002 command."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET", _("SET \037channel\037 TOPICLOCK {ON | OFF}"));;
}
};
class CommandCSSASetTopicLock : public CommandCSSetTopicLock
{
public:
CommandCSSASetTopicLock() : CommandCSSetTopicLock("chanserv/saset/topiclock")
CommandCSSASetTopicLock(Module *creator) : CommandCSSetTopicLock(creator, "chanserv/saset/topiclock", "chanserv/saset/topiclock")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET", _("SASET \002channel\002 TOPICLOCK {ON | OFF}"));
}
};
class CSSetTopicLock : public Module
@@ -80,31 +79,10 @@ class CSSetTopicLock : public Module
CommandCSSASetTopicLock commandcssasettopiclock;
public:
CSSetTopicLock(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetTopicLock(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssettopiclock(this), commandcssasettopiclock(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssettopiclock);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasettopiclock);
}
~CSSetTopicLock()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssettopiclock);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasettopiclock);
}
};
+27 -46
View File
@@ -11,31 +11,40 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
#define CHECKLEV(lev) (ci->levels[(lev)] != ACCESS_INVALID && access->level >= ci->levels[(lev)])
class CommandCSSetXOP : public Command
{
public:
CommandCSSetXOP(const Anope::string &cpermission = "") : Command("XOP", 2, 2, cpermission)
CommandCSSetXOP(Module *creator, const Anope::string &cname = "chanserv/set/xop", const Anope::string &cpermission = "") : Command(creator, "chanserv/xop", 2, 2, cpermission)
{
this->SetDesc(_("Toggle the user privilege system"));
this->SetSyntax(_("\037channel\037 XOP {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ModuleManager::FindModule("cs_xop"))
{
source.Reply(_("xOP system is not available."), "XOP");
return MOD_CONT;
source.Reply(_("xOP system is not available."));
return;
}
if (!ci)
throw CoreException("NULL ci in CommandCSSetXOP");
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!this->permission.empty() && !check_access(u, ci, CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -81,14 +90,14 @@ class CommandCSSetXOP : public Command
else
this->OnSyntaxError(source, "XOP");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 XOP {ON | OFF}\002\n"
" \n"
"Enables or disables the xOP lists system for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the xOP lists system for a channel.\n"
"When \002XOP\002 is set, you have to use the \002AOP\002/\002SOP\002/\002VOP\002\n"
"commands in order to give channel privileges to\n"
"users, else you have to use the \002ACCESS\002 command.\n"
@@ -105,27 +114,17 @@ class CommandCSSetXOP : public Command
"the \002LEVELS\002 command.\n"
" \n"
"Switching from xOP lists system to access list system\n"
"causes no problem though."), this->name.c_str());
"causes no problem though."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET XOP", _("SET \037channel\037 XOP {ON | OFF}"));
}
};
class CommandCSSASetXOP : public CommandCSSetXOP
{
public:
CommandCSSASetXOP() : CommandCSSetXOP("chanserv/saset/xop")
CommandCSSASetXOP(Module *creator) : CommandCSSetXOP(creator, "chanserv/saset/xop", "chanserv/saset/xop")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET XOP", _("SASET \002channel\002 XOP {ON | OFF}"));
}
};
class CSSetXOP : public Module
@@ -134,31 +133,13 @@ class CSSetXOP : public Module
CommandCSSASetXOP commandcssasetxop;
public:
CSSetXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSetXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetxop(this), commandcssasetxop(this)
{
this->SetAuthor("Anope");
if (!chanserv)
throw ModuleException("ChanServ is not loaded!");
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetxop);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetxop);
}
~CSSetXOP()
{
Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetxop);
c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetxop);
ModuleManager::RegisterService(&commandcssetxop);
ModuleManager::RegisterService(&commandcssasetxop);
}
};
+17 -15
View File
@@ -12,35 +12,41 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSStatus : public Command
{
public:
CommandCSStatus() : Command("STATUS", 2, 2, "chanserv/status")
CommandCSStatus(Module *creator) : Command(creator, "chanserv/status", 2, 2, "chanserv/status")
{
this->SetDesc(_("Returns the current access level of a user on a channel"));
this->SetSyntax(_("\037channel\037 \037item\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
const Anope::string &nick = params[1];
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
User *u2 = finduser(nick);
ChanAccess *u2_access = ci->GetAccess(u2);
if (u2)
source.Reply(_("STATUS %s %s %d"), ci->name.c_str(), u2->nick.c_str(), u2_access ? u2_access->level : 0);
else /* !u2 */
source.Reply(_("STATUS ERROR Nick %s not online"), nick.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002STATUS \037channel\037 \037nickname\037\002\n"
" \n"
"Returns the current access level of the given nick on the\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Returns the current access level of the given nick on the\n"
"given channel. The reply is of the form:\n"
" \n"
" STATUS \037channel\037 \037nickname\037 \037access-level\037\n"
@@ -50,11 +56,6 @@ class CommandCSStatus : public Command
" STATUS ERROR \037error-message\037"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "STATUS", _("STATUS \037channel\037 \037item\037"));
}
};
class CSStatus : public Module
@@ -62,11 +63,12 @@ class CSStatus : public Module
CommandCSStatus commandcsstatus;
public:
CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsstatus(this)
{
this->SetAuthor("Anope");
this->AddCommand(chanserv->Bot(), &commandcsstatus);
ModuleManager::RegisterService(&commandcsstatus);
}
};
+40 -39
View File
@@ -12,49 +12,53 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSSuspend : public Command
{
public:
CommandCSSuspend() : Command("SUSPEND", 1, 2, "chanserv/suspend")
CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 1, 2, "chanserv/suspend")
{
this->SetDesc(_("Prevent a channel from being used preserving channel data and settings"));
this->SetSyntax(_("\037channel\037 [\037reason\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &reason = params.size() > 1 ? params[1] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
/* Assumes that permission checking has already been done. */
if (Config->ForceForbidReason && reason.empty())
{
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
if (readonly)
source.Reply(_(READ_ONLY_MODE));
source.Reply(READ_ONLY_MODE);
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
ci->SetFlag(CI_SUSPENDED);
ci->Extend("suspend_by", new ExtensibleItemRegular<Anope::string>(u->nick));
if (!reason.empty())
ci->Extend("suspend_reason", new ExtensibleItemRegular<Anope::string>(u->nick));
if (c)
if (ci->c)
{
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; )
{
UserContainer *uc = *it++;
if (uc->user->HasMode(UMODE_OPER))
continue;
c->Kick(NULL, uc->user, "%s", !reason.empty() ? reason.c_str() : translate(uc->user, _("This channel has been suspended.")));
ci->c->Kick(NULL, uc->user, "%s", !reason.empty() ? reason.c_str() : translate(uc->user, _("This channel has been suspended.")));
}
}
@@ -63,49 +67,50 @@ class CommandCSSuspend : public Command
FOREACH_MOD(I_OnChanSuspend, OnChanSuspend(ci));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002SUSPEND \037channel\037 [\037reason\037]\002\n"
" \n"
"Disallows anyone from registering or using the given\n"
"channel. May be cancelled by using the UNSUSPEND\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Disallows anyone from using the given channel.\n"
"May be cancelled by using the UNSUSPEND\n"
"command to preserve all previous channel data/settings.\n"
" \n"
"Reason may be required on certain networks."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SUSPEND", Config->ForceForbidReason ? _("SUSPEND \037channel\037 \037reason\037") : _("SUSPEND \037channel\037 \037freason\037"));
}
};
class CommandCSUnSuspend : public Command
{
public:
CommandCSUnSuspend() : Command("UNSUSPEND", 1, 1, "chanserv/suspend")
CommandCSUnSuspend(Module *creator) : Command(creator, "chanserv/unsuspend", 1, 1, "chanserv/suspend")
{
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetDesc(_("Releases a suspended channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
source.Reply(_(READ_ONLY_MODE));
source.Reply(READ_ONLY_MODE);
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
/* Only UNSUSPEND already suspended channels */
if (!ci->HasFlag(CI_SUSPENDED))
{
source.Reply(_("Couldn't release channel \002%s\002!"), ci->name.c_str());
return MOD_CONT;
return;
}
Anope::string by, reason;
@@ -121,22 +126,17 @@ class CommandCSUnSuspend : public Command
FOREACH_MOD(I_OnChanUnsuspend, OnChanUnsuspend(ci));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002UNSUSPEND \037channel\037\002\n"
" \n"
"Releases a suspended channel. All data and settings\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Releases a suspended channel. All data and settings\n"
"are preserved from before the suspension."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "UNSUSPEND", _("UNSUSPEND \037channel\037"));
}
};
class CSSuspend : public Module
@@ -145,12 +145,13 @@ class CSSuspend : public Module
CommandCSUnSuspend commandcsunsuspend;
public:
CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssuspend(this), commandcsunsuspend(this)
{
this->SetAuthor("Anope");
this->AddCommand(chanserv->Bot(), &commandcssuspend);
this->AddCommand(chanserv->Bot(), &commandcsunsuspend);
ModuleManager::RegisterService(&commandcssuspend);
ModuleManager::RegisterService(&commandcsunsuspend);
}
};
+24 -25
View File
@@ -12,61 +12,59 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSTopic : public Command
{
public:
CommandCSTopic() : Command("TOPIC", 1, 2)
CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 1, 2)
{
this->SetDesc(_("Manipulate the topic of the specified channel"));
this->SetSyntax(_("\037channel\037 [\037topic\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &topic = params.size() > 1 ? params[1] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
else if (!check_access(u, ci, CA_TOPIC) && !u->HasCommand("chanserv/topic"))
source.Reply(_(ACCESS_DENIED));
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->c)
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
else if (!check_access(u, ci, CA_TOPIC) && !u->HasCommand("chanserv/chanserv/topic"))
source.Reply(ACCESS_DENIED);
else
{
bool has_topiclock = ci->HasFlag(CI_TOPICLOCK);
ci->UnsetFlag(CI_TOPICLOCK);
c->ChangeTopic(u->nick, topic, Anope::CurTime);
ci->c->ChangeTopic(u->nick, topic, Anope::CurTime);
if (has_topiclock)
ci->SetFlag(CI_TOPICLOCK);
bool override = !check_access(u, ci, CA_TOPIC);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to change the topic to " << (!topic.empty() ? topic : "No topic");
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002TOPIC \037channel\037 [\037topic\037]\002\n"
" \n"
"Causes %s to set the channel topic to the one\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Causes %s to set the channel topic to the one\n"
"specified. If \002topic\002 is not given, then an empty topic\n"
"is set. This command is most useful in conjunction\n"
"with \002SET TOPICLOCK\002. See \002%s%s HELP SET TOPICLOCK\002\n"
"for more information.\n"
" \n"
"with topic lock.\n"
"By default, limited to those with founder access on the\n"
"channel."), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
"channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "TOPIC", _("TOPIC \037channel\037 [\037topic\037]"));
}
};
class CSTopic : public Module
@@ -74,11 +72,12 @@ class CSTopic : public Module
CommandCSTopic commandcstopic;
public:
CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcstopic(this)
{
this->SetAuthor("Anope");
this->AddCommand(chanserv->Bot(), &commandcstopic);
ModuleManager::RegisterService(&commandcstopic);
}
};
+27 -26
View File
@@ -12,32 +12,37 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
class CommandCSUnban : public Command
{
public:
CommandCSUnban() : Command("UNBAN", 1, 2)
CommandCSUnban(Module *creator) : Command(creator, "chanserv/unban", 1, 2)
{
this->SetDesc(_("Remove all bans preventing a user from entering a channel"));
this->SetSyntax(_("\037channel\037 [\037nick\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
if (!c)
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (ci->c == NULL)
{
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
return;
}
if (!check_access(u, ci, CA_UNBAN))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
User *u2 = u;
@@ -46,35 +51,30 @@ class CommandCSUnban : public Command
if (!u2)
{
source.Reply(_(NICK_X_NOT_IN_USE), params[1].c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
return;
}
common_unban(ci, u2, u == u2);
if (u2 == u)
source.Reply(_("You have been unbanned from \002%s\002."), c->name.c_str());
source.Reply(_("You have been unbanned from \002%s\002."), ci->c->name.c_str());
else
source.Reply(_("\002%s\002 has been unbanned from \002%s\002."), u2->nick.c_str(), c->name.c_str());
source.Reply(_("\002%s\002 has been unbanned from \002%s\002."), u2->nick.c_str(), ci->c->name.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002UNBAN \037channel\037 [\037nick\037]\002\n"
" \n"
"Tells %s to remove all bans preventing you or the given\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Tells %s to remove all bans preventing you or the given\n"
"user from entering the given channel. \n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."), Config->s_ChanServ.c_str());
"on the channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "UNBAN", _("UNBAN \037channel\037 [\037nick\037]"));
}
};
class CSUnban : public Module
@@ -82,11 +82,12 @@ class CSUnban : public Module
CommandCSUnban commandcsunban;
public:
CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsunban(this)
{
this->SetAuthor("Anope");
this->AddCommand(chanserv->Bot(), &commandcsunban);
ModuleManager::RegisterService(&commandcsunban);
}
};
+108 -162
View File
@@ -12,7 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "chanserv.h"
enum
{
@@ -27,20 +26,21 @@ enum
class XOPListCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
int level;
Command *c;
bool SentHeader;
public:
XOPListCallback(CommandSource &_source, const Anope::string &numlist, int _level, Command *_c) : NumberList(numlist, false), source(_source), level(_level), c(_c), SentHeader(false)
XOPListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist, int _level, Command *_c) : NumberList(numlist, false), source(_source), ci(_ci), level(_level), c(_c), SentHeader(false)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAccessCount())
if (!Number || Number > ci->GetAccessCount())
return;
ChanAccess *access = source.ci->GetAccess(Number - 1);
ChanAccess *access = ci->GetAccess(Number - 1);
if (level != access->level)
return;
@@ -48,7 +48,7 @@ class XOPListCallback : public NumberList
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("%s list for %s:\n Num Nick"), this->c->name.c_str(), source.ci->name.c_str());
source.Reply(_("%s list for %s:\n Num Nick"), this->c->name.c_str(), ci->name.c_str());
}
DoList(source, access, Number - 1, level);
@@ -63,36 +63,37 @@ class XOPListCallback : public NumberList
class XOPDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool override;
public:
XOPDelCallback(CommandSource &_source, Command *_c, bool _override, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), override(_override)
XOPDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, bool _override, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), override(_override)
{
}
~XOPDelCallback()
{
if (!Deleted)
source.Reply(_("No matching entries on %s %s list."), source.ci->name.c_str(), this->c->name.c_str());
source.Reply(_("No matching entries on %s %s list."), ci->name.c_str(), this->c->name.c_str());
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "deleted access of users " << Nicks;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "deleted access of users " << Nicks;
if (Deleted == 1)
source.Reply(_("Deleted one entry from %s %s list."), source.ci->name.c_str(), this->c->name.c_str());
source.Reply(_("Deleted one entry from %s %s list."), ci->name.c_str(), this->c->name.c_str());
else
source.Reply(_("Deleted %d entries from %s %s list."), Deleted, source.ci->name.c_str(), this->c->name.c_str());
source.Reply(_("Deleted %d entries from %s %s list."), Deleted, ci->name.c_str(), this->c->name.c_str());
}
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAccessCount())
if (!Number || Number > ci->GetAccessCount())
return;
ChanAccess *access = source.ci->GetAccess(Number - 1);
ChanAccess *access = ci->GetAccess(Number - 1);
++Deleted;
if (!Nicks.empty())
@@ -100,19 +101,18 @@ class XOPDelCallback : public NumberList
else
Nicks = access->GetMask();
FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access));
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, source.u, access));
source.ci->EraseAccess(Number - 1);
ci->EraseAccess(Number - 1);
}
};
class XOPBase : public Command
{
private:
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params, int level)
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, int level)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string mask = params.size() > 2 ? params[2] : "";
int change = 0;
@@ -120,13 +120,13 @@ class XOPBase : public Command
if (mask.empty())
{
this->OnSyntaxError(source, "ADD");
return MOD_CONT;
return;
}
if (readonly)
{
source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), this->name.c_str());
return MOD_CONT;
return;
}
ChanAccess *access = ci->GetAccess(u);
@@ -134,8 +134,8 @@ class XOPBase : public Command
if ((level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
NickAlias *na = findnick(mask);
@@ -150,8 +150,8 @@ class XOPBase : public Command
**/
if (access->level >= ulev && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
++change;
}
@@ -159,7 +159,7 @@ class XOPBase : public Command
if (!change && ci->GetAccessCount() >= Config->CSAccessMax)
{
source.Reply(_("Sorry, you can only have %d %s entries on a channel."), Config->CSAccessMax, this->name.c_str());
return MOD_CONT;
return;
}
if (!change)
@@ -185,32 +185,31 @@ class XOPBase : public Command
source.Reply(_("\002%s\002 moved to %s %s list."), access->GetMask().c_str(), ci->name.c_str(), this->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params, int level)
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, int level)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
if (mask.empty())
{
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
return;
}
if (readonly)
{
source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), this->name.c_str());
return MOD_CONT;
return;
}
if (!ci->GetAccessCount())
{
source.Reply(_("%s %s list is empty."), ci->name.c_str(), this->name.c_str());
return MOD_CONT;
return;
}
ChanAccess *access = ci->GetAccess(u);
@@ -218,8 +217,8 @@ class XOPBase : public Command
if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
access = ci->GetAccess(mask, 0, false);
@@ -228,18 +227,18 @@ class XOPBase : public Command
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
bool override = level >= ulev || ulev < ACCESS_AOP;
XOPDelCallback list(source, this, override, mask);
XOPDelCallback list(source, ci, this, override, mask);
list.Process();
}
else if (!access || access->level != level)
{
source.Reply(_("\002%s\002 not found on %s %s list."), mask.c_str(), ci->name.c_str(), this->name.c_str());
return MOD_CONT;
return;
}
else
{
if (access->nc != u->Account() && ulev <= access->level && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else
{
bool override = ulev <= access->level;
@@ -253,23 +252,22 @@ class XOPBase : public Command
}
}
return MOD_CONT;
return;
}
CommandReturn DoList(CommandSource &source, const std::vector<Anope::string> &params, int level)
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, int level)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &nick = params.size() > 2 ? params[2] : "";
ChanAccess *access = ci->GetAccess(u);
uint16 ulev = access ? access->level : 0;
if (!ulev && !u->HasCommand("chanserv/access/list"))
if (!ulev && !u->HasCommand("chanserv/chanserv/access/list"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
bool override = !ulev;
@@ -278,12 +276,12 @@ class XOPBase : public Command
if (!ci->GetAccessCount())
{
source.Reply(_("%s %s list is empty."), ci->name.c_str(), this->name.c_str());
return MOD_CONT;
return;
}
if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
XOPListCallback list(source, nick, level, this);
XOPListCallback list(source, ci, nick, level, this);
list.Process();
}
else
@@ -312,30 +310,29 @@ class XOPBase : public Command
source.Reply(_("No matching entries on %s %s list."), ci->name.c_str(), this->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoClear(CommandSource &source, int level)
void DoClear(CommandSource &source, ChannelInfo *ci, int level)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), this->name.c_str());
return MOD_CONT;
return;
}
if (!ci->GetAccessCount())
{
source.Reply(_("%s %s list is empty."), ci->name.c_str(), this->name.c_str());
return MOD_CONT;
return;
}
if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
bool override = !check_access(u, ci, CA_FOUNDER);
@@ -352,69 +349,72 @@ class XOPBase : public Command
source.Reply(_("Channel %s %s list has been cleared."), ci->name.c_str(), this->name.c_str());
return MOD_CONT;
return;
}
protected:
CommandReturn DoXop(CommandSource &source, const std::vector<Anope::string> &params, int level)
void DoXop(CommandSource &source, const std::vector<Anope::string> &params, int level)
{
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
const Anope::string &cmd = params[1];
if (!ci->HasFlag(CI_XOP))
source.Reply(_("You can't use this command. Use the ACCESS command instead.\n"
"Type \002%s%s HELP ACCESS\002 for more information."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
source.Reply(_("You can't use this command. Use the ACCESS command instead."));
else if (cmd.equals_ci("ADD"))
return this->DoAdd(source, params, level);
return this->DoAdd(source, ci, params, level);
else if (cmd.equals_ci("DEL"))
return this->DoDel(source, params, level);
return this->DoDel(source, ci, params, level);
else if (cmd.equals_ci("LIST"))
return this->DoList(source, params, level);
return this->DoList(source, ci, params, level);
else if (cmd.equals_ci("CLEAR"))
return this->DoClear(source, level);
return this->DoClear(source, ci, level);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
public:
XOPBase(const Anope::string &command) : Command(command, 2, 4)
XOPBase(Module *modname, const Anope::string &command) : Command(modname, command, 2, 4)
{
this->SetSyntax("\037channel\037 ADD \037mask\037");
this->SetSyntax("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}");
this->SetSyntax("\037channel\037 LIST [\037mask\037 | \037list\037]");
this->SetSyntax("\037channel\037 CLEAR");
}
virtual ~XOPBase()
{
}
virtual CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0;
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) = 0;
};
class CommandCSQOP : public XOPBase
{
public:
CommandCSQOP() : XOPBase("QOP")
CommandCSQOP(Module *creator) : XOPBase(creator, "chanserv/qop")
{
this->SetDesc(_("Modify the list of QOP users"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
return this->DoXop(source, params, ACCESS_QOP);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002QOP \037channel\037 ADD \037mask\037\002\n"
" \002QOP \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002QOP \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002QOP \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002QOP\002 (AutoOwner) \002list\002 for a channel. The QOP \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002QOP\002 (AutoOwner) \002list\002 for a channel. The QOP \n"
"list gives users the right to be auto-owner on your channel,\n"
"which gives them almost (or potentially, total) access.\n"
" \n"
@@ -445,38 +445,30 @@ class CommandCSQOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "QOP", _("QOP \037channel\037 {ADD|DEL|LIST|CLEAR} [\037nick\037 | \037entry-list\037]"));
}
};
class CommandCSAOP : public XOPBase
{
public:
CommandCSAOP() : XOPBase("AOP")
CommandCSAOP(Module *creator) : XOPBase(creator, "chanserv/aop")
{
this->SetDesc(_("Modify the list of AOP users"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
return this->DoXop(source, params, ACCESS_AOP);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002AOP \037channel\037 ADD \037mask\037\002\n"
" \002AOP \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002AOP \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002AOP \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002AOP\002 (AutoOP) \002list\002 for a channel. The AOP \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002AOP\002 (AutoOP) \002list\002 for a channel. The AOP \n"
"list gives users the right to be auto-opped on your channel,\n"
"to unban or invite themselves if needed, to have their\n"
"greet message showed on join, and so on.\n"
@@ -509,38 +501,30 @@ class CommandCSAOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "AOP", _("AOP \037channel\037 {ADD|DEL|LIST|CLEAR} [\037nick\037 | \037entry-list\037]"));
}
};
class CommandCSHOP : public XOPBase
{
public:
CommandCSHOP() : XOPBase("HOP")
CommandCSHOP(Module *creator) : XOPBase(creator, "chanserv/hop")
{
this->SetDesc(_("Maintains the HOP (HalfOP) list for a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
return this->DoXop(source, params, ACCESS_HOP);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002HOP \037channel\037 ADD \037mask\037\002\n"
" \002HOP \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002HOP \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002HOP \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002HOP\002 (HalfOP) \002list\002 for a channel. The HOP \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002HOP\002 (HalfOP) \002list\002 for a channel. The HOP \n"
"list gives users the right to be auto-halfopped on your \n"
"channel.\n"
" \n"
@@ -571,38 +555,30 @@ class CommandCSHOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "HOP", _("HOP \037channel\037 {ADD|DEL|LIST|CLEAR} [\037nick\037 | \037entry-list\037]"));
}
};
class CommandCSSOP : public XOPBase
{
public:
CommandCSSOP() : XOPBase("SOP")
CommandCSSOP(Module *creator) : XOPBase(creator, "chanserv/sop")
{
this->SetDesc(_("Modify the list of SOP users"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
return this->DoXop(source, params, ACCESS_SOP);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002SOP \037channel\037 ADD \037mask\037\002\n"
" \002SOP \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002SOP \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002SOP \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002SOP\002 (SuperOP) \002list\002 for a channel. The SOP \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002SOP\002 (SuperOP) \002list\002 for a channel. The SOP \n"
"list gives users all rights given by the AOP list, and adds\n"
"those needed to use the AutoKick and the BadWords lists, \n"
"to send and read channel memos, and so on.\n"
@@ -635,38 +611,30 @@ class CommandCSSOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SOP", _("SOP \037channel\037 {ADD|DEL|LIST|CLEAR} [\037nick\037 | \037entry-list\037]"));
}
};
class CommandCSVOP : public XOPBase
{
public:
CommandCSVOP() : XOPBase("VOP")
CommandCSVOP(Module *creator) : XOPBase(creator, "chanserv/vop")
{
this->SetDesc(_("Maintains the VOP (VOicePeople) list for a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
return this->DoXop(source, params, ACCESS_VOP);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002VOP \037channel\037 ADD \037mask\037\002\n"
" \002VOP \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002VOP \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002VOP \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002VOP\002 (VOicePeople) \002list\002 for a channel. \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002VOP\002 (VOicePeople) \002list\002 for a channel. \n"
"The VOP list allows users to be auto-voiced and to voice \n"
"themselves if they aren't.\n"
" \n"
@@ -698,15 +666,10 @@ class CommandCSVOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "VOP", _("VOP \037channel\037 {ADD|DEL|LIST|CLEAR} [\037nick\037 | \037entry-list\037]"));
}
};
class CSXOP : public Module
@@ -718,33 +681,16 @@ class CSXOP : public Module
CommandCSVOP commandcsvop;
public:
CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsqop(this), commandcssop(this), commandcsaop(this), commandcshop(this), commandcsvop(this)
{
this->SetAuthor("Anope");
this->AddCommand(chanserv->Bot(), &commandcssop);
this->AddCommand(chanserv->Bot(), &commandcsaop);
this->AddCommand(chanserv->Bot(), &commandcsvop);
if (Me && Me->IsSynced())
OnUplinkSync(NULL);
Implementation i[] = {I_OnUplinkSync, I_OnServerDisconnect};
ModuleManager::Attach(i, this, 2);
}
void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
this->AddCommand(chanserv->Bot(), &commandcsqop);
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
this->AddCommand(chanserv->Bot(), &commandcshop);
}
void OnServerDisconnect()
{
this->DelCommand(chanserv->Bot(), &commandcsqop);
this->DelCommand(chanserv->Bot(), &commandcshop);
ModuleManager::RegisterService(&commandcssop);
ModuleManager::RegisterService(&commandcsaop);
ModuleManager::RegisterService(&commandcsqop);
ModuleManager::RegisterService(&commandcsvop);
ModuleManager::RegisterService(&commandcshop);
}
};
+206 -279
View File
@@ -1,5 +1,4 @@
#include "module.h"
#include "operserv.h"
#include "../extra/sql.h"
#include "os_session.h"
@@ -53,18 +52,19 @@ static void WriteBotMetadata(const Anope::string &key, const Anope::string &data
class CommandSQLSync : public Command
{
public:
CommandSQLSync() : Command("SQLSYNC", 0, 0, "operserv/sqlsync")
CommandSQLSync(Module *creator) : Command(creator, "SQLSYNC", 0, 0, "operserv/sqlsync")
{
this->SetDesc(_("Import your databases to SQL"));
this->SetSyntax("");
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params);
void Execute(CommandSource &source, const std::vector<Anope::string> &params);
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002SQLSYNC\002\n"
" \n"
"This command syncs your databases with SQL. You should\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("This command syncs your databases with SQL. You should\n"
"only have to execute this command once, when you initially\n"
"import your databases into SQL."));
return true;
@@ -102,8 +102,9 @@ class DBMySQL : public Module
if (readonly && this->ro)
{
readonly = this->ro = false;
if (operserv)
ircdproto->SendGlobops(operserv->Bot(), "Found SQL again, going out of readonly mode...");
BotInfo *bi = findbot(Config->OperServ);
if (bi)
ircdproto->SendGlobops(bi, "Found SQL again, going out of readonly mode...");
}
SQL->Run(&sqlinterface, query);
@@ -112,19 +113,19 @@ class DBMySQL : public Module
{
if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
{
if (operserv)
ircdproto->SendGlobops(operserv->Bot(), "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
BotInfo *bi = findbot(Config->OperServ);
if (bi)
ircdproto->SendGlobops(bi, "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
readonly = this->ro = true;
this->lastwarn = Anope::CurTime;
}
}
}
DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sqlinterface(this), SQL("mysql/main"), SessionInterface("session")
DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), commandsqlsync(this), sqlinterface(this), SQL("mysql/main"), SessionInterface("session")
{
me = this;
this->lastwarn = 0;
this->ro = false;
@@ -133,8 +134,7 @@ class DBMySQL : public Module
};
ModuleManager::Attach(i, this, 2);
if (operserv)
this->AddCommand(operserv->Bot(), &commandsqlsync);
ModuleManager::RegisterService(&commandsqlsync);
if (CurrentUplink)
OnServerConnect();
@@ -161,12 +161,12 @@ class DBMySQL : public Module
/* MemoServ */
I_OnMemoSend, I_OnMemoDel,
/* OperServ */
I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
I_OnExceptionAdd, I_OnExceptionDel,
I_OnAddXLine, I_OnDelXLine,
/* HostServ */
I_OnSetVhost, I_OnDeleteVhost
};
ModuleManager::Attach(i, this, 42);
ModuleManager::Attach(i, this, 41);
}
EventReturn OnLoadDatabase()
@@ -546,46 +546,28 @@ class DBMySQL : public Module
}
}
if (SQLine)
for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
{
query = "SELECT * FROM `anope_os_akills`";
XLineManager *xm = *it;
query = "SELECT * FROM `anope_os_xlines` WHERE `type` = @type";
query.setValue("type", Anope::string(xm->Type()));
r = SQL->RunQuery(query);
for (int i = 0; i < r.Rows(); ++i)
{
Anope::string user = r.Get(i, "user");
Anope::string host = r.Get(i, "host");
Anope::string by = r.Get(i, "by");
Anope::string by = r.Get(i, "xby");
Anope::string reason = r.Get(i, "reason");
time_t seton = r.Get(i, "seton").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "seton")) : Anope::CurTime;
time_t expires = r.Get(i, "expires").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "expires")) : Anope::CurTime;
XLine *x = SGLine->Add(user + "@" + host, by, expires, reason);
XLine *x = xm->Add(user + "@" + host, by, expires, reason);
if (x)
x->Created = seton;
}
}
query = "SELECT * FROM `anope_os_xlines`";
r = SQL->RunQuery(query);
for (int i = 0; i < r.Rows(); ++i)
{
Anope::string mask = r.Get(i, "mask");
Anope::string by = r.Get(i, "xby");
Anope::string reason = r.Get(i, "reason");
time_t seton = r.Get(i, "seton").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "seton")) : Anope::CurTime;
time_t expires = r.Get(i, "expire").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "expire")) : Anope::CurTime;
XLine *x = NULL;
if (SNLine && r.Get(i, "type").equals_cs("SNLINE"))
x = SNLine->Add(mask, by, expires, reason);
else if (SQLine && r.Get(i, "type").equals_cs("SQLINE"))
x = SQLine->Add(mask, by, expires, reason);
else if (SZLine && r.Get(i, "type").equals_cs("SZLINE"))
x = SZLine->Add(mask, by, expires, reason);
if (x)
x->Created = seton;
}
query = "SELECT * FROM `anope_os_exceptions`";
r = SQL->RunQuery(query);
for (int i = 0; i < r.Rows(); ++i)
@@ -652,10 +634,6 @@ class DBMySQL : public Module
query = "INSERT INTO `anope_os_core` (maxusercnt, maxusertime, akills_count, snlines_count, sqlines_count, szlines_count) VALUES(@maxusercnt, @maxusertime, @akills_count, @snlines_count, @sqlines_count, @szlines_count)";
query.setValue("maxusercnt", maxusercnt);
query.setValue("maxusertime", maxusertime);
query.setValue("akills_count", SGLine ? SGLine->GetCount() : 0);
query.setValue("snlines_count", SQLine ? SQLine->GetCount() : 0);
query.setValue("sqlines_count", SNLine ? SNLine->GetCount() : 0);
query.setValue("szlines_count", SZLine ? SZLine->GetCount() : 0);
this->RunQuery(query);
for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
@@ -678,10 +656,12 @@ class DBMySQL : public Module
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
{
if (it->second->HasFlag(BI_CONF))
continue;
CurBot = it->second;
FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteBotMetadata, CurBot));
/* This is for the core bots, bots added by users are already handled by an event */
query = "INSERT INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES(@nick, @user, @host, @rname, @flags, @created, @chancount) ON DUPLICATE KEY UPDATE nick=VALUES(nick), user=VALUES(user), host=VALUES(host), rname=VALUES(rname), flags=VALUES(flags), created=VALUES(created), chancount=VALUES(chancount)";
query.setValue("nick", CurBot->nick);
query.setValue("user", CurBot->GetIdent());
@@ -703,215 +683,202 @@ class DBMySQL : public Module
void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
User *u = source.u;
BotInfo *service = command->service;
ChannelInfo *ci = source.ci;
if (service->nick == Config->s_NickServ)
if (command->name.find("nickserv/set/") == 0 || command->name.find("nickserv/saset/") == 0)
{
if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->HasCommand("nickserv/saset") && params.size() > 1)))
NickAlias *na = findnick(command->name.find("nickserv/set/") == 0 ? source.u->nick : params[1]);
if (!na)
return;
if (command->name == "nickserv/set/password" || command->name == "nickserv/saset/password")
{
Anope::string cmd = (command->name.equals_ci("SET") ? params[0] : params[1]);
NickCore *nc = (command->name.equals_ci("SET") ? u->Account() : findcore(params[0]));
if (!nc)
return;
if (cmd.equals_ci("PASSWORD") && params.size() > 1)
{
SQLQuery query("UPDATE `anope_ns_core` SET `pass` = @pass WHERE `display` = @display");
query.setValue("pass", nc->pass);
query.setValue("display", nc->display);
this->RunQuery(query);
}
else if (cmd.equals_ci("LANGUAGE") && params.size() > 1)
{
SQLQuery query("UPDATE `anope_ns_core` SET `language` = @language WHERE `display` = @display");
query.setValue("language", nc->language);
query.setValue("display", nc->display);
this->RunQuery(query);
}
else if (cmd.equals_ci("EMAIL"))
{
SQLQuery query("UPDATE `anope_ns_core` SET `email` = @email WHERE `display` = @display");
query.setValue("email", nc->email);
query.setValue("display", nc->display);
this->RunQuery(query);
}
else if (cmd.equals_ci("GREET"))
{
SQLQuery query("UPDATE `anope_ns_core` SET `greet` = @greet WHERE `display` = @display");
query.setValue("greet", nc->greet);
query.setValue("display", nc->display);
this->RunQuery(query);
}
else if (cmd.equals_ci("KILL") || cmd.equals_ci("SECURE") || cmd.equals_ci("PRIVATE") || cmd.equals_ci("MSG") || cmd.equals_ci("HIDE") || cmd.equals_ci("AUTOOP"))
{
SQLQuery query("UPDATE `anope_ns_core` SET `flags` = @flags WHERE `display` = @display");
query.setValue("flags", ToString(nc->ToString()));
query.setValue("display", nc->display);
this->RunQuery(query);
}
SQLQuery query("UPDATE `anope_ns_core` SET `pass` = @pass WHERE `display` = @display");
query.setValue("pass", na->nc->pass);
query.setValue("display", na->nc->display);
this->RunQuery(query);
}
else if (command->name == "nickserv/set/language" || command->name == "nickserv/saset/language")
{
SQLQuery query("UPDATE `anope_ns_core` SET `language` = @language WHERE `display` = @display");
query.setValue("language", na->nc->language);
query.setValue("display", na->nc->display);
this->RunQuery(query);
}
else if (command->name == "nickserv/set/email" || command->name == "nickserv/saset/email")
{
SQLQuery query("UPDATE `anope_ns_core` SET `email` = @email WHERE `display` = @display");
query.setValue("email", na->nc->email);
query.setValue("display", na->nc->display);
this->RunQuery(query);
}
else if (command->name == "nickserv/set/greet" || command->name == "nickserv/saset/greet")
{
SQLQuery query("UPDATE `anope_ns_core` SET `greet` = @greet WHERE `display` = @display");
query.setValue("greet", na->nc->greet);
query.setValue("display", na->nc->display);
this->RunQuery(query);
}
else
{
SQLQuery query("UPDATE `anope_ns_core` SET `flags` = @flags WHERE `display` = @display");
query.setValue("flags", ToString(na->nc->ToString()));
query.setValue("display", na->nc->display);
this->RunQuery(query);
}
}
else if (service->nick == Config->s_ChanServ)
else if (command->name.find("chanserv/set") == 0 || command->name.find("chanserv/saset") == 0)
{
if (command->name.equals_ci("SET") && u->Account() && params.size() > 1)
ChannelInfo *ci = params.size() > 0 ? cs_findchan(params[0]) : NULL;
if (!ci)
return;
if (command->name == "chanserv/set/founder" || command->name == "chanserv/saset/founder")
{
if (!ci)
return;
if (!u->HasPriv("chanserv/set") && check_access(u, ci, CA_SET))
return;
if (params[1].equals_ci("FOUNDER"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `founder` = @founder WHERE `name` = @name");
query.setValue("founder", ci->GetFounder() ? ci->GetFounder()->display : "");
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("SUCCESSOR"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `successor` = @successor WHERE `name` = @name");
query.setValue("successor", ci->successor ? ci->successor->display : "");
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("DESC"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `descr` = @descr WHERE `name` = @name");
query.setValue("descr", ci->desc);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("BANTYPE"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `bantype` = @bantype WHERE `name` = @name");
query.setValue("bantype", ci->bantype);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("KEEPTOPIC") || params[1].equals_ci("TOPICLOCK") || params[1].equals_ci("PRIVATE") || params[1].equals_ci("SECUREOPS") || params[1].equals_ci("SECUREFOUNDER") || params[1].equals_ci("RESTRICTED") || params[1].equals_ci("SECURE") || params[1].equals_ci("SIGNKICK") || params[1].equals_ci("OPNOTICE") || params[1].equals_ci("XOP") || params[1].equals_ci("PEACE") || params[1].equals_ci("PERSIST") || params[1].equals_ci("NOEXPIRE"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `flags` = @flags WHERE `name` = @name");
query.setValue("flags", ToString(ci->ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
SQLQuery query("UPDATE `anope_cs_info` SET `founder` = @founder WHERE `name` = @name");
query.setValue("founder", ci->GetFounder() ? ci->GetFounder()->display : "");
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (command->name == "chanserv/set/successor" || command->name == "chanserv/saset/successor")
{
SQLQuery query("UPDATE `anope_cs_info` SET `successor` = @successor WHERE `name` = @name");
query.setValue("successor", ci->successor ? ci->successor->display : "");
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (command->name == "chanserv/set/desc" || command->name == "chanserv/saset/desc")
{
SQLQuery query("UPDATE `anope_cs_info` SET `descr` = @descr WHERE `name` = @name");
query.setValue("descr", ci->desc);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (command->name == "chanserv/set/bantype" || command->name == "chanserv/saset/bantype")
{
SQLQuery query("UPDATE `anope_cs_info` SET `bantype` = @bantype WHERE `name` = @name");
query.setValue("bantype", ci->bantype);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else
{
SQLQuery query("UPDATE `anope_cs_info` SET `flags` = @flags WHERE `name` = @name");
query.setValue("flags", ToString(ci->ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
}
else if (service->nick == Config->s_BotServ)
else if (command->name == "botserv/kick" && params.size() > 2)
{
if (command->name.equals_ci("KICK") && params.size() > 2)
ChannelInfo *ci = cs_findchan(params[0]);
if (!ci)
return;
if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
if (params[1].equals_ci("BADWORDS") || params[1].equals_ci("BOLDS") || params[1].equals_ci("CAPS") || params[1].equals_ci("COLORS") || params[1].equals_ci("FLOOD") || params[1].equals_ci("REPEAT") || params[1].equals_ci("REVERSES") || params[1].equals_ci("UNDERLINES"))
{
if (!ci)
return;
if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
if (params[1].equals_ci("BADWORDS") || params[1].equals_ci("BOLDS") || params[1].equals_ci("CAPS") || params[1].equals_ci("COLORS") || params[1].equals_ci("FLOOD") || params[1].equals_ci("REPEAT") || params[1].equals_ci("REVERSES") || params[1].equals_ci("UNDERLINES"))
if (params[2].equals_ci("ON") || params[2].equals_ci("OFF"))
{
if (params[2].equals_ci("ON") || params[2].equals_ci("OFF"))
for (int i = 0; i < TTB_SIZE; ++i)
{
for (int i = 0; i < TTB_SIZE; ++i)
{
SQLQuery query("INSERT INTO `anope_cs_ttb` (channel, ttb_id, value) VALUES(@channel, @ttb_id, @value) ON DUPLICATE KEY UPDATE channel=VALUES(channel), ttb_id=VALUES(ttb_id), value=VALUES(value)");
query.setValue("channel", ci->name);
query.setValue("ttb_id", i);
query.setValue("value", ci->ttb[i]);
this->RunQuery(query);
}
SQLQuery query("INSERT INTO `anope_cs_ttb` (channel, ttb_id, value) VALUES(@channel, @ttb_id, @value) ON DUPLICATE KEY UPDATE channel=VALUES(channel), ttb_id=VALUES(ttb_id), value=VALUES(value)");
query.setValue("channel", ci->name);
query.setValue("ttb_id", i);
query.setValue("value", ci->ttb[i]);
this->RunQuery(query);
}
{
SQLQuery query("UPDATE `anope_cs_info` SET `botflags` = @botflags WHERE `name` = @name");
query.setValue("botflags", ToString(ci->botflags.ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
{
SQLQuery query("UPDATE `anope_cs_info` SET `botflags` = @botflags WHERE `name` = @name");
query.setValue("botflags", ToString(ci->botflags.ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
if (params[1].equals_ci("CAPS"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `capsmin` = @capsmin, `capspercent` = @capspercent WHERE `name` = @name");
query.setValue("capsmin", ci->capsmin);
query.setValue("capspercent", ci->capspercent);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("FLOOD"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `floodlines` = @floodlines, `floodsecs` = @floodsecs WHERE `name` = @name");
query.setValue("floodlines", ci->floodlines);
query.setValue("floodsecs", ci->floodsecs);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("REPEAT"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `repeattimes` = @ WHERE `name` = @");
query.setValue("repeattimes", ci->repeattimes);
query.setValue("name", ci->name);
this->RunQuery(query);
}
if (params[1].equals_ci("CAPS"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `capsmin` = @capsmin, `capspercent` = @capspercent WHERE `name` = @name");
query.setValue("capsmin", ci->capsmin);
query.setValue("capspercent", ci->capspercent);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("FLOOD"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `floodlines` = @floodlines, `floodsecs` = @floodsecs WHERE `name` = @name");
query.setValue("floodlines", ci->floodlines);
query.setValue("floodsecs", ci->floodsecs);
query.setValue("name", ci->name);
this->RunQuery(query);
}
else if (params[1].equals_ci("REPEAT"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `repeattimes` = @ WHERE `name` = @");
query.setValue("repeattimes", ci->repeattimes);
query.setValue("name", ci->name);
this->RunQuery(query);
}
}
}
else if (command->name.equals_ci("SET") && params.size() > 2)
}
else if (command->name == "botserv/set" && params.size() > 1)
{
ChannelInfo *ci = cs_findchan(params[0]);
if (ci && !check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
BotInfo *bi = NULL;
if (!ci)
bi = findbot(params[0]);
if (bi && params[1].equals_ci("PRIVATE") && u->HasPriv("botserv/set/private"))
{
if (ci && !check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
BotInfo *bi = NULL;
if (!ci)
bi = findbot(params[0]);
if (bi && params[1].equals_ci("PRIVATE") && u->HasPriv("botserv/set/private"))
{
SQLQuery query("UPDATE `anope_bs_core` SET `flags` = @ WHERE `nick` = @");
query.setValue("flags", ToString(bi->ToString()));
query.setValue("nick", bi->nick);
this->RunQuery(query);
}
else if (!ci)
return;
else if (params[1].equals_ci("DONTKICKOPS") || params[1].equals_ci("DONTKICKVOICES") || params[1].equals_ci("FANTASY") || params[1].equals_ci("GREET") || params[1].equals_ci("SYMBIOSIS") || params[1].equals_ci("NOBOT"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `botflags` = @ WHERE `name` = @");
query.setValue("botflags", ToString(ci->botflags.ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
SQLQuery query("UPDATE `anope_bs_core` SET `flags` = @ WHERE `nick` = @");
query.setValue("flags", ToString(bi->ToString()));
query.setValue("nick", bi->nick);
this->RunQuery(query);
}
else if (!ci)
return;
else if (params[1].equals_ci("DONTKICKOPS") || params[1].equals_ci("DONTKICKVOICES") || params[1].equals_ci("FANTASY") || params[1].equals_ci("GREET") || params[1].equals_ci("SYMBIOSIS") || params[1].equals_ci("NOBOT"))
{
SQLQuery query("UPDATE `anope_cs_info` SET `botflags` = @ WHERE `name` = @");
query.setValue("botflags", ToString(ci->botflags.ToString()));
query.setValue("name", ci->name);
this->RunQuery(query);
}
}
else if (service->nick == Config->s_MemoServ)
else if (command->name == "memoserv/ignore" && params.size() > 0)
{
if (command->name.equals_ci("IGNORE") && params.size() > 0)
Anope::string target = params[0];
NickCore *nc = NULL;
ChannelInfo *ci = NULL;
if (target[0] != '#')
{
Anope::string target = params[0];
NickCore *nc = NULL;
ci = NULL;
if (target[0] != '#')
{
target = u->nick;
nc = u->Account();
if (!nc)
return;
}
else
{
ci = cs_findchan(target);
if (!ci || !check_access(u, ci, CA_MEMO))
return;
}
target = u->nick;
nc = u->Account();
if (!nc)
return;
}
else
{
ci = cs_findchan(target);
if (!ci || !check_access(u, ci, CA_MEMO))
return;
}
MemoInfo *mi = ci ? &ci->memos : &nc->memos;
Anope::string table = ci ? "anope_cs_info_metadata" : "anope_ns_core_metadata";
Anope::string ename = ci ? "channel" : "nick";
MemoInfo *mi = ci ? &ci->memos : &nc->memos;
Anope::string table = ci ? "anope_cs_info_metadata" : "anope_ns_core_metadata";
Anope::string ename = ci ? "channel" : "nick";
SQLQuery query("DELETE FROM `" + table + "` WHERE `" + ename + "` = @target AND `name` = 'MEMO_IGNORE'");
query.setValue("target", target);
SQLQuery query("DELETE FROM `" + table + "` WHERE `" + ename + "` = @target AND `name` = 'MEMO_IGNORE'");
query.setValue("target", target);
this->RunQuery(query);
query = "INSERT INTO `" + table + "` VALUES(" + ename + ", name, value) (@target, 'MEMO_IGNORE, @ignore)";
query.setValue("target", target);
for (unsigned j = 0; j < mi->ignores.size(); ++j)
{
query.setValue("ignore", mi->ignores[j]);
this->RunQuery(query);
query = "INSERT INTO `" + table + "` VALUES(" + ename + ", name, value) (@target, 'MEMO_IGNORE, @ignore)";
query.setValue("target", target);
for (unsigned j = 0; j < mi->ignores.size(); ++j)
{
query.setValue("ignore", mi->ignores[j]);
this->RunQuery(query);
}
}
}
}
@@ -1334,34 +1301,6 @@ class DBMySQL : public Module
this->RunQuery(query);
}
EventReturn OnAddAkill(XLine *ak)
{
SQLQuery query("INSERT INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES(@user, @host, @xby, @reason, @seton, @expire)");
query.setValue("user", ak->GetUser());
query.setValue("host", ak->GetHost());
query.setValue("xby", ak->By);
query.setValue("reason", ak->Reason);
query.setValue("seton", ak->Created);
query.setValue("expire", ak->Expires);
this->RunQuery(query);
return EVENT_CONTINUE;
}
void OnDelAkill(User *, XLine *ak)
{
SQLQuery query;
if (ak)
{
query = "DELETE FROM `anope_os_akills` WHERE `host` = @host";
query.setValue("host", ak->GetHost());
}
else
query = "TRUNCATE TABLE `anope_os_akills`";
this->RunQuery(query);
}
EventReturn OnExceptionAdd(Exception *ex)
{
SQLQuery query("INSERT INTO `anope_os_exceptions` (mask, slimit, who, reason, time, expires) VALUES(@mask, @slimit, @who, @reason, @time, @expires)");
@@ -1381,10 +1320,10 @@ class DBMySQL : public Module
this->RunQuery(query);
}
EventReturn OnAddXLine(XLine *x, XLineType Type)
EventReturn OnAddXLine(XLine *x, XLineManager *xlm)
{
SQLQuery query("INSERT INTO `anope_os_xlines` (type, mask, xby, reason, seton, expire) VALUES(@type, @mask, @xby, @reason, @seton, @expire)");
query.setValue("type", Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE"));
query.setValue("type", Anope::string(xlm->Type()));
query.setValue("mask", x->Mask);
query.setValue("xby", x->By);
query.setValue("reason", x->Reason);
@@ -1394,7 +1333,7 @@ class DBMySQL : public Module
return EVENT_CONTINUE;
}
void OnDelXLine(User *, XLine *x, XLineType Type)
void OnDelXLine(User *, XLine *x, XLineManager *xlm)
{
SQLQuery query;
@@ -1402,12 +1341,12 @@ class DBMySQL : public Module
{
query = "DELETE FROM `anope_os_xlines` WHERE `mask` = @mask AND `type` = @type";
query.setValue("mask", x->Mask);
query.setValue("type", Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE"));
query.setValue("type", Anope::string(xlm->Type()));
}
else
{
query = "DELETE FROM `anope_os_xlines` WHERE `type` = @type";
query.setValue("type", Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE"));
query.setValue("type", Anope::string(xlm->Type()));
}
this->RunQuery(query);
@@ -1602,32 +1541,20 @@ static void SaveDatabases()
}
}
if (SGLine)
for (unsigned i = 0, end = SGLine->GetCount(); i < end; ++i)
me->OnAddAkill(SGLine->GetEntry(i));
if (SZLine)
for (unsigned i = 0, end = SZLine->GetCount(); i < end; ++i)
me->OnAddXLine(SZLine->GetEntry(i), X_SZLINE);
if (SQLine)
for (unsigned i = 0, end = SQLine->GetCount(); i < end; ++i)
me->OnAddXLine(SQLine->GetEntry(i), X_SQLINE);
if (SNLine)
for (unsigned i = 0, end = SNLine->GetCount(); i < end; ++i)
me->OnAddXLine(SNLine->GetEntry(i), X_SNLINE);
for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
for (unsigned i = 0, end = (*it)->GetCount(); i < end; ++i)
me->OnAddXLine((*it)->GetEntry(i), *it);
if (me->SessionInterface)
for (SessionService::ExceptionVector::iterator it = me->SessionInterface->GetExceptions().begin(); it != me->SessionInterface->GetExceptions().end(); ++it)
me->OnExceptionAdd(*it);
}
CommandReturn CommandSQLSync::Execute(CommandSource &source, const std::vector<Anope::string> &params)
void CommandSQLSync::Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
SaveDatabases();
source.Reply(_("Updating MySQL."));
return MOD_CONT;
return;
}
MODULE_INIT(DBMySQL)
+36 -63
View File
@@ -11,7 +11,6 @@
/*************************************************************************/
#include "module.h"
#include "operserv.h"
#include "os_session.h"
Anope::string DatabaseFile;
@@ -305,38 +304,28 @@ static void LoadOperInfo(const std::vector<Anope::string> &params)
maxusercnt = params[1].is_pos_number_only() ? convertTo<uint32>(params[1]) : 0;
maxusertime = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0;
}
else if (params[0].equals_ci("SNLINE") || params[0].equals_ci("SQLINE") || params[0].equals_ci("SZLINE"))
else if (params[0].equals_ci("SXLINE"))
{
Anope::string mask = params[1];
Anope::string by = params[2];
time_t seton = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : 0;
time_t expires = params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0;
Anope::string reason = params[5];
char type = params[1][0];
for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
{
XLineManager *xl = *it;
if (xl->Type() == type)
{
Anope::string mask = params[2];
Anope::string by = params[3];
time_t seton = params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0;
time_t expires = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0;
Anope::string reason = params[6];
XLine *x = NULL;
if (params[0].equals_ci("SNLINE") && SNLine)
x = SNLine->Add(mask, by, expires, reason);
else if (params[0].equals_ci("SQLINE") && SQLine)
x = SQLine->Add(mask, by, expires, reason);
else if (params[0].equals_ci("SZLINE") && SZLine)
x = SZLine->Add(mask, by, expires, reason);
if (x)
x->Created = seton;
XLine *x = xl->Add(mask, by, expires, reason);
if (x)
x->Created = seton;
break;
}
}
}
else if (params[0].equals_ci("AKILL") && SGLine)
{
Anope::string user = params[1];
Anope::string host = params[2];
Anope::string by = params[3];
time_t seton = params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0;
time_t expires = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0;
Anope::string reason = params[6];
XLine *x = SGLine->Add(user + "@" + host, by, expires, reason);
if (x)
x->Created = seton;
}
else if (params[0].equals_ci("EXCEPTION"))
else if (params[0].equals_ci("EXCEPTION") && SessionInterface)
{
Exception *exception = new Exception();
exception->mask = params[1];
@@ -403,8 +392,6 @@ class DBPlain : public Module
Log(LOG_DEBUG) << "db_plain: Attemping to rename " << DatabaseFile << " to " << newname;
if (rename(DatabaseFile.c_str(), newname.c_str()))
{
if (operserv)
ircdproto->SendGlobops(operserv->Bot(), "Unable to backup database!");
Log() << "Unable to back up database!";
if (!Config->NoBackupOkay)
@@ -755,6 +742,9 @@ class DBPlain : public Module
{
BotInfo *bi = it->second;
if (bi->HasFlag(BI_CONF))
continue;
db_buffer << "BI " << bi->nick << " " << bi->GetIdent() << " " << bi->host << " " << bi->created << " " << bi->chancount << " :" << bi->realname << endl;
if (bi->FlagCount())
db_buffer << "MD FLAGS " << ToString(bi->ToString()) << endl;
@@ -850,40 +840,23 @@ class DBPlain : public Module
db_buffer << "OS STATS " << maxusercnt << " " << maxusertime << endl;
if (SGLine)
for (unsigned i = 0, end = SGLine->GetCount(); i < end; ++i)
{
XLine *x = SGLine->GetEntry(i);
db_buffer << "OS AKILL " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
if (SNLine)
for (unsigned i = 0, end = SNLine->GetCount(); i < end; ++i)
{
XLine *x = SNLine->GetEntry(i);
db_buffer << "OS SNLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
if (SQLine)
for (unsigned i = 0, end = SQLine->GetCount(); i < end; ++i)
{
XLine *x = SQLine->GetEntry(i);
db_buffer << "OS SQLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
if (SZLine)
for (unsigned i = 0, end = SZLine->GetCount(); i < end; ++i)
{
XLine *x = SZLine->GetEntry(i);
db_buffer << "OS SZLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
for (SessionService::ExceptionVector::iterator it = SessionInterface->GetExceptions().begin(); it != SessionInterface->GetExceptions().end(); ++it)
for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
{
Exception *e = *it;
db_buffer << "OS EXCEPTION " << e->mask << " " << e->limit << " " << e->who << " " << e->time << " " << e->expires << " " << e->reason << endl;
XLineManager *xl = *it;
for (unsigned i = 0, end = xl->GetCount(); i < end; ++i)
{
XLine *x = xl->GetEntry(i);
db_buffer << "OS SXLINE " << xl->Type() << " " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
}
if (SessionInterface)
for (SessionService::ExceptionVector::iterator it = SessionInterface->GetExceptions().begin(); it != SessionInterface->GetExceptions().end(); ++it)
{
Exception *e = *it;
db_buffer << "OS EXCEPTION " << e->mask << " " << e->limit << " " << e->who << " " << e->time << " " << e->expires << " " << e->reason << endl;
}
FOREACH_MOD(I_OnDatabaseWrite, OnDatabaseWrite(Write));
std::fstream db;
+1 -1
View File
@@ -339,7 +339,7 @@ class EMD5 : public Module
return EVENT_ALLOW;
}
EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
NickAlias *na = findnick(account);
NickCore *nc = na ? na->nc : NULL;
+1 -1
View File
@@ -41,7 +41,7 @@ class ENone : public Module
return EVENT_ALLOW;
}
EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
NickAlias *na = findnick(account);
NickCore *nc = na ? na->nc : NULL;
+1 -1
View File
@@ -349,7 +349,7 @@ class EOld : public Module
return EVENT_ALLOW;
}
EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
NickAlias *na = findnick(account);
NickCore *nc = na ? na->nc : NULL;
+1 -1
View File
@@ -192,7 +192,7 @@ class ESHA1 : public Module
return EVENT_ALLOW;
}
EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
NickAlias *na = findnick(account);
NickCore *nc = na ? na->nc : NULL;
+1 -1
View File
@@ -278,7 +278,7 @@ class ESHA256 : public Module
return EVENT_ALLOW;
}
EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
NickAlias *na = findnick(account);
NickCore *nc = na ? na->nc : NULL;
+17 -19
View File
@@ -17,34 +17,34 @@
class CommandGLGlobal : public Command
{
public:
CommandGLGlobal() : Command("GLOBAL", 1, 1, "global/global")
CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1, "global/global")
{
this->SetDesc(_("Send a message to all users"));
this->SetSyntax(_("\037message\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
const Anope::string &msg = params[0];
Log(LOG_ADMIN, u, this);
global->SendGlobal(global->Bot(), u->nick, msg);
return MOD_CONT;
if (!global)
source.Reply("No global reference, is gl_main loaded?");
else
{
Log(LOG_ADMIN, u, this);
global->SendGlobal(findbot(Config->Global), u->nick, msg);
}
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002GLOBAL \037message\037\002\n"
" \n"
"Allows Administrators to send messages to all users on the \n"
"network. The message will be sent from the nick \002%s\002."), Config->s_Global.c_str());
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows Administrators to send messages to all users on the \n"
"network. The message will be sent from the nick \002%s\002."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "GLOBAL", _("GLOBAL \037message\037"));
}
};
class GLGlobal : public Module
@@ -52,14 +52,12 @@ class GLGlobal : public Module
CommandGLGlobal commandglglobal;
public:
GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandglglobal(this)
{
this->SetAuthor("Anope");
if (Config->s_Global.empty())
throw ModuleException("Global is disabled");
this->AddCommand(global->Bot(), &commandglglobal);
ModuleManager::RegisterService(&commandglglobal);
}
};
-57
View File
@@ -1,57 +0,0 @@
/* Global 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"
#include "global.h"
class CommandGLHelp : public Command
{
public:
CommandGLHelp() : Command("HELP", 1, 1)
{
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(global->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
source.Reply(_("%s commands:"), Config->s_Global.c_str());
for (CommandMap::const_iterator it = global->Bot()->Commands.begin(), it_end = global->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
}
};
class GLHelp : public Module
{
CommandGLHelp commandoshelp;
public:
GLHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!global)
throw ModuleException("Global is not loaded!");
this->AddCommand(global->Bot(), &commandoshelp);
}
};
MODULE_INIT(GLHelp)
+25 -42
View File
@@ -14,26 +14,19 @@
#include "module.h"
#include "global.h"
static BotInfo *Global = NULL;
class MyGlobalService : public GlobalService
{
void ServerGlobal(Server *s, const Anope::string &message)
{
if (s != Me && !s->HasFlag(SERVER_JUPED))
notice_server(Config->s_Global, s, "%s", message.c_str());
void ServerGlobal(Server *s, const Anope::string &message)
{
if (s != Me && !s->HasFlag(SERVER_JUPED))
notice_server(Config->Global, s, "%s", message.c_str());
for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
this->ServerGlobal(s->GetLinks()[i], message);
}
}
public:
MyGlobalService(Module *m) : GlobalService(m) { }
BotInfo *Bot()
{
return Global;
}
void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message)
{
if (Me->GetLinks().empty())
@@ -52,57 +45,47 @@ class MyGlobalService : public GlobalService
class GlobalCore : public Module
{
MyGlobalService myglobal;
MyGlobalService myglobalservice;
public:
GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), myglobal(this)
GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
myglobalservice(this)
{
this->SetAuthor("Anope");
Implementation i[] = { I_OnRestart, I_OnShutdown, I_OnNewServer };
BotInfo *Global = findbot(Config->Global);
if (Global == NULL)
throw ModuleException("No bot named " + Config->Global);
ModuleManager::RegisterService(&this->myglobalservice);
Implementation i[] = { I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp };
ModuleManager::Attach(i, this, 3);
ModuleManager::RegisterService(&this->myglobal);
Global = new BotInfo(Config->s_Global, Config->ServiceUser, Config->ServiceHost, Config->desc_Global);
Global->SetFlag(BI_CORE);
spacesepstream coreModules(Config->GlobalCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
ModuleManager::LoadModule(module, NULL);
}
~GlobalCore()
{
spacesepstream coreModules(Config->GlobalCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
{
Module *m = ModuleManager::FindModule(module);
if (m != NULL)
ModuleManager::UnloadModule(m, NULL);
}
delete Global;
}
void OnRestart()
{
if (Config->GlobalOnCycle)
global->SendGlobal(global->Bot(), "", Config->GlobalOnCycleMessage);
global->SendGlobal(findbot(Config->Global), "", Config->GlobalOnCycleMessage);
}
void OnShutdown()
{
if (Config->GlobalOnCycle)
global->SendGlobal(global->Bot(), "", Config->GlobalOnCycleMessage);
global->SendGlobal(findbot(Config->Global), "", Config->GlobalOnCycleMessage);
}
void OnNewServer(Server *s)
{
if (Config->GlobalOnCycle && !Config->GlobalOnCycleUP.empty())
notice_server(Config->s_Global, s, "%s", Config->GlobalOnCycleUP.c_str());
notice_server(Config->Global, s, "%s", Config->GlobalOnCycleUP.c_str());
}
void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (!params.empty() || source.owner->nick != Config->Global)
return;
source.Reply(_("%s commands:\n"), Config->Global.c_str());
}
};
-2
View File
@@ -6,8 +6,6 @@ class GlobalService : public Service
public:
GlobalService(Module *m) : Service(m, "Global") { }
virtual BotInfo *Bot() = 0;
/** Send out a global message to all users
* @param sender Our client which should send the global
* @param source The sender of the global
+120
View File
@@ -0,0 +1,120 @@
/* 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 CommandHelp : public Command
{
public:
CommandHelp(Module *creator) : Command(creator, "generic/help", 0)
{
this->SetDesc(_("Displays this list and give information about commands"));
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
FOREACH_MOD(I_OnPreHelp, OnPreHelp(source, params));
User *u = source.u;
BotInfo *bi = source.owner;
if (params.empty())
{
for (command_map::iterator it = bi->commands.begin(), it_end = bi->commands.end(); it != it_end; ++it)
{
// Smaller command exists
Anope::string cmd = myStrGetToken(it->first, ' ', 0);
if (cmd != it->first && bi->commands.count(cmd))
continue;
service_reference<Command> c(it->second);
if (!c)
continue;
if (!Config->HidePrivilegedCommands || c->permission.empty() || u->HasCommand(c->permission))
{
source.command = it->first;
c->OnServHelp(source);
}
}
}
else
{
bool helped = false;
for (unsigned max = params.size(); max > 0; --max)
{
Anope::string full_command;
for (unsigned i = 0; i < max; ++i)
full_command += " " + params[i];
full_command.erase(full_command.begin());
std::map<Anope::string, Anope::string>::iterator it = bi->commands.find(full_command);
if (it == bi->commands.end())
continue;
service_reference<Command> c(it->second);
if (!c)
continue;
if (Config->HidePrivilegedCommands && !c->permission.empty() && !u->HasCommand(c->permission))
continue;
const Anope::string &subcommand = params.size() > max ? params[max] : "";
source.command = full_command;
if (!c->OnHelp(source, subcommand))
continue;
helped = true;
source.Reply(" ");
/* Inform the user what permission is required to use the command */
if (!c->permission.empty())
source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), c->permission.c_str());
if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
source.Reply( _("You need to be identified to use this command."));
/* User doesn't have the proper permission to use this command */
else if (!c->permission.empty() && !u->HasCommand(c->permission))
source.Reply(_("You cannot use this command."));
/* User can use this command */
else
source.Reply(_("You can use this command."));
break;
}
if (helped == false)
source.Reply(_("No help available for \002%s\002."), params[0].c_str());
}
FOREACH_MOD(I_OnPostHelp, OnPostHelp(source, params));
return;
}
};
class Help : public Module
{
CommandHelp commandhelp;
public:
Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhelp(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandhelp);
}
};
MODULE_INIT(Help)
-17
View File
@@ -1,17 +0,0 @@
#ifndef HOSTSERV_H
#define HOSTSERV_H
class HostServService : public Service
{
public:
HostServService(Module *m) : Service(m, "HostServ") { }
virtual BotInfo *Bot() = 0;
virtual void Sync(NickAlias *na) = 0;
};
static service_reference<HostServService> hostserv("HostServ");
#endif // HOSTSERV_H
+50 -16
View File
@@ -12,17 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSDel : public Command
{
public:
CommandHSDel() : Command("DEL", 1, 1, "hostserv/del")
CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 1, "hostserv/del")
{
this->SetDesc(_("Delete the vhost of another user"));
this->SetSyntax(_("\037nick\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
const Anope::string &nick = params[0];
@@ -32,41 +32,75 @@ class CommandHSDel : public Command
Log(LOG_ADMIN, u, this) << "for user " << na->nick;
FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na));
na->hostinfo.RemoveVhost();
source.Reply(_("vhost for \002%s\002 removed."), nick.c_str());
source.Reply(_("Vhost for \002%s\002 removed."), nick.c_str());
}
else
source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEL\002 \002<nick>\002\n"
"Deletes the vhost assigned to the given nick from the\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deletes the vhost assigned to the given nick from the\n"
"database."));
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
class CommandHSDelAll : public Command
{
public:
CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1, "hostserv/del")
{
SyntaxError(source, "DEL", _("DEL \002<nick>\002."));
this->SetDesc(_("Delete the vhost for all nicks in a group"));
this->SetSyntax(_("\037nick\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[0];
User *u = source.u;
NickAlias *na = findnick(nick);
if (na)
{
FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na));
NickCore *nc = na->nc;
for (std::list<NickAlias *>::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it)
{
na = *it;
na->hostinfo.RemoveVhost();
}
Log(LOG_ADMIN, u, this) << "for all nicks in group " << nc->display;
source.Reply(_("vhosts for group \002%s\002 have been removed."), nc->display.c_str());
}
else
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deletes the vhost for all nicks in the same group as\n"
"that of the given nick."));
return true;
}
};
class HSDel : public Module
{
CommandHSDel commandhsdel;
CommandHSDelAll commandhsdelall;
public:
HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhsdel(this), commandhsdelall(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhsdel);
ModuleManager::RegisterService(&commandhsdel);
ModuleManager::RegisterService(&commandhsdelall);
}
};
-78
View File
@@ -1,78 +0,0 @@
/* HostServ 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"
#include "hostserv.h"
class CommandHSDelAll : public Command
{
public:
CommandHSDelAll() : Command("DELALL", 1, 1, "hostserv/del")
{
this->SetDesc(_("Delete the vhost for all nicks in a group"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[0];
User *u = source.u;
NickAlias *na = findnick(nick);
if (na)
{
FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na));
NickCore *nc = na->nc;
for (std::list<NickAlias *>::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it)
{
na = *it;
na->hostinfo.RemoveVhost();
}
Log(LOG_ADMIN, u, this) << "for all nicks in group " << nc->display;
source.Reply(_("vhosts for group \002%s\002 have been removed."), nc->display.c_str());
}
else
source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str());
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DELALL\002 \002<nick>\002.\n"
"Deletes the vhost for all nicks in the same group as\n"
"that of the given nick."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DELALL", _("DELALL <nick>\002."));
}
};
class HSDelAll : public Module
{
CommandHSDelAll commandhsdelall;
public:
HSDelAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhsdelall);
}
};
MODULE_INIT(HSDelAll)
+26 -16
View File
@@ -12,39 +12,51 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSGroup : public Command
{
public:
CommandHSGroup() : Command("GROUP", 0, 0)
void Sync(NickAlias *na)
{
this->SetDesc(_("Syncs the vhost for all nicks in a group"));
if (!na || !na->hostinfo.HasVhost())
return;
for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end; ++it)
{
NickAlias *nick = *it;
nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
}
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
public:
CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0)
{
this->SetDesc(_("Syncs the vhost for all nicks in a group"));
this->SetSyntax("");
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
NickAlias *na = findnick(u->nick);
if (na && u->Account() == na->nc && na->hostinfo.HasVhost())
{
hostserv->Sync(na);
this->Sync(na);
if (!na->hostinfo.GetIdent().empty())
source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002@\002%s\002"), u->Account()->display.c_str(), na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str());
else
source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002"), u->Account()->display.c_str(), na->hostinfo.GetHost().c_str());
}
else
source.Reply(_(HOST_NOT_ASSIGNED));
source.Reply(HOST_NOT_ASSIGNED);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002GROUP\002\n"
" \n"
"This command allows users to set the vhost of their\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("This command allows users to set the vhost of their\n"
"CURRENT nick to be the vhost for all nicks in the same\n"
"group."));
return true;
@@ -56,14 +68,12 @@ class HSGroup : public Module
CommandHSGroup commandhsgroup;
public:
HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhsgroup(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhsgroup);
ModuleManager::RegisterService(&commandhsgroup);
}
};
-58
View File
@@ -1,58 +0,0 @@
/* HostServ 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"
#include "hostserv.h"
class CommandHSHelp : public Command
{
public:
CommandHSHelp() : Command("HELP", 1, 1)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(hostserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
source.Reply(_("%s commands:"), Config->s_HostServ.c_str());
for (CommandMap::const_iterator it = hostserv->Bot()->Commands.begin(), it_end = hostserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
}
};
class HSHelp : public Module
{
CommandHSHelp commandhshelp;
public:
HSHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhshelp);
}
};
MODULE_INIT(HSHelp)
+14 -15
View File
@@ -12,17 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSList : public Command
{
public:
CommandHSList() : Command("LIST", 0, 1, "hostserv/list")
CommandHSList(Module *creator) : Command(creator, "hostserv/list", 0, 1, "hostserv/list")
{
this->SetDesc(_("Displays one or more vhost entries."));
this->SetSyntax(_("\002[<key>|<#X-Y>]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &key = !params.empty() ? params[0] : "";
int from = 0, to = 0, counter = 1;
@@ -37,15 +37,15 @@ class CommandHSList : public Command
size_t tmp = key.find('-');
if (tmp == Anope::string::npos || tmp == key.length() || tmp == 1)
{
source.Reply(_(LIST_INCORRECT_RANGE));
return MOD_CONT;
source.Reply(LIST_INCORRECT_RANGE);
return;
}
for (unsigned i = 1, end = key.length(); i < end; ++i)
{
if (!isdigit(key[i]) && i != tmp)
{
source.Reply(_(LIST_INCORRECT_RANGE));
return MOD_CONT;
source.Reply(LIST_INCORRECT_RANGE);
return;
}
try
{
@@ -100,13 +100,14 @@ class CommandHSList : public Command
else
source.Reply(_("Displayed all records (Count: \002%d\002)"), display_counter);
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002LIST\002 \002[<key>|<#X-Y>]\002\n"
"This command lists registered vhosts to the operator\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("This command lists registered vhosts to the operator\n"
"if a Key is specified, only entries whos nick or vhost match\n"
"the pattern given in <key> are displayed e.g. Rob* for all\n"
"entries beginning with \"Rob\"\n"
@@ -124,14 +125,12 @@ class HSList : public Module
CommandHSList commandhslist;
public:
HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhslist(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhslist);
ModuleManager::RegisterService(&commandhslist);
}
};
+22 -59
View File
@@ -12,71 +12,23 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
static BotInfo *HostServ = NULL;
class MyHostServService : public HostServService
{
public:
MyHostServService(Module *m) : HostServService(m) { }
BotInfo *Bot()
{
return HostServ;
}
void Sync(NickAlias *na)
{
if (!na || !na->hostinfo.HasVhost())
return;
for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end; ++it)
{
NickAlias *nick = *it;
nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
}
}
};
class HostServCore : public Module
{
MyHostServService myhostserv;
public:
HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), myhostserv(this)
HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!ircd || !ircd->vhost)
throw ModuleException("Your IRCd does not suppor vhosts");
BotInfo *HostServ = findbot(Config->HostServ);
if (HostServ == NULL)
throw ModuleException("No bot named " + Config->HostServ);
ModuleManager::RegisterService(&this->myhostserv);
HostServ = new BotInfo(Config->s_HostServ, Config->ServiceUser, Config->ServiceHost, Config->desc_HostServ);
HostServ->SetFlag(BI_CORE);
Implementation i[] = { I_OnNickIdentify, I_OnNickUpdate };
ModuleManager::Attach(i, this, 2);
spacesepstream coreModules(Config->HostCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
ModuleManager::LoadModule(module, NULL);
}
~HostServCore()
{
spacesepstream coreModules(Config->HostCoreModules);
Anope::string module;
while (coreModules.GetToken(module))
{
Module *m = ModuleManager::FindModule(module);
if (m != NULL)
ModuleManager::UnloadModule(m, NULL);
}
delete HostServ;
Implementation i[] = { I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp };
ModuleManager::Attach(i, this, 3);
}
void OnNickIdentify(User *u)
@@ -105,10 +57,14 @@ class HostServCore : public Module
if (ircd->vident && !na->hostinfo.GetIdent().empty())
u->SetVIdent(na->hostinfo.GetIdent());
if (!na->hostinfo.GetIdent().empty())
u->SendMessage(HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str());
else
u->SendMessage(HostServ, _("Your vhost of \002%s\002 is now activated."), na->hostinfo.GetHost().c_str());
BotInfo *bi = findbot(Config->HostServ);
if (bi)
{
if (!na->hostinfo.GetIdent().empty())
u->SendMessage(bi, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str());
else
u->SendMessage(bi, _("Your vhost of \002%s\002 is now activated."), na->hostinfo.GetHost().c_str());
}
}
}
@@ -116,6 +72,13 @@ class HostServCore : public Module
{
this->OnNickIdentify(u);
}
void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params)
{
if (!params.empty() || source.owner->nick != Config->HostServ)
return;
source.Reply(_("%s commands:\n"), Config->HostServ.c_str());
}
};
MODULE_INIT(HostServCore)
+11 -12
View File
@@ -12,23 +12,23 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSOff : public Command
{
public:
CommandHSOff() : Command("OFF", 0, 0)
CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0)
{
this->SetDesc(_("Deactivates your assigned vhost"));
this->SetSyntax("");
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
NickAlias *na = findnick(u->nick);
if (!na || !na->hostinfo.HasVhost())
source.Reply(_(HOST_NOT_ASSIGNED));
source.Reply(HOST_NOT_ASSIGNED);
else
{
ircdproto->SendVhostDel(u);
@@ -36,13 +36,14 @@ class CommandHSOff : public Command
source.Reply(_("Your vhost was removed and the normal cloaking restored."));
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002OFF\002\n"
"Deactivates the vhost currently assigned to the nick in use.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
"on you will see your real IP address."));
return true;
@@ -54,14 +55,12 @@ class HSOff : public Module
CommandHSOff commandhsoff;
public:
HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhsoff(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhsoff);
ModuleManager::RegisterService(&commandhsoff);
}
};
+11 -12
View File
@@ -12,17 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSOn : public Command
{
public:
CommandHSOn() : Command("ON", 0, 0)
CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0)
{
this->SetDesc(_("Activates your assigned vhost"));
this->SetSyntax("");
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
NickAlias *na = findnick(u->nick);
@@ -44,15 +44,16 @@ class CommandHSOn : public Command
u->UpdateHost();
}
else
source.Reply(_(HOST_NOT_ASSIGNED));
source.Reply(HOST_NOT_ASSIGNED);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002ON\002\n"
"Activates the vhost currently assigned to the nick in use.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
"on you will see the vhost instead of your real IP address."));
return true;
@@ -64,14 +65,12 @@ class HSOn : public Module
CommandHSOn commandhson;
public:
HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandhson(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhson);
ModuleManager::RegisterService(&commandhson);
}
};
+129 -26
View File
@@ -12,27 +12,27 @@
/*************************************************************************/
#include "module.h"
#include "hostserv.h"
class CommandHSSet : public Command
{
public:
CommandHSSet() : Command("SET", 2, 2, "hostserv/set")
CommandHSSet(Module *creator) : Command(creator, "hostserv/set", 2, 2, "hostserv/set")
{
this->SetDesc(_("Set the vhost of another user"));
this->SetSyntax(_("\037nick\037 \037hostmask\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string nick = params[0];
const Anope::string &nick = params[0];
NickAlias *na = findnick(nick);
if (na == NULL)
{
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
return MOD_CONT;
return;
}
Anope::string rawhostmask = params[1];
@@ -51,7 +51,7 @@ class CommandHSSet : public Command
if (host.empty())
{
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
if (!user.empty())
@@ -59,31 +59,31 @@ class CommandHSSet : public Command
if (user.length() > Config->UserLen)
{
source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen);
return MOD_CONT;
return;
}
else if (!ircd->vident)
{
source.Reply(HOST_NO_VIDENT);
return MOD_CONT;
return;
}
for (Anope::string::iterator s = user.begin(), s_end = user.end(); s != s_end; ++s)
if (!isvalidchar(*s))
{
source.Reply(HOST_SET_IDENT_ERROR);
return MOD_CONT;
return;
}
}
if (host.length() > Config->HostLen)
{
source.Reply(_(HOST_SET_TOOLONG), Config->HostLen);
return MOD_CONT;
source.Reply(HOST_SET_TOOLONG, Config->HostLen);
return;
}
if (!isValidHost(host, 3))
{
source.Reply(_(HOST_SET_ERROR));
return MOD_CONT;
source.Reply(HOST_SET_ERROR);
return;
}
Log(LOG_ADMIN, u, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
@@ -91,42 +91,145 @@ class CommandHSSet : public Command
na->hostinfo.SetVhost(user, host, u->nick);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
if (!user.empty())
source.Reply(_("vhost for \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
source.Reply(_("VHost for \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
else
source.Reply(_("vhost for \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
return MOD_CONT;
source.Reply(_("VHost for \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002SET\002 \002<nick>\002 \002<hostmask>\002.\n"
"Sets the vhost for the given nick to that of the given\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Sets the vhost for the given nick to that of the given\n"
"hostmask. If your IRCD supports vIdents, then using\n"
"SET <nick> <ident>@<hostmask> set idents for users as \n"
"well as vhosts."));
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
class CommandHSSetAll : public Command
{
void Sync(NickAlias *na)
{
SyntaxError(source, "SET", _("SET \002<nick>\002 \002<hostmask>\002."));
if (!na || !na->hostinfo.HasVhost())
return;
for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end; ++it)
{
NickAlias *nick = *it;
nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
}
}
public:
CommandHSSetAll(Module *creator) : Command(creator, "hostserv/setall", 2, 2, "hostserv/set")
{
this->SetDesc(_("Set the vhost for all nicks in a group"));
this->SetSyntax(_("\037nick\037 \037hostmask>\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string nick = params[0];
NickAlias *na = findnick(nick);
if (na == NULL)
{
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
return;
}
Anope::string rawhostmask = params[1];
Anope::string user, host;
size_t a = rawhostmask.find('@');
if (a == Anope::string::npos)
host = rawhostmask;
else
{
user = rawhostmask.substr(0, a);
host = rawhostmask.substr(a + 1);
}
if (host.empty())
{
this->OnSyntaxError(source, "");
return;
}
if (!user.empty())
{
if (user.length() > Config->UserLen)
{
source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen);
return;
}
else if (!ircd->vident)
{
source.Reply(HOST_NO_VIDENT);
return;
}
for (Anope::string::iterator s = user.begin(), s_end = user.end(); s != s_end; ++s)
if (!isvalidchar(*s))
{
source.Reply(HOST_SET_IDENT_ERROR);
return;
}
}
if (host.length() > Config->HostLen)
{
source.Reply(HOST_SET_TOOLONG, Config->HostLen);
return;
}
if (!isValidHost(host, 3))
{
source.Reply(HOST_SET_ERROR);
return;
}
Log(LOG_ADMIN, u, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
na->hostinfo.SetVhost(user, host, u->nick);
this->Sync(na);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
if (!user.empty())
source.Reply(_("VHost for group \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
else
source.Reply(_("VHost for group \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Sets the vhost for all nicks in the same group as that\n"
"of the given nick. If your IRCD supports vIdents, then\n"
"using SETALL <nick> <ident>@<hostmask> will set idents\n"
"for users as well as vhosts.\n"
"* NOTE, this will not update the vhost for any nicks\n"
"added to the group after this command was used."));
return true;
}
};
class HSSet : public Module
{
CommandHSSet commandhsset;
CommandHSSetAll commandhssetall;
public:
HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandhsset(this), commandhssetall(this)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhsset);
ModuleManager::RegisterService(&commandhsset);
ModuleManager::RegisterService(&commandhssetall);
}
};
-135
View File
@@ -1,135 +0,0 @@
/* HostServ 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"
#include "hostserv.h"
class CommandHSSetAll : public Command
{
public:
CommandHSSetAll() : Command("SETALL", 2, 2, "hostserv/set")
{
this->SetDesc(_("Set the vhost for all nicks in a group"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string nick = params[0];
NickAlias *na = findnick(nick);
if (na == NULL)
{
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
return MOD_CONT;
}
Anope::string rawhost = params[1];
Anope::string user, host;
size_t a = rawhost.find('@');
if (a == Anope::string::npos)
host = rawhost;
else
{
user = rawhost.substr(0, a);
host = rawhost.substr(a + 1);
}
if (host.empty())
{
this->OnSyntaxError(source, "");
return MOD_CONT;
}
if (!user.empty())
{
if (user.length() > Config->UserLen)
{
source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen);
return MOD_CONT;
}
else if (!ircd->vident)
{
source.Reply(HOST_NO_VIDENT);
return MOD_CONT;
}
for (Anope::string::iterator s = user.begin(), s_end = user.end(); s != s_end; ++s)
if (!isvalidchar(*s))
{
source.Reply(HOST_SET_IDENT_ERROR);
return MOD_CONT;
}
}
if (host.length() > Config->HostLen)
{
source.Reply(_(HOST_SET_TOOLONG), Config->HostLen);
return MOD_CONT;
}
if (!isValidHost(host, 3))
{
source.Reply(_(HOST_SET_ERROR));
return MOD_CONT;
}
Log(LOG_ADMIN, u, this) << "to set the vhost for all nicks in group " << na->nc->display << " to " << (!user.empty() ? user + "@" : "") << host;
na->hostinfo.SetVhost(user, host, u->nick);
hostserv->Sync(na);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
if (!user.empty())
source.Reply(_("vhost for group \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
else
source.Reply(_("vhost for group \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002SETALL\002 \002<nick>\002 \002<hostmask>\002.\n"
"Sets the vhost for all nicks in the same group as that\n"
"of the given nick. If your IRCD supports vIdents, then\n"
"using SETALL <nick> <ident>@<hostmask> will set idents\n"
"for users as well as vhosts.\n"
"* NOTE, this will not update the vhost for any nicks\n"
"added to the group after this command was used."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SETALL", _("SETALL \002<nick>\002 \002<hostmask>\002."));
}
};
class HSSetAll : public Module
{
CommandHSSetAll commandhssetall;
public:
HSSetAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
{
this->SetAuthor("Anope");
if (!hostserv)
throw ModuleException("HostServ is not loaded!");
this->AddCommand(hostserv->Bot(), &commandhssetall);
}
};
MODULE_INIT(HSSetAll)
-2
View File
@@ -14,8 +14,6 @@ class MemoServService : public Service
MemoServService(Module *m) : Service(m, "MemoServ") { }
virtual BotInfo *Bot() = 0;
/** Retrieve the memo info for a nick or channel
* @param target Target
* @param ischan Set to true if target is a channel
+13 -19
View File
@@ -17,12 +17,13 @@
class CommandMSCancel : public Command
{
public:
CommandMSCancel() : Command("CANCEL", 1, 1)
CommandMSCancel(Module *creator) : Command(creator, "memoserv/cancel", 1, 1)
{
this->SetDesc(_("Cancel last memo you sent"));
this->SetDesc(_("Cancel the last memo you sent"));
this->SetSyntax(_("{\037nick\037 | \037channel\037}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
@@ -32,7 +33,7 @@ class CommandMSCancel : public Command
MemoInfo *mi = memoserv->GetMemoInfo(nname, ischan);
if (mi == NULL)
source.Reply(ischan ? _(CHAN_X_NOT_REGISTERED) : _(NICK_X_NOT_REGISTERED), nname.c_str());
source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), nname.c_str());
else
{
for (int i = mi->memos.size() - 1; i >= 0; --i)
@@ -41,27 +42,22 @@ class CommandMSCancel : public Command
FOREACH_MOD(I_OnMemoDel, OnMemoDel(findnick(nname)->nc, mi, mi->memos[i]));
mi->Del(mi->memos[i]);
source.Reply(_("Last memo to \002%s\002 has been cancelled."), nname.c_str());
return MOD_CONT;
return;
}
source.Reply(_("No memo was cancelable."));
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CANCEL {\037nick\037 | \037channel\037}\002\n"
" \n"
"Cancels the last memo you sent to the given nick or channel,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Cancels the last memo you sent to the given nick or channel,\n"
"provided it has not been read at the time you use the command."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CANCEL", _("CANCEL {\037nick\037 | \037channel\037}"));
}
};
class MSCancel : public Module
@@ -69,14 +65,12 @@ class MSCancel : public Module
CommandMSCancel commandmscancel;
public:
MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandmscancel(this)
{
this->SetAuthor("Anope");
if (!memoserv)
throw ModuleException("MemoServ is not loaded!");
this->AddCommand(memoserv->Bot(), &commandmscancel);
ModuleManager::RegisterService(&commandmscancel);
}
};
+12 -19
View File
@@ -12,17 +12,17 @@
/*************************************************************************/
#include "module.h"
#include "memoserv.h"
class CommandMSCheck : public Command
{
public:
CommandMSCheck() : Command("CHECK", 1, 1)
CommandMSCheck(Module *creator) : Command(creator, "memoserv/check", 1, 1)
{
this->SetDesc(_("Checks if last memo to a nick was read"));
this->SetSyntax(_("\037nick\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
@@ -33,8 +33,8 @@ class CommandMSCheck : public Command
NickAlias *na = findnick(recipient);
if (!na)
{
source.Reply(_(NICK_X_NOT_REGISTERED), recipient.c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_REGISTERED, recipient.c_str());
return;
}
MemoInfo *mi = &na->nc->memos;
@@ -59,22 +59,17 @@ class CommandMSCheck : public Command
if (!found)
source.Reply(_("Nick %s doesn't have a memo from you."), na->nick.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CHECK \037nick\037\002\n"
" \n"
"Checks whether the _last_ memo you sent to \037nick\037 has been read\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Checks whether the _last_ memo you sent to \037nick\037 has been read\n"
"or not. Note that this does only work with nicks, not with chans."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CHECK", _("CHECK \037nickname\037"));
}
};
class MSCheck : public Module
@@ -82,14 +77,12 @@ class MSCheck : public Module
CommandMSCheck commandmscheck;
public:
MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandmscheck(this)
{
this->SetAuthor("Anope");
if (!memoserv)
throw ModuleException("MemoServ is not loaded!");
this->AddCommand(memoserv->Bot(), &commandmscheck);
ModuleManager::RegisterService(&commandmscheck);
}
};
+18 -25
View File
@@ -12,7 +12,6 @@
/*************************************************************************/
#include "module.h"
#include "memoserv.h"
class MemoDelCallback : public NumberList
{
@@ -42,12 +41,13 @@ class MemoDelCallback : public NumberList
class CommandMSDel : public Command
{
public:
CommandMSDel() : Command("DEL", 0, 2)
CommandMSDel(Module *creator) : Command(creator, "memoserv/del", 0, 2)
{
this->SetDesc(_("Delete a memo or memos"));
this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | ALL}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
@@ -62,18 +62,18 @@ class CommandMSDel : public Command
if (!(ci = cs_findchan(chan)))
{
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
else if (readonly)
{
source.Reply(_(READ_ONLY_MODE));
return MOD_CONT;
source.Reply(READ_ONLY_MODE);
return;
}
else if (!check_access(u, ci, CA_MEMO))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
mi = &ci->memos;
}
@@ -84,9 +84,9 @@ class CommandMSDel : public Command
else if (mi->memos.empty())
{
if (!chan.empty())
source.Reply(_(MEMO_X_HAS_NO_MEMOS), chan.c_str());
source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
else
source.Reply(_(MEMO_HAVE_NO_MEMOS));
source.Reply(MEMO_HAVE_NO_MEMOS);
}
else
{
@@ -121,14 +121,14 @@ class CommandMSDel : public Command
source.Reply(_("All of your memos have been deleted."));
}
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEL [\037channel\037] {\037num\037 | \037list\037 | LAST | ALL}\002\n"
" \n"
"Deletes the specified memo or memos. You can supply\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deletes the specified memo or memos. You can supply\n"
"multiple memo numbers or ranges of numbers instead of a\n"
"single number, as in the second example below.\n"
" \n"
@@ -144,11 +144,6 @@ class CommandMSDel : public Command
" Deletes memos numbered 2 through 5 and 7 through 9."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEL", _("DEL [\037channel\037] {\037num\037 | \037list\037 | ALL}"));
}
};
class MSDel : public Module
@@ -156,14 +151,12 @@ class MSDel : public Module
CommandMSDel commandmsdel;
public:
MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE)
MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandmsdel(this)
{
this->SetAuthor("Anope");
if (!memoserv)
throw ModuleException("MemoServ is not loaded!");
this->AddCommand(memoserv->Bot(), &commandmsdel);
ModuleManager::RegisterService(&commandmsdel);
}
};

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