From 484160eb4ed560eeda97c94a42dd8e31431ab251 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 24 Jan 2024 12:34:03 +0000 Subject: Shuffle modules around a bit. --- modules/botserv/botserv.cpp | 213 +++++ modules/botserv/bs_assign.cpp | 260 ++++++ modules/botserv/bs_autoassign.cpp | 37 + modules/botserv/bs_badwords.cpp | 476 +++++++++++ modules/botserv/bs_bot.cpp | 387 +++++++++ modules/botserv/bs_botlist.cpp | 82 ++ modules/botserv/bs_control.cpp | 149 ++++ modules/botserv/bs_info.cpp | 134 +++ modules/botserv/bs_kick.cpp | 1491 +++++++++++++++++++++++++++++++++ modules/botserv/bs_set.cpp | 231 +++++ modules/bs_autoassign.cpp | 37 - modules/chanserv/chanserv.cpp | 481 +++++++++++ modules/chanserv/cs_access.cpp | 939 +++++++++++++++++++++ modules/chanserv/cs_akick.cpp | 585 +++++++++++++ modules/chanserv/cs_ban.cpp | 254 ++++++ modules/chanserv/cs_clone.cpp | 262 ++++++ modules/chanserv/cs_drop.cpp | 97 +++ modules/chanserv/cs_enforce.cpp | 279 ++++++ modules/chanserv/cs_entrymsg.cpp | 294 +++++++ modules/chanserv/cs_fantasy_stats.cpp | 180 ++++ modules/chanserv/cs_fantasy_top.cpp | 194 +++++ modules/chanserv/cs_flags.cpp | 518 ++++++++++++ modules/chanserv/cs_getkey.cpp | 75 ++ modules/chanserv/cs_info.cpp | 100 +++ modules/chanserv/cs_invite.cpp | 113 +++ modules/chanserv/cs_kick.cpp | 149 ++++ modules/chanserv/cs_list.cpp | 267 ++++++ modules/chanserv/cs_log.cpp | 404 +++++++++ modules/chanserv/cs_mode.cpp | 1066 +++++++++++++++++++++++ modules/chanserv/cs_register.cpp | 126 +++ modules/chanserv/cs_seen.cpp | 461 ++++++++++ modules/chanserv/cs_set.cpp | 1326 +++++++++++++++++++++++++++++ modules/chanserv/cs_set_misc.cpp | 222 +++++ modules/chanserv/cs_status.cpp | 125 +++ modules/chanserv/cs_statusupdate.cpp | 68 ++ modules/chanserv/cs_suspend.cpp | 296 +++++++ modules/chanserv/cs_sync.cpp | 68 ++ modules/chanserv/cs_topic.cpp | 273 ++++++ modules/chanserv/cs_unban.cpp | 132 +++ modules/chanserv/cs_updown.cpp | 245 ++++++ modules/chanserv/cs_xop.cpp | 651 ++++++++++++++ modules/chanstats.cpp | 660 +++++++++++++++ modules/commands/bs_assign.cpp | 260 ------ modules/commands/bs_badwords.cpp | 476 ----------- modules/commands/bs_bot.cpp | 387 --------- modules/commands/bs_botlist.cpp | 82 -- modules/commands/bs_control.cpp | 149 ---- modules/commands/bs_info.cpp | 134 --- modules/commands/bs_kick.cpp | 1491 --------------------------------- modules/commands/bs_set.cpp | 231 ----- modules/commands/cs_access.cpp | 939 --------------------- modules/commands/cs_akick.cpp | 585 ------------- modules/commands/cs_ban.cpp | 254 ------ modules/commands/cs_clone.cpp | 262 ------ modules/commands/cs_drop.cpp | 97 --- modules/commands/cs_enforce.cpp | 279 ------ modules/commands/cs_entrymsg.cpp | 294 ------- modules/commands/cs_flags.cpp | 518 ------------ modules/commands/cs_getkey.cpp | 75 -- modules/commands/cs_info.cpp | 100 --- modules/commands/cs_invite.cpp | 113 --- modules/commands/cs_kick.cpp | 149 ---- modules/commands/cs_list.cpp | 267 ------ modules/commands/cs_log.cpp | 404 --------- modules/commands/cs_mode.cpp | 1066 ----------------------- modules/commands/cs_register.cpp | 126 --- modules/commands/cs_seen.cpp | 461 ---------- modules/commands/cs_set.cpp | 1326 ----------------------------- modules/commands/cs_set_misc.cpp | 222 ----- modules/commands/cs_status.cpp | 125 --- modules/commands/cs_suspend.cpp | 296 ------- modules/commands/cs_sync.cpp | 68 -- modules/commands/cs_topic.cpp | 273 ------ modules/commands/cs_unban.cpp | 132 --- modules/commands/cs_updown.cpp | 245 ------ modules/commands/cs_xop.cpp | 651 -------------- modules/commands/gl_global.cpp | 68 -- modules/commands/greet.cpp | 220 ----- modules/commands/help.cpp | 199 ----- modules/commands/hs_del.cpp | 116 --- modules/commands/hs_group.cpp | 118 --- modules/commands/hs_list.cpp | 160 ---- modules/commands/hs_off.cpp | 71 -- modules/commands/hs_on.cpp | 77 -- modules/commands/hs_request.cpp | 399 --------- modules/commands/hs_set.cpp | 231 ----- modules/commands/ms_cancel.cpp | 103 --- modules/commands/ms_check.cpp | 89 -- modules/commands/ms_del.cpp | 162 ---- modules/commands/ms_ignore.cpp | 134 --- modules/commands/ms_info.cpp | 235 ------ modules/commands/ms_list.cpp | 167 ---- modules/commands/ms_read.cpp | 227 ----- modules/commands/ms_rsend.cpp | 106 --- modules/commands/ms_send.cpp | 90 -- modules/commands/ms_sendall.cpp | 70 -- modules/commands/ms_set.cpp | 317 ------- modules/commands/ms_staff.cpp | 67 -- modules/commands/ns_access.cpp | 208 ----- modules/commands/ns_ajoin.cpp | 408 --------- modules/commands/ns_alist.cpp | 148 ---- modules/commands/ns_cert.cpp | 412 --------- modules/commands/ns_drop.cpp | 88 -- modules/commands/ns_getemail.cpp | 74 -- modules/commands/ns_group.cpp | 399 --------- modules/commands/ns_identify.cpp | 131 --- modules/commands/ns_info.cpp | 287 ------- modules/commands/ns_list.cpp | 303 ------- modules/commands/ns_logout.cpp | 93 -- modules/commands/ns_recover.cpp | 301 ------- modules/commands/ns_register.cpp | 445 ---------- modules/commands/ns_resetpass.cpp | 146 ---- modules/commands/ns_set.cpp | 1464 -------------------------------- modules/commands/ns_set_misc.cpp | 238 ------ modules/commands/ns_status.cpp | 89 -- modules/commands/ns_suspend.cpp | 291 ------- modules/commands/ns_update.cpp | 64 -- modules/commands/os_akill.cpp | 487 ----------- modules/commands/os_chankill.cpp | 119 --- modules/commands/os_config.cpp | 149 ---- modules/commands/os_defcon.cpp | 603 ------------- modules/commands/os_dns.cpp | 944 --------------------- modules/commands/os_forbid.cpp | 573 ------------- modules/commands/os_ignore.cpp | 421 ---------- modules/commands/os_info.cpp | 291 ------- modules/commands/os_jupe.cpp | 82 -- modules/commands/os_kick.cpp | 86 -- modules/commands/os_kill.cpp | 69 -- modules/commands/os_list.cpp | 289 ------- modules/commands/os_login.cpp | 135 --- modules/commands/os_logsearch.cpp | 187 ----- modules/commands/os_mode.cpp | 192 ----- modules/commands/os_modinfo.cpp | 211 ----- modules/commands/os_module.cpp | 192 ----- modules/commands/os_news.cpp | 478 ----------- modules/commands/os_noop.cpp | 100 --- modules/commands/os_oper.cpp | 292 ------- modules/commands/os_reload.cpp | 69 -- modules/commands/os_session.cpp | 738 ---------------- modules/commands/os_set.cpp | 269 ------ modules/commands/os_shutdown.cpp | 112 --- modules/commands/os_stats.cpp | 281 ------- modules/commands/os_svs.cpp | 182 ---- modules/commands/os_sxline.cpp | 731 ---------------- modules/commands/os_update.cpp | 54 -- modules/cs_statusupdate.cpp | 68 -- modules/global/gl_global.cpp | 68 ++ modules/global/global.cpp | 102 +++ modules/greet.cpp | 220 +++++ modules/help.cpp | 199 +++++ modules/hostserv/hostserv.cpp | 131 +++ modules/hostserv/hs_del.cpp | 116 +++ modules/hostserv/hs_group.cpp | 118 +++ modules/hostserv/hs_list.cpp | 160 ++++ modules/hostserv/hs_off.cpp | 71 ++ modules/hostserv/hs_on.cpp | 77 ++ modules/hostserv/hs_request.cpp | 399 +++++++++ modules/hostserv/hs_set.cpp | 231 +++++ modules/irc2sql/CMakeLists.txt | 1 + modules/irc2sql/irc2sql.cpp | 326 +++++++ modules/irc2sql/irc2sql.h | 88 ++ modules/irc2sql/tables.cpp | 343 ++++++++ modules/irc2sql/utils.cpp | 68 ++ modules/memoserv/memoserv.cpp | 237 ++++++ modules/memoserv/ms_cancel.cpp | 103 +++ modules/memoserv/ms_check.cpp | 89 ++ modules/memoserv/ms_del.cpp | 162 ++++ modules/memoserv/ms_ignore.cpp | 134 +++ modules/memoserv/ms_info.cpp | 235 ++++++ modules/memoserv/ms_list.cpp | 167 ++++ modules/memoserv/ms_read.cpp | 227 +++++ modules/memoserv/ms_rsend.cpp | 106 +++ modules/memoserv/ms_send.cpp | 90 ++ modules/memoserv/ms_sendall.cpp | 70 ++ modules/memoserv/ms_set.cpp | 317 +++++++ modules/memoserv/ms_staff.cpp | 67 ++ modules/nickserv/nickserv.cpp | 569 +++++++++++++ modules/nickserv/ns_access.cpp | 208 +++++ modules/nickserv/ns_ajoin.cpp | 408 +++++++++ modules/nickserv/ns_alist.cpp | 148 ++++ modules/nickserv/ns_cert.cpp | 412 +++++++++ modules/nickserv/ns_drop.cpp | 88 ++ modules/nickserv/ns_getemail.cpp | 74 ++ modules/nickserv/ns_group.cpp | 399 +++++++++ modules/nickserv/ns_identify.cpp | 131 +++ modules/nickserv/ns_info.cpp | 287 +++++++ modules/nickserv/ns_list.cpp | 303 +++++++ modules/nickserv/ns_logout.cpp | 93 ++ modules/nickserv/ns_maxemail.cpp | 112 +++ modules/nickserv/ns_recover.cpp | 301 +++++++ modules/nickserv/ns_register.cpp | 445 ++++++++++ modules/nickserv/ns_resetpass.cpp | 146 ++++ modules/nickserv/ns_set.cpp | 1464 ++++++++++++++++++++++++++++++++ modules/nickserv/ns_set_misc.cpp | 238 ++++++ modules/nickserv/ns_status.cpp | 89 ++ modules/nickserv/ns_suspend.cpp | 291 +++++++ modules/nickserv/ns_update.cpp | 64 ++ modules/ns_maxemail.cpp | 112 --- modules/operserv/operserv.cpp | 300 +++++++ modules/operserv/os_akill.cpp | 487 +++++++++++ modules/operserv/os_chankill.cpp | 119 +++ modules/operserv/os_config.cpp | 149 ++++ modules/operserv/os_defcon.cpp | 603 +++++++++++++ modules/operserv/os_dns.cpp | 944 +++++++++++++++++++++ modules/operserv/os_forbid.cpp | 573 +++++++++++++ modules/operserv/os_ignore.cpp | 421 ++++++++++ modules/operserv/os_info.cpp | 291 +++++++ modules/operserv/os_jupe.cpp | 82 ++ modules/operserv/os_kick.cpp | 86 ++ modules/operserv/os_kill.cpp | 69 ++ modules/operserv/os_list.cpp | 289 +++++++ modules/operserv/os_login.cpp | 135 +++ modules/operserv/os_logsearch.cpp | 187 +++++ modules/operserv/os_mode.cpp | 192 +++++ modules/operserv/os_modinfo.cpp | 211 +++++ modules/operserv/os_module.cpp | 192 +++++ modules/operserv/os_news.cpp | 478 +++++++++++ modules/operserv/os_noop.cpp | 100 +++ modules/operserv/os_oper.cpp | 292 +++++++ modules/operserv/os_reload.cpp | 69 ++ modules/operserv/os_session.cpp | 738 ++++++++++++++++ modules/operserv/os_set.cpp | 269 ++++++ modules/operserv/os_shutdown.cpp | 112 +++ modules/operserv/os_stats.cpp | 281 +++++++ modules/operserv/os_svs.cpp | 182 ++++ modules/operserv/os_sxline.cpp | 731 ++++++++++++++++ modules/operserv/os_update.cpp | 54 ++ modules/pseudoclients/botserv.cpp | 213 ----- modules/pseudoclients/chanserv.cpp | 481 ----------- modules/pseudoclients/global.cpp | 102 --- modules/pseudoclients/hostserv.cpp | 131 --- modules/pseudoclients/memoserv.cpp | 237 ------ modules/pseudoclients/nickserv.cpp | 569 ------------- modules/pseudoclients/operserv.cpp | 300 ------- modules/stats/chanstats.cpp | 660 --------------- modules/stats/cs_fantasy_stats.cpp | 180 ---- modules/stats/cs_fantasy_top.cpp | 194 ----- modules/stats/irc2sql/CMakeLists.txt | 1 - modules/stats/irc2sql/irc2sql.cpp | 326 ------- modules/stats/irc2sql/irc2sql.h | 88 -- modules/stats/irc2sql/tables.cpp | 343 -------- modules/stats/irc2sql/utils.cpp | 68 -- 242 files changed, 33998 insertions(+), 33998 deletions(-) create mode 100644 modules/botserv/botserv.cpp create mode 100644 modules/botserv/bs_assign.cpp create mode 100644 modules/botserv/bs_autoassign.cpp create mode 100644 modules/botserv/bs_badwords.cpp create mode 100644 modules/botserv/bs_bot.cpp create mode 100644 modules/botserv/bs_botlist.cpp create mode 100644 modules/botserv/bs_control.cpp create mode 100644 modules/botserv/bs_info.cpp create mode 100644 modules/botserv/bs_kick.cpp create mode 100644 modules/botserv/bs_set.cpp delete mode 100644 modules/bs_autoassign.cpp create mode 100644 modules/chanserv/chanserv.cpp create mode 100644 modules/chanserv/cs_access.cpp create mode 100644 modules/chanserv/cs_akick.cpp create mode 100644 modules/chanserv/cs_ban.cpp create mode 100644 modules/chanserv/cs_clone.cpp create mode 100644 modules/chanserv/cs_drop.cpp create mode 100644 modules/chanserv/cs_enforce.cpp create mode 100644 modules/chanserv/cs_entrymsg.cpp create mode 100644 modules/chanserv/cs_fantasy_stats.cpp create mode 100644 modules/chanserv/cs_fantasy_top.cpp create mode 100644 modules/chanserv/cs_flags.cpp create mode 100644 modules/chanserv/cs_getkey.cpp create mode 100644 modules/chanserv/cs_info.cpp create mode 100644 modules/chanserv/cs_invite.cpp create mode 100644 modules/chanserv/cs_kick.cpp create mode 100644 modules/chanserv/cs_list.cpp create mode 100644 modules/chanserv/cs_log.cpp create mode 100644 modules/chanserv/cs_mode.cpp create mode 100644 modules/chanserv/cs_register.cpp create mode 100644 modules/chanserv/cs_seen.cpp create mode 100644 modules/chanserv/cs_set.cpp create mode 100644 modules/chanserv/cs_set_misc.cpp create mode 100644 modules/chanserv/cs_status.cpp create mode 100644 modules/chanserv/cs_statusupdate.cpp create mode 100644 modules/chanserv/cs_suspend.cpp create mode 100644 modules/chanserv/cs_sync.cpp create mode 100644 modules/chanserv/cs_topic.cpp create mode 100644 modules/chanserv/cs_unban.cpp create mode 100644 modules/chanserv/cs_updown.cpp create mode 100644 modules/chanserv/cs_xop.cpp create mode 100644 modules/chanstats.cpp delete mode 100644 modules/commands/bs_assign.cpp delete mode 100644 modules/commands/bs_badwords.cpp delete mode 100644 modules/commands/bs_bot.cpp delete mode 100644 modules/commands/bs_botlist.cpp delete mode 100644 modules/commands/bs_control.cpp delete mode 100644 modules/commands/bs_info.cpp delete mode 100644 modules/commands/bs_kick.cpp delete mode 100644 modules/commands/bs_set.cpp delete mode 100644 modules/commands/cs_access.cpp delete mode 100644 modules/commands/cs_akick.cpp delete mode 100644 modules/commands/cs_ban.cpp delete mode 100644 modules/commands/cs_clone.cpp delete mode 100644 modules/commands/cs_drop.cpp delete mode 100644 modules/commands/cs_enforce.cpp delete mode 100644 modules/commands/cs_entrymsg.cpp delete mode 100644 modules/commands/cs_flags.cpp delete mode 100644 modules/commands/cs_getkey.cpp delete mode 100644 modules/commands/cs_info.cpp delete mode 100644 modules/commands/cs_invite.cpp delete mode 100644 modules/commands/cs_kick.cpp delete mode 100644 modules/commands/cs_list.cpp delete mode 100644 modules/commands/cs_log.cpp delete mode 100644 modules/commands/cs_mode.cpp delete mode 100644 modules/commands/cs_register.cpp delete mode 100644 modules/commands/cs_seen.cpp delete mode 100644 modules/commands/cs_set.cpp delete mode 100644 modules/commands/cs_set_misc.cpp delete mode 100644 modules/commands/cs_status.cpp delete mode 100644 modules/commands/cs_suspend.cpp delete mode 100644 modules/commands/cs_sync.cpp delete mode 100644 modules/commands/cs_topic.cpp delete mode 100644 modules/commands/cs_unban.cpp delete mode 100644 modules/commands/cs_updown.cpp delete mode 100644 modules/commands/cs_xop.cpp delete mode 100644 modules/commands/gl_global.cpp delete mode 100644 modules/commands/greet.cpp delete mode 100644 modules/commands/help.cpp delete mode 100644 modules/commands/hs_del.cpp delete mode 100644 modules/commands/hs_group.cpp delete mode 100644 modules/commands/hs_list.cpp delete mode 100644 modules/commands/hs_off.cpp delete mode 100644 modules/commands/hs_on.cpp delete mode 100644 modules/commands/hs_request.cpp delete mode 100644 modules/commands/hs_set.cpp delete mode 100644 modules/commands/ms_cancel.cpp delete mode 100644 modules/commands/ms_check.cpp delete mode 100644 modules/commands/ms_del.cpp delete mode 100644 modules/commands/ms_ignore.cpp delete mode 100644 modules/commands/ms_info.cpp delete mode 100644 modules/commands/ms_list.cpp delete mode 100644 modules/commands/ms_read.cpp delete mode 100644 modules/commands/ms_rsend.cpp delete mode 100644 modules/commands/ms_send.cpp delete mode 100644 modules/commands/ms_sendall.cpp delete mode 100644 modules/commands/ms_set.cpp delete mode 100644 modules/commands/ms_staff.cpp delete mode 100644 modules/commands/ns_access.cpp delete mode 100644 modules/commands/ns_ajoin.cpp delete mode 100644 modules/commands/ns_alist.cpp delete mode 100644 modules/commands/ns_cert.cpp delete mode 100644 modules/commands/ns_drop.cpp delete mode 100644 modules/commands/ns_getemail.cpp delete mode 100644 modules/commands/ns_group.cpp delete mode 100644 modules/commands/ns_identify.cpp delete mode 100644 modules/commands/ns_info.cpp delete mode 100644 modules/commands/ns_list.cpp delete mode 100644 modules/commands/ns_logout.cpp delete mode 100644 modules/commands/ns_recover.cpp delete mode 100644 modules/commands/ns_register.cpp delete mode 100644 modules/commands/ns_resetpass.cpp delete mode 100644 modules/commands/ns_set.cpp delete mode 100644 modules/commands/ns_set_misc.cpp delete mode 100644 modules/commands/ns_status.cpp delete mode 100644 modules/commands/ns_suspend.cpp delete mode 100644 modules/commands/ns_update.cpp delete mode 100644 modules/commands/os_akill.cpp delete mode 100644 modules/commands/os_chankill.cpp delete mode 100644 modules/commands/os_config.cpp delete mode 100644 modules/commands/os_defcon.cpp delete mode 100644 modules/commands/os_dns.cpp delete mode 100644 modules/commands/os_forbid.cpp delete mode 100644 modules/commands/os_ignore.cpp delete mode 100644 modules/commands/os_info.cpp delete mode 100644 modules/commands/os_jupe.cpp delete mode 100644 modules/commands/os_kick.cpp delete mode 100644 modules/commands/os_kill.cpp delete mode 100644 modules/commands/os_list.cpp delete mode 100644 modules/commands/os_login.cpp delete mode 100644 modules/commands/os_logsearch.cpp delete mode 100644 modules/commands/os_mode.cpp delete mode 100644 modules/commands/os_modinfo.cpp delete mode 100644 modules/commands/os_module.cpp delete mode 100644 modules/commands/os_news.cpp delete mode 100644 modules/commands/os_noop.cpp delete mode 100644 modules/commands/os_oper.cpp delete mode 100644 modules/commands/os_reload.cpp delete mode 100644 modules/commands/os_session.cpp delete mode 100644 modules/commands/os_set.cpp delete mode 100644 modules/commands/os_shutdown.cpp delete mode 100644 modules/commands/os_stats.cpp delete mode 100644 modules/commands/os_svs.cpp delete mode 100644 modules/commands/os_sxline.cpp delete mode 100644 modules/commands/os_update.cpp delete mode 100644 modules/cs_statusupdate.cpp create mode 100644 modules/global/gl_global.cpp create mode 100644 modules/global/global.cpp create mode 100644 modules/greet.cpp create mode 100644 modules/help.cpp create mode 100644 modules/hostserv/hostserv.cpp create mode 100644 modules/hostserv/hs_del.cpp create mode 100644 modules/hostserv/hs_group.cpp create mode 100644 modules/hostserv/hs_list.cpp create mode 100644 modules/hostserv/hs_off.cpp create mode 100644 modules/hostserv/hs_on.cpp create mode 100644 modules/hostserv/hs_request.cpp create mode 100644 modules/hostserv/hs_set.cpp create mode 100644 modules/irc2sql/CMakeLists.txt create mode 100644 modules/irc2sql/irc2sql.cpp create mode 100644 modules/irc2sql/irc2sql.h create mode 100644 modules/irc2sql/tables.cpp create mode 100644 modules/irc2sql/utils.cpp create mode 100644 modules/memoserv/memoserv.cpp create mode 100644 modules/memoserv/ms_cancel.cpp create mode 100644 modules/memoserv/ms_check.cpp create mode 100644 modules/memoserv/ms_del.cpp create mode 100644 modules/memoserv/ms_ignore.cpp create mode 100644 modules/memoserv/ms_info.cpp create mode 100644 modules/memoserv/ms_list.cpp create mode 100644 modules/memoserv/ms_read.cpp create mode 100644 modules/memoserv/ms_rsend.cpp create mode 100644 modules/memoserv/ms_send.cpp create mode 100644 modules/memoserv/ms_sendall.cpp create mode 100644 modules/memoserv/ms_set.cpp create mode 100644 modules/memoserv/ms_staff.cpp create mode 100644 modules/nickserv/nickserv.cpp create mode 100644 modules/nickserv/ns_access.cpp create mode 100644 modules/nickserv/ns_ajoin.cpp create mode 100644 modules/nickserv/ns_alist.cpp create mode 100644 modules/nickserv/ns_cert.cpp create mode 100644 modules/nickserv/ns_drop.cpp create mode 100644 modules/nickserv/ns_getemail.cpp create mode 100644 modules/nickserv/ns_group.cpp create mode 100644 modules/nickserv/ns_identify.cpp create mode 100644 modules/nickserv/ns_info.cpp create mode 100644 modules/nickserv/ns_list.cpp create mode 100644 modules/nickserv/ns_logout.cpp create mode 100644 modules/nickserv/ns_maxemail.cpp create mode 100644 modules/nickserv/ns_recover.cpp create mode 100644 modules/nickserv/ns_register.cpp create mode 100644 modules/nickserv/ns_resetpass.cpp create mode 100644 modules/nickserv/ns_set.cpp create mode 100644 modules/nickserv/ns_set_misc.cpp create mode 100644 modules/nickserv/ns_status.cpp create mode 100644 modules/nickserv/ns_suspend.cpp create mode 100644 modules/nickserv/ns_update.cpp delete mode 100644 modules/ns_maxemail.cpp create mode 100644 modules/operserv/operserv.cpp create mode 100644 modules/operserv/os_akill.cpp create mode 100644 modules/operserv/os_chankill.cpp create mode 100644 modules/operserv/os_config.cpp create mode 100644 modules/operserv/os_defcon.cpp create mode 100644 modules/operserv/os_dns.cpp create mode 100644 modules/operserv/os_forbid.cpp create mode 100644 modules/operserv/os_ignore.cpp create mode 100644 modules/operserv/os_info.cpp create mode 100644 modules/operserv/os_jupe.cpp create mode 100644 modules/operserv/os_kick.cpp create mode 100644 modules/operserv/os_kill.cpp create mode 100644 modules/operserv/os_list.cpp create mode 100644 modules/operserv/os_login.cpp create mode 100644 modules/operserv/os_logsearch.cpp create mode 100644 modules/operserv/os_mode.cpp create mode 100644 modules/operserv/os_modinfo.cpp create mode 100644 modules/operserv/os_module.cpp create mode 100644 modules/operserv/os_news.cpp create mode 100644 modules/operserv/os_noop.cpp create mode 100644 modules/operserv/os_oper.cpp create mode 100644 modules/operserv/os_reload.cpp create mode 100644 modules/operserv/os_session.cpp create mode 100644 modules/operserv/os_set.cpp create mode 100644 modules/operserv/os_shutdown.cpp create mode 100644 modules/operserv/os_stats.cpp create mode 100644 modules/operserv/os_svs.cpp create mode 100644 modules/operserv/os_sxline.cpp create mode 100644 modules/operserv/os_update.cpp delete mode 100644 modules/pseudoclients/botserv.cpp delete mode 100644 modules/pseudoclients/chanserv.cpp delete mode 100644 modules/pseudoclients/global.cpp delete mode 100644 modules/pseudoclients/hostserv.cpp delete mode 100644 modules/pseudoclients/memoserv.cpp delete mode 100644 modules/pseudoclients/nickserv.cpp delete mode 100644 modules/pseudoclients/operserv.cpp delete mode 100644 modules/stats/chanstats.cpp delete mode 100644 modules/stats/cs_fantasy_stats.cpp delete mode 100644 modules/stats/cs_fantasy_top.cpp delete mode 100644 modules/stats/irc2sql/CMakeLists.txt delete mode 100644 modules/stats/irc2sql/irc2sql.cpp delete mode 100644 modules/stats/irc2sql/irc2sql.h delete mode 100644 modules/stats/irc2sql/tables.cpp delete mode 100644 modules/stats/irc2sql/utils.cpp (limited to 'modules') diff --git a/modules/botserv/botserv.cpp b/modules/botserv/botserv.cpp new file mode 100644 index 000000000..d2b8df4bb --- /dev/null +++ b/modules/botserv/botserv.cpp @@ -0,0 +1,213 @@ +/* BotServ core functions + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "module.h" + +class BotServCore final + : public Module +{ + Reference BotServ; + ExtensibleRef persist, inhabit; + +public: + BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), + persist("PERSIST"), inhabit("inhabit") + { + } + + void OnReload(Configuration::Conf *conf) override + { + const Anope::string &bsnick = conf->GetModule(this)->Get("client"); + BotServ = BotInfo::Find(bsnick, true); + } + + void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) override + { + /* Do not allow removing bot modes on our service bots */ + if (chan->ci && chan->ci->bi == user) + { + const Anope::string &botmodes = Config->GetModule(this)->Get("botmodes"); + for (auto botmode : botmodes) + chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmode), chan->ci->bi->GetUID()); + } + } + + void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) override + { + if (ci->c && ci->c->users.size() >= Config->GetModule(this)->Get("minusers")) + { + ChannelStatus status(Config->GetModule(this)->Get("botmodes")); + bi->Join(ci->c, &status); + } + } + + void OnJoinChannel(User *user, Channel *c) override + { + if (!Config || !IRCD) + return; + + BotInfo *bi = user->server == Me ? dynamic_cast(user) : NULL; + if (bi && Config->GetModule(this)->Get("smartjoin")) + { + /* We check for bans */ + for (const auto &entry : c->GetModeList("BAN")) + { + Entry ban("BAN", entry); + if (ban.Matches(user)) + c->RemoveMode(NULL, "BAN", ban.GetMask()); + } + + Anope::string Limit; + unsigned limit = 0; + try + { + if (c->GetParam("LIMIT", Limit)) + limit = convertTo(Limit); + } + catch (const ConvertException &) { } + + /* Should we be invited? */ + if (c->HasMode("INVITE") || (limit && c->users.size() >= limit)) + { + ChannelMode *cm = ModeManager::FindChannelModeByName("OP"); + char symbol = cm ? anope_dynamic_static_cast(cm)->symbol : 0; + IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str()); + } + + ModeManager::ProcessModes(); + } + + if (user->server != Me && 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 doesn't just leave, the bot will never + * make it into the channel, leaving the channel botless even for + * legit users - Rob + **/ + /* This is before the user has joined the channel, so check usercount + 1 */ + if (c->users.size() + 1 >= Config->GetModule(this)->Get("minusers") && !c->FindUser(c->ci->bi)) + { + ChannelStatus status(Config->GetModule(this)->Get("botmodes")); + c->ci->bi->Join(c, &status); + } + } + } + + void OnLeaveChannel(User *u, Channel *c) override + { + /* Channel is persistent, it shouldn't be deleted and the service bot should stay */ + if (c->ci && persist && persist->HasExt(c->ci)) + return; + + /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediately + * We also don't part the bot here either, if necessary we will part it after the sync + */ + if (c->syncing) + return; + + /* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */ + if (inhabit && inhabit->HasExt(c)) + return; + + /* This is called prior to removing the user from the channel, so c->users.size() - 1 should be safe */ + if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->GetModule(this)->Get("minusers") && c->FindUser(c->ci->bi)) + c->ci->bi->Part(c->ci->c); + } + + EventReturn OnPreHelp(CommandSource &source, const std::vector ¶ms) override + { + if (!params.empty()) + return EVENT_CONTINUE; + + if (source.c) + { + source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n" + "Fantasy commands are commands that can be executed from messaging a\n" + "channel, and provide a more convenient way to execute commands. Commands that\n" + "require a channel as a parameter will automatically have that parameter\n" + "given.\n"), source.service->nick.c_str()); + const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get("fantasycharacter", "!"); + if (!fantasycharacters.empty()) + source.Reply(_(" \n" + "Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str()); + source.Reply(_(" \n" + "Available commands are:")); + } + else if (*source.service == BotServ) + { + 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"), + BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), + Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str()); + } + + return EVENT_CONTINUE; + } + + void OnPostHelp(CommandSource &source, const std::vector ¶ms) override + { + if (!params.empty() || source.c || source.service != *BotServ) + return; + + source.Reply(_(" \n" + "Bot will join a channel whenever there is at least\n" + "\002%d\002 user(s) on it."), Config->GetModule(this)->Get("minusers")); + const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get("fantasycharacter", "!"); + if (!fantasycharacters.empty()) + source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n" + "can be executed by prefixing the command name with\n" + "one of the following characters: %s"), fantasycharacters.c_str()); + } + + EventReturn OnChannelModeSet(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string ¶m) override + { + if (source.GetUser() && !source.GetBot() && Config->GetModule(this)->Get("smartjoin") && mode->name == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) + { + BotInfo *bi = c->ci->bi; + + Entry ban("BAN", param); + if (ban.Matches(bi)) + c->RemoveMode(bi, "BAN", param); + } + + return EVENT_CONTINUE; + } + + void OnCreateChan(ChannelInfo *ci) override + { + /* Set default bot flags */ + spacesepstream sep(Config->GetModule(this)->Get("defaults", "greet fantasy")); + for (Anope::string token; sep.GetToken(token);) + ci->Extend("BS_" + token.upper()); + } + + void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) override + { + BotInfo *bi = BotInfo::Find(target->GetUID()); + if (bi) + /* Bots get rejoined */ + bi->Join(channel, &status); + } + + void OnCreateBot(BotInfo *bi) override + { + if (bi->botmodes.empty()) + bi->botmodes = Config->GetModule(this)->Get("botumodes"); + } +}; + +MODULE_INIT(BotServCore) diff --git a/modules/botserv/bs_assign.cpp b/modules/botserv/bs_assign.cpp new file mode 100644 index 000000000..43abdd55f --- /dev/null +++ b/modules/botserv/bs_assign.cpp @@ -0,0 +1,260 @@ +/* BotServ core functions + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "module.h" + +class CommandBSAssign final + : public Command +{ +public: + CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2) + { + this->SetDesc(_("Assigns a bot to a channel")); + this->SetSyntax(_("\037channel\037 \037nick\037")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + const Anope::string &chan = params[0]; + const Anope::string &nick = params[1]; + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot assignment is temporarily disabled.")); + return; + } + + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + BotInfo *bi = BotInfo::Find(nick, true); + if (!bi) + { + source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); + return; + } + + AccessGroup access = source.AccessFor(ci); + if (ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration"))) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (bi->oper_only && !source.HasPriv("botserv/administration")) + { + source.Reply(ACCESS_DENIED); + return; + } + + 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; + } + + bool override = !access.HasPriv("ASSIGN"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << bi->nick; + + bi->Assign(source.GetUser(), ci); + source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str()); + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Assigns the specified bot to a channel. You\n" + "can then configure the bot for the channel so it fits\n" + "your needs.")); + return true; + } +}; + +class CommandBSUnassign final + : public Command +{ +public: + CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1) + { + this->SetDesc(_("Unassigns a bot from a channel")); + this->SetSyntax(_("\037channel\037")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot assignment is temporarily disabled.")); + return; + } + + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + AccessGroup access = source.AccessFor(ci); + if (!source.HasPriv("botserv/administration") && !access.HasPriv("ASSIGN")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (!ci->bi) + { + source.Reply(BOT_NOT_ASSIGNED); + return; + } + + if (ci->HasExt("PERSIST") && !ModeManager::FindChannelModeByName("PERM")) + { + source.Reply(_("You cannot unassign bots while persist is set on the channel.")); + return; + } + + bool override = !access.HasPriv("ASSIGN"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << ci->bi->nick; + + ci->bi->UnAssign(source.GetUser(), ci); + source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str()); + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + 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 having to reconfigure\n" + "it entirely.")); + return true; + } +}; + +class CommandBSSetNoBot final + : public Command +{ +public: + CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("Prevent a bot from being assigned to a channel")); + this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + const Anope::string &value = params[1]; + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot modification is temporarily disabled.")); + return; + } + + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (value.equals_ci("ON")) + { + Log(LOG_ADMIN, source, this, ci) << "to enable nobot"; + + ci->Extend("BS_NOBOT"); + if (ci->bi) + ci->bi->UnAssign(source.GetUser(), ci); + source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str()); + } + else if (value.equals_ci("OFF")) + { + Log(LOG_ADMIN, source, this, ci) << "to disable nobot"; + + ci->Shrink("BS_NOBOT"); + source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "This option makes a channel unassignable. If a bot\n" + "is already assigned to the channel, it is unassigned\n" + "automatically when you enable it.")); + return true; + } +}; + +class BSAssign final + : public Module +{ + ExtensibleItem nobot; + + CommandBSAssign commandbsassign; + CommandBSUnassign commandbsunassign; + CommandBSSetNoBot commandbssetnobot; + +public: + BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + nobot(this, "BS_NOBOT"), + commandbsassign(this), commandbsunassign(this), commandbssetnobot(this) + { + } + + void OnInvite(User *source, Channel *c, User *targ) override + { + BotInfo *bi; + if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = dynamic_cast(targ))) + return; + + AccessGroup access = c->ci->AccessFor(source); + if (nobot.HasExt(c->ci) || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration"))) + { + targ->SendMessage(bi, ACCESS_DENIED); + return; + } + + if (bi->oper_only && !source->HasPriv("botserv/administration")) + { + targ->SendMessage(bi, ACCESS_DENIED); + return; + } + + if (c->ci->bi == bi) + { + targ->SendMessage(bi, _("Bot \002%s\002 is already assigned to channel \002%s\002."), c->ci->bi->nick.c_str(), c->name.c_str()); + return; + } + + bi->Assign(source, c->ci); + targ->SendMessage(bi, _("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), c->name.c_str()); + } + + void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) override + { + if (nobot.HasExt(ci)) + info.AddOption(_("No bot")); + } +}; + +MODULE_INIT(BSAssign) diff --git a/modules/botserv/bs_autoassign.cpp b/modules/botserv/bs_autoassign.cpp new file mode 100644 index 000000000..a716525f9 --- /dev/null +++ b/modules/botserv/bs_autoassign.cpp @@ -0,0 +1,37 @@ +/* + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + */ + +#include "module.h" + +class BSAutoAssign final + : public Module +{ +public: + BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + { + } + + void OnChanRegistered(ChannelInfo *ci) override + { + const Anope::string &bot = Config->GetModule(this)->Get("bot"); + if (bot.empty()) + return; + + BotInfo *bi = BotInfo::Find(bot, true); + if (bi == NULL) + { + Log(this) << "bs_autoassign is configured to assign bot " << bot << ", but it does not exist?"; + return; + } + + bi->Assign(NULL, ci); + } +}; + +MODULE_INIT(BSAutoAssign) diff --git a/modules/botserv/bs_badwords.cpp b/modules/botserv/bs_badwords.cpp new file mode 100644 index 000000000..e513170e7 --- /dev/null +++ b/modules/botserv/bs_badwords.cpp @@ -0,0 +1,476 @@ +/* BotServ core functions + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "module.h" +#include "modules/bs_badwords.h" + +struct BadWordImpl final + : BadWord + , Serializable +{ + BadWordImpl() : Serializable("BadWord") { } + ~BadWordImpl() override; + + void Serialize(Serialize::Data &data) const override + { + data["ci"] << this->chan; + data["word"] << this->word; + data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type; + } + + static Serializable* Unserialize(Serializable *obj, Serialize::Data &); +}; + +struct BadWordsImpl final + : BadWords +{ + Serialize::Reference ci; + typedef std::vector list; + Serialize::Checker badwords; + + BadWordsImpl(Extensible *obj) : ci(anope_dynamic_static_cast(obj)), badwords("BadWord") { } + + ~BadWordsImpl() override; + + BadWord* AddBadWord(const Anope::string &word, BadWordType type) override + { + auto *bw = new BadWordImpl(); + bw->chan = ci->name; + bw->word = word; + bw->type = type; + + this->badwords->push_back(bw); + + FOREACH_MOD(OnBadWordAdd, (ci, bw)); + + return bw; + } + + BadWord* GetBadWord(unsigned index) const override + { + if (this->badwords->empty() || index >= this->badwords->size()) + return NULL; + + BadWordImpl *bw = (*this->badwords)[index]; + bw->QueueUpdate(); + return bw; + } + + unsigned GetBadWordCount() const override + { + return this->badwords->size(); + } + + void EraseBadWord(unsigned index) override + { + if (this->badwords->empty() || index >= this->badwords->size()) + return; + + FOREACH_MOD(OnBadWordDel, (ci, (*this->badwords)[index])); + + delete this->badwords->at(index); + } + + void ClearBadWords() override + { + while (!this->badwords->empty()) + delete this->badwords->back(); + } + + void Check() override + { + if (this->badwords->empty()) + ci->Shrink("badwords"); + } +}; + +BadWordsImpl::~BadWordsImpl() +{ + for (list::iterator it = badwords->begin(); it != badwords->end();) + { + BadWord *bw = *it; + ++it; + delete bw; + } +} + +BadWordImpl::~BadWordImpl() +{ + ChannelInfo *ci = ChannelInfo::Find(chan); + if (ci) + { + BadWordsImpl *badwords = ci->GetExt("badwords"); + if (badwords) + { + BadWordsImpl::list::iterator it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this); + if (it != badwords->badwords->end()) + badwords->badwords->erase(it); + } + } +} + +Serializable* BadWordImpl::Unserialize(Serializable *obj, Serialize::Data &data) +{ + Anope::string sci, sword; + + data["ci"] >> sci; + data["word"] >> sword; + + ChannelInfo *ci = ChannelInfo::Find(sci); + if (!ci) + return NULL; + + unsigned int n; + data["type"] >> n; + + BadWordImpl *bw; + if (obj) + bw = anope_dynamic_static_cast(obj); + else + bw = new BadWordImpl(); + bw->chan = sci; + bw->word = sword; + bw->type = static_cast(n); + + BadWordsImpl *bws = ci->Require("badwords"); + if (!obj) + bws->badwords->push_back(bw); + + return bw; +} + +class BadwordsDelCallback final + : public NumberList +{ + CommandSource &source; + ChannelInfo *ci; + BadWords *bw; + Command *c; + unsigned deleted = 0; + bool override = false; +public: + BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c) + { + if (!source.AccessFor(ci).HasPriv("BADWORDS") && source.HasPriv("botserv/administration")) + this->override = true; + bw = ci->Require("badwords"); + } + + ~BadwordsDelCallback() override + { + if (!deleted) + 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."), ci->name.c_str()); + else + source.Reply(_("Deleted %d entries from %s bad words list."), deleted, ci->name.c_str()); + } + + void HandleNumber(unsigned Number) override + { + if (!bw || !Number || Number > bw->GetBadWordCount()) + return; + + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "DEL " << bw->GetBadWord(Number - 1)->word; + ++deleted; + bw->EraseBadWord(Number - 1); + } +}; + +class CommandBSBadwords final + : public Command +{ +private: + void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word) + { + bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "LIST"; + ListFormatter list(source.GetAccount()); + BadWords *bw = ci->GetExt("badwords"); + + list.AddColumn(_("Number")).AddColumn(_("Word")).AddColumn(_("Type")); + + if (!bw || !bw->GetBadWordCount()) + { + source.Reply(_("%s bad words list is empty."), ci->name.c_str()); + return; + } + else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos) + { + class BadwordsListCallback final + : public NumberList + { + ListFormatter &list; + BadWords *bw; + public: + BadwordsListCallback(ListFormatter &_list, BadWords *_bw, const Anope::string &numlist) : NumberList(numlist, false), list(_list), bw(_bw) + { + } + + void HandleNumber(unsigned Number) override + { + if (!Number || Number > bw->GetBadWordCount()) + return; + + const BadWord *b = bw->GetBadWord(Number - 1); + ListFormatter::ListEntry entry; + entry["Number"] = stringify(Number); + entry["Word"] = b->word; + entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : "")); + this->list.AddEntry(entry); + } + } + nl_list(list, bw, word); + nl_list.Process(); + } + else + { + for (unsigned i = 0, end = bw->GetBadWordCount(); i < end; ++i) + { + const BadWord *b = bw->GetBadWord(i); + + if (!word.empty() && !Anope::Match(b->word, word)) + continue; + + ListFormatter::ListEntry entry; + entry["Number"] = stringify(i + 1); + entry["Word"] = b->word; + entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : "")); + list.AddEntry(entry); + } + } + + if (list.IsEmpty()) + source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); + else + { + std::vector replies; + list.Process(replies); + + source.Reply(_("Bad words list for %s:"), ci->name.c_str()); + + for (const auto &reply : replies) + source.Reply(reply); + + source.Reply(_("End of bad words list.")); + } + } + + void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word) + { + size_t pos = word.rfind(' '); + BadWordType bwtype = BW_ANY; + Anope::string realword = word; + BadWords *badwords = ci->Require("badwords"); + + if (pos != Anope::string::npos) + { + Anope::string opt = word.substr(pos + 1); + if (!opt.empty()) + { + if (opt.equals_ci("SINGLE")) + bwtype = BW_SINGLE; + else if (opt.equals_ci("START")) + bwtype = BW_START; + else if (opt.equals_ci("END")) + bwtype = BW_END; + } + realword = word.substr(0, pos); + } + + unsigned badwordsmax = Config->GetModule(this->module)->Get("badwordsmax"); + if (badwords->GetBadWordCount() >= badwordsmax) + { + source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax); + return; + } + + bool casesensitive = Config->GetModule(this->module)->Get("casesensitive"); + + for (unsigned i = 0, end = badwords->GetBadWordCount(); i < end; ++i) + { + const BadWord *bw = badwords->GetBadWord(i); + + if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && 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; + } + } + + bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword; + badwords->AddBadWord(realword, bwtype); + + source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str()); + } + + void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word) + { + BadWords *badwords = ci->GetExt("badwords"); + + if (!badwords || !badwords->GetBadWordCount()) + { + source.Reply(_("%s bad words list is empty."), ci->name.c_str()); + return; + } + + /* 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, ci, this, word); + list.Process(); + } + else + { + unsigned i, end; + const BadWord *badword; + + for (i = 0, end = badwords->GetBadWordCount(); i < end; ++i) + { + badword = badwords->GetBadWord(i); + + if (word.equals_ci(badword->word)) + break; + } + + if (i == end) + { + source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str()); + return; + } + + bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "DEL " << badword->word; + + source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str()); + + badwords->EraseBadWord(i); + } + + badwords->Check(); + } + + void DoClear(CommandSource &source, ChannelInfo *ci) + { + bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "CLEAR"; + + BadWords *badwords = ci->GetExt("badwords"); + if (badwords) + badwords->ClearBadWords(); + source.Reply(_("Bad words list is now empty.")); + } + +public: + CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) + { + this->SetDesc(_("Maintains the bad words list")); + this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]")); + this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}")); + this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]")); + this->SetSyntax(_("\037channel\037 CLEAR")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + const Anope::string &cmd = params[1]; + const Anope::string &word = params.size() > 2 ? params[2] : ""; + bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR"); + + if (!need_args && word.empty()) + { + this->OnSyntaxError(source, cmd); + return; + } + + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!source.AccessFor(ci).HasPriv("BADWORDS") && !source.HasPriv("botserv/administration")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bad words list modification is temporarily disabled.")); + return; + } + + if (cmd.equals_ci("ADD")) + return this->DoAdd(source, ci, word); + else if (cmd.equals_ci("DEL")) + return this->DoDelete(source, ci, word); + else if (cmd.equals_ci("LIST")) + return this->DoList(source, ci, word); + else if (cmd.equals_ci("CLEAR")) + return this->DoClear(source, ci); + else + this->OnSyntaxError(source, ""); + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + 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 %s\002.\n" + " \n" + "The \002ADD\002 command adds the given word to the\n" + "bad words list. If SINGLE is specified, a kick will be\n" + "done only if a user says the entire word. If START is\n" + "specified, a kick will be done if a user says a word\n" + "that starts with \037word\037. If END is specified, a kick\n" + "will be done if a user says a word that ends with\n" + "\037word\037. If you don't specify anything, a kick will\n" + "be issued every time \037word\037 is said by a user.\n" + " \n"), Config->StrictPrivmsg.c_str(), source.service->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 \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" + " \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 \002CLEAR\002 command clears all entries from the\n" + "bad words list.")); + return true; + } +}; + +class BSBadwords final + : public Module +{ + CommandBSBadwords commandbsbadwords; + ExtensibleItem badwords; + Serialize::Type badword_type; + +public: + BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + commandbsbadwords(this), badwords(this, "badwords"), badword_type("BadWord", BadWordImpl::Unserialize) + { + } +}; + +MODULE_INIT(BSBadwords) diff --git a/modules/botserv/bs_bot.cpp b/modules/botserv/bs_bot.cpp new file mode 100644 index 000000000..170e1073a --- /dev/null +++ b/modules/botserv/bs_bot.cpp @@ -0,0 +1,387 @@ +/* BotServ core functions + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "module.h" + +class CommandBSBot final + : public Command +{ +private: + void DoAdd(CommandSource &source, const std::vector ¶ms) + { + const Anope::string &nick = params[1]; + const Anope::string &user = params[2]; + const Anope::string &host = params[3]; + const Anope::string &real = params[4]; + + if (BotInfo::Find(nick, true)) + { + source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); + return; + } + + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get("nicklen")) + { + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get("nicklen")); + return; + } + + if (user.length() > networkinfo->Get("userlen")) + { + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get("userlen")); + return; + } + + if (host.length() > networkinfo->Get("hostlen")) + { + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get("hostlen")); + return; + } + + if (!IRCD->IsNickValid(nick)) + { + source.Reply(_("Bot nicks may only contain valid nick characters.")); + return; + } + + if (!IRCD->IsIdentValid(user)) + { + source.Reply(_("Bot idents may only contain valid ident characters.")); + return; + } + + if (!IRCD->IsHostValid(host)) + { + source.Reply(_("Bot hosts may only contain valid host characters.")); + return; + } + + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (NickAlias::Find(nick)) + { + source.Reply(NICK_ALREADY_REGISTERED, nick.c_str()); + return; + } + + User *u = User::Find(nick, true); + if (u) + { + source.Reply(_("Nick \002%s\002 is currently in use."), u->nick.c_str()); + return; + } + + auto *bi = new BotInfo(nick, user, host, real); + + Log(LOG_ADMIN, source, 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(OnBotCreate, (bi)); + return; + } + + void DoChange(CommandSource &source, const std::vector ¶ms) + { + const Anope::string &oldnick = params[1]; + const Anope::string &nick = params.size() > 2 ? params[2] : ""; + const Anope::string &user = params.size() > 3 ? params[3] : ""; + const Anope::string &host = params.size() > 4 ? params[4] : ""; + const Anope::string &real = params.size() > 5 ? params[5] : ""; + + if (oldnick.empty() || nick.empty()) + { + this->OnSyntaxError(source, "CHANGE"); + return; + } + + BotInfo *bi = BotInfo::Find(oldnick, true); + if (!bi) + { + source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str()); + return; + } + + if (bi->conf) + { + source.Reply(_("Bot %s is not changeable."), bi->nick.c_str()); + return; + } + + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get("nicklen")) + { + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get("nicklen")); + return; + } + + if (user.length() > networkinfo->Get("userlen")) + { + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get("userlen")); + return; + } + + if (host.length() > networkinfo->Get("hostlen")) + { + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get("hostlen")); + return; + } + + /* Checks whether there *are* changes. + * Case sensitive because we may want to change just the case. + * And we must finally check that the nick is not already + * taken by another bot. + */ + 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(_("The old information is the same as the new information specified.")); + return; + } + + if (!IRCD->IsNickValid(nick)) + { + source.Reply(_("Bot nicks may only contain valid nick characters.")); + return; + } + + if (!user.empty() && !IRCD->IsIdentValid(user)) + { + source.Reply(_("Bot idents may only contain valid ident characters.")); + return; + } + + if (!host.empty() && !IRCD->IsHostValid(host)) + { + source.Reply(_("Bot hosts may only contain valid host characters.")); + return; + } + + if (!nick.equals_ci(bi->nick)) + { + if (BotInfo::Find(nick, true)) + { + source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); + return; + } + + if (User::Find(nick, true)) + { + source.Reply(_("Nick \002%s\002 is currently in use."), nick.c_str()); + return; + } + } + + if (!nick.equals_ci(bi->nick)) + { + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (NickAlias::Find(nick)) + { + 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. */ + XLine x_del(bi->nick); + IRCD->SendSQLineDel(&x_del); + + /* Add a Q line for the new nick */ + XLine x(nick, "Reserved for services"); + IRCD->SendSQLine(NULL, &x); + } + + if (!user.empty()) + { + IRCD->SendQuit(bi, "Quit: Be right back"); + bi->introduced = false; + } + else + IRCD->SendNickChange(bi, nick); + + if (!nick.equals_cs(bi->nick)) + bi->SetNewNick(nick); + + if (!user.empty() && !user.equals_cs(bi->GetIdent())) + bi->SetIdent(user); + if (!host.empty() && !host.equals_cs(bi->host)) + bi->host = host; + if (!real.empty() && !real.equals_cs(bi->realname)) + bi->realname = real; + + if (!user.empty()) + bi->OnKill(); + + source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); + Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; + + FOREACH_MOD(OnBotChange, (bi)); + return; + } + + void DoDel(CommandSource &source, const std::vector ¶ms) + { + const Anope::string &nick = params[1]; + + if (nick.empty()) + { + this->OnSyntaxError(source, "DEL"); + return; + } + + BotInfo *bi = BotInfo::Find(nick, true); + if (!bi) + { + source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); + return; + } + + if (bi->conf) + { + source.Reply(_("Bot %s is not deletable."), bi->nick.c_str()); + return; + } + + FOREACH_MOD(OnBotDelete, (bi)); + + Log(LOG_ADMIN, source, this) << "DEL " << bi->nick; + + source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str()); + delete bi; + return; + } +public: + CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6) + { + 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")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + const Anope::string &cmd = params[0]; + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot modification is temporarily disabled.")); + return; + } + + if (cmd.equals_ci("ADD")) + { + // ADD nick user host real - 5 + if (!source.HasCommand("botserv/bot/add")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params.size() < 5) + { + this->OnSyntaxError(source, "ADD"); + return; + } + + std::vector tempparams = params; + // ADD takes less params than CHANGE, so we need to take 6 if given and append it with a space to 5. + if (tempparams.size() >= 6) + tempparams[4] = tempparams[4] + " " + tempparams[5]; + + return this->DoAdd(source, tempparams); + } + else if (cmd.equals_ci("CHANGE")) + { + // CHANGE oldn newn user host real - 6 + // but only oldn and newn are required + if (!source.HasCommand("botserv/bot/change")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params.size() < 3) + { + this->OnSyntaxError(source, "CHANGE"); + return; + } + + return this->DoChange(source, params); + } + else if (cmd.equals_ci("DEL")) + { + // DEL nick + if (!source.HasCommand("botserv/bot/del")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params.size() < 1) + { + this->OnSyntaxError(source, "DEL"); + return; + } + + return this->DoDel(source, params); + } + else + this->OnSyntaxError(source, ""); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_(