summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml7
-rw-r--r--CMakeLists.txt400
-rwxr-xr-xConfig48
-rw-r--r--Config.exebin18944 -> 0 bytes
-rw-r--r--cmake/Anope.cmake525
-rw-r--r--cmake/FindGettext.cmake12
-rw-r--r--cmake/ReadFile.cmake5
-rw-r--r--data/CMakeLists.txt6
-rw-r--r--data/anope.example.conf (renamed from data/example.conf)274
-rw-r--r--data/ascii.conf157
-rw-r--r--data/bahamut.example.conf170
-rw-r--r--data/botserv.example.conf56
-rw-r--r--data/chanserv.example.conf136
-rw-r--r--data/chanstats.example.conf2
-rw-r--r--data/example.chk8
-rw-r--r--data/global.example.conf15
-rw-r--r--data/hostserv.example.conf39
-rw-r--r--data/hybrid.example.conf231
-rw-r--r--data/inspircd20.example.conf547
-rw-r--r--data/memoserv.example.conf61
-rw-r--r--data/modules.example.conf228
-rw-r--r--data/ngircd.example.conf234
-rw-r--r--data/nickserv.example.conf109
-rw-r--r--data/operserv.example.conf135
-rw-r--r--data/plexus.example.conf294
-rw-r--r--data/ratbox.example.conf174
-rw-r--r--data/rfc1459.conf24
-rw-r--r--data/stats.standalone.example.conf513
-rw-r--r--data/unreal.example.conf449
-rw-r--r--docs/ASTYLE1
-rw-r--r--docs/C++CASTING111
-rw-r--r--docs/CMakeLists.txt4
-rw-r--r--docs/CODING239
-rw-r--r--docs/Changes.conf5
-rw-r--r--docs/EVENTS35
-rw-r--r--docs/FAQ10
-rw-r--r--docs/INSTALL16
-rw-r--r--docs/INSTALL.fr18
-rw-r--r--docs/LANGUAGE2
-rw-r--r--docs/MODULES6
-rw-r--r--docs/NEWS7
-rw-r--r--docs/README6
-rw-r--r--docs/REDIS160
-rw-r--r--docs/TOOLS24
-rw-r--r--docs/WIN32.txt4
-rw-r--r--docs/XMLRPC/xmlrpc.php2
-rw-r--r--include/CMakeLists.txt46
-rw-r--r--include/access.h174
-rw-r--r--include/accessgroup.h62
-rw-r--r--include/account.h281
-rw-r--r--include/anope.h164
-rw-r--r--include/base.h88
-rw-r--r--include/bots.h115
-rw-r--r--include/channels.h46
-rw-r--r--include/commands.h60
-rw-r--r--include/config.h88
-rw-r--r--include/defs.h66
-rw-r--r--include/event.h1232
-rw-r--r--include/extensible.h204
-rw-r--r--include/hashcomp.h91
-rw-r--r--include/language.h89
-rw-r--r--include/lists.h61
-rw-r--r--include/logger.h42
-rw-r--r--include/mail.h28
-rw-r--r--include/memo.h55
-rw-r--r--include/messages.h126
-rw-r--r--include/modes.h117
-rw-r--r--include/module.h38
-rw-r--r--include/modules.h1073
-rw-r--r--include/modules/botserv.h32
-rw-r--r--include/modules/botserv/badwords.h112
-rw-r--r--include/modules/botserv/bot.h58
-rw-r--r--include/modules/botserv/info.h33
-rw-r--r--include/modules/botserv/kick.h141
-rw-r--r--include/modules/bs_badwords.h70
-rw-r--r--include/modules/bs_kick.h44
-rw-r--r--include/modules/chanserv.h479
-rw-r--r--include/modules/chanserv/access.h72
-rw-r--r--include/modules/chanserv/akick.h77
-rw-r--r--include/modules/chanserv/drop.h35
-rw-r--r--include/modules/chanserv/entrymsg.h41
-rw-r--r--include/modules/chanserv/info.h37
-rw-r--r--include/modules/chanserv/log.h51
-rw-r--r--include/modules/chanserv/main/chanaccess.h50
-rw-r--r--include/modules/chanserv/mode.h133
-rw-r--r--include/modules/chanserv/set.h38
-rw-r--r--include/modules/chanserv/set_misc.h36
-rw-r--r--include/modules/chanserv/suspend.h69
-rw-r--r--include/modules/cs_entrymsg.h34
-rw-r--r--include/modules/cs_log.h42
-rw-r--r--include/modules/cs_mode.h89
-rw-r--r--include/modules/dns.h64
-rw-r--r--include/modules/encryption.h33
-rw-r--r--include/modules/fantasy.h54
-rw-r--r--include/modules/global.h40
-rw-r--r--include/modules/help.h42
-rw-r--r--include/modules/hostserv/del.h34
-rw-r--r--include/modules/httpd.h41
-rw-r--r--include/modules/ldap.h38
-rw-r--r--include/modules/memoserv.h165
-rw-r--r--include/modules/nickserv.h327
-rw-r--r--include/modules/nickserv/access.h34
-rw-r--r--include/modules/nickserv/ajoin.h37
-rw-r--r--include/modules/nickserv/cert.h76
-rw-r--r--include/modules/nickserv/drop.h35
-rw-r--r--include/modules/nickserv/group.h35
-rw-r--r--include/modules/nickserv/info.h37
-rw-r--r--include/modules/nickserv/set.h38
-rw-r--r--include/modules/nickserv/set_misc.h37
-rw-r--r--include/modules/nickserv/suspend.h69
-rw-r--r--include/modules/nickserv/update.h34
-rw-r--r--include/modules/ns_cert.h70
-rw-r--r--include/modules/operserv/defcon.h34
-rw-r--r--include/modules/operserv/dns.h83
-rw-r--r--include/modules/operserv/forbid.h68
-rw-r--r--include/modules/operserv/ignore.h49
-rw-r--r--include/modules/operserv/info.h39
-rw-r--r--include/modules/operserv/news.h47
-rw-r--r--include/modules/operserv/session.h97
-rw-r--r--include/modules/operserv/stats.h35
-rw-r--r--include/modules/os_forbid.h53
-rw-r--r--include/modules/os_ignore.h43
-rw-r--r--include/modules/os_news.h52
-rw-r--r--include/modules/os_session.h94
-rw-r--r--include/modules/protocol/charybdis.h60
-rw-r--r--include/modules/protocol/hybrid.h129
-rw-r--r--include/modules/protocol/plexus.h50
-rw-r--r--include/modules/protocol/ratbox.h66
-rw-r--r--include/modules/pseudoclients/chanserv.h25
-rw-r--r--include/modules/pseudoclients/global.h27
-rw-r--r--include/modules/pseudoclients/memoserv.h41
-rw-r--r--include/modules/pseudoclients/nickserv.h24
-rw-r--r--include/modules/redis.h53
-rw-r--r--include/modules/sasl.h116
-rw-r--r--include/modules/set_misc.h17
-rw-r--r--include/modules/sql.h182
-rw-r--r--include/modules/ssl.h26
-rw-r--r--include/modules/suspend.h19
-rw-r--r--include/modules/xmlrpc.h36
-rw-r--r--include/opertype.h98
-rw-r--r--include/protocol.h133
-rw-r--r--include/pstdint.h800
-rw-r--r--include/regchannel.h252
-rw-r--r--include/regexpr.h45
-rw-r--r--include/serialize.h976
-rw-r--r--include/servers.h26
-rw-r--r--include/service.h232
-rw-r--r--include/services.h43
-rw-r--r--include/socketengine.h22
-rw-r--r--include/sockets.h46
-rw-r--r--include/sysconf.h.cmake61
-rw-r--r--include/threadengine.h80
-rw-r--r--include/timers.h26
-rw-r--r--include/uplink.h61
-rw-r--r--include/users.h91
-rw-r--r--include/version.cpp22
-rw-r--r--include/xline.h144
-rw-r--r--language/CMakeLists.txt8
-rw-r--r--language/anope.ca_ES.po1567
-rw-r--r--language/anope.de_DE.po1599
-rw-r--r--language/anope.el_GR.po1607
-rw-r--r--language/anope.en_US.po1426
-rw-r--r--language/anope.es_ES.po1632
-rw-r--r--language/anope.fr_FR.po1214
-rw-r--r--language/anope.hu_HU.po1564
-rw-r--r--language/anope.it_IT.po1627
-rw-r--r--language/anope.nl_NL.po1848
-rw-r--r--language/anope.pl_PL.po1560
-rw-r--r--language/anope.pt_PT.po1568
-rw-r--r--language/anope.ru_RU.po1568
-rw-r--r--language/anope.tr_TR.po1568
-rw-r--r--modules/CMakeLists.txt272
-rw-r--r--modules/botserv/CMakeLists.txt1
-rw-r--r--modules/botserv/assign.cpp291
-rw-r--r--modules/botserv/autoassign.cpp48
-rw-r--r--modules/botserv/badwords.cpp472
-rw-r--r--modules/botserv/bot.cpp427
-rw-r--r--modules/botserv/botlist.cpp100
-rw-r--r--modules/botserv/control.cpp176
-rw-r--r--modules/botserv/info.cpp118
-rw-r--r--modules/botserv/kick.cpp1743
-rw-r--r--modules/botserv/main/CMakeLists.txt1
-rw-r--r--modules/botserv/main/botserv.cpp (renamed from modules/pseudoclients/botserv.cpp)108
-rw-r--r--modules/botserv/set.cpp (renamed from modules/commands/bs_set.cpp)115
-rw-r--r--modules/bs_autoassign.cpp36
-rw-r--r--modules/chanserv/CMakeLists.txt2
-rw-r--r--modules/chanserv/access.cpp922
-rw-r--r--modules/chanserv/akick.cpp735
-rw-r--r--modules/chanserv/ban.cpp275
-rw-r--r--modules/chanserv/clone.cpp235
-rw-r--r--modules/chanserv/drop.cpp105
-rw-r--r--modules/chanserv/enforce.cpp (renamed from modules/commands/cs_enforce.cpp)129
-rw-r--r--modules/chanserv/entrymsg.cpp285
-rw-r--r--modules/chanserv/flags.cpp541
-rw-r--r--modules/chanserv/getkey.cpp83
-rw-r--r--modules/chanserv/info.cpp101
-rw-r--r--modules/chanserv/invite.cpp117
-rw-r--r--modules/chanserv/kick.cpp160
-rw-r--r--modules/chanserv/list.cpp274
-rw-r--r--modules/chanserv/log.cpp466
-rw-r--r--modules/chanserv/main/CMakeLists.txt1
-rw-r--r--modules/chanserv/main/chanaccess.cpp120
-rw-r--r--modules/chanserv/main/chanaccesstype.h42
-rw-r--r--modules/chanserv/main/channel.cpp401
-rw-r--r--modules/chanserv/main/channel.h96
-rw-r--r--modules/chanserv/main/channeltype.cpp64
-rw-r--r--modules/chanserv/main/channeltype.h53
-rw-r--r--modules/chanserv/main/chanserv.cpp607
-rw-r--r--modules/chanserv/main/level.cpp52
-rw-r--r--modules/chanserv/main/level.h40
-rw-r--r--modules/chanserv/main/leveltype.h35
-rw-r--r--modules/chanserv/main/mode.cpp52
-rw-r--r--modules/chanserv/main/mode.h40
-rw-r--r--modules/chanserv/main/modetype.h35
-rw-r--r--modules/chanserv/mode.cpp1011
-rw-r--r--modules/chanserv/register.cpp174
-rw-r--r--modules/chanserv/seen.cpp (renamed from modules/commands/cs_seen.cpp)170
-rw-r--r--modules/chanserv/set.cpp1291
-rw-r--r--modules/chanserv/set_misc.cpp227
-rw-r--r--modules/chanserv/status.cpp123
-rw-r--r--modules/chanserv/statusupdate.cpp (renamed from modules/cs_statusupdate.cpp)36
-rw-r--r--modules/chanserv/suspend.cpp350
-rw-r--r--modules/chanserv/sync.cpp85
-rw-r--r--modules/chanserv/topic.cpp289
-rw-r--r--modules/chanserv/unban.cpp (renamed from modules/commands/cs_unban.cpp)66
-rw-r--r--modules/chanserv/updown.cpp (renamed from modules/commands/cs_updown.cpp)124
-rw-r--r--modules/chanserv/xop.cpp668
-rw-r--r--modules/commands/bs_assign.cpp256
-rw-r--r--modules/commands/bs_badwords.cpp469
-rw-r--r--modules/commands/bs_bot.cpp385
-rw-r--r--modules/commands/bs_botlist.cpp82
-rw-r--r--modules/commands/bs_control.cpp146
-rw-r--r--modules/commands/bs_info.cpp134
-rw-r--r--modules/commands/bs_kick.cpp1474
-rw-r--r--modules/commands/cs_access.cpp904
-rw-r--r--modules/commands/cs_akick.cpp572
-rw-r--r--modules/commands/cs_ban.cpp248
-rw-r--r--modules/commands/cs_clone.cpp261
-rw-r--r--modules/commands/cs_drop.cpp95
-rw-r--r--modules/commands/cs_entrymsg.cpp289
-rw-r--r--modules/commands/cs_flags.cpp504
-rw-r--r--modules/commands/cs_getkey.cpp73
-rw-r--r--modules/commands/cs_info.cpp98
-rw-r--r--modules/commands/cs_invite.cpp111
-rw-r--r--modules/commands/cs_kick.cpp147
-rw-r--r--modules/commands/cs_list.cpp266
-rw-r--r--modules/commands/cs_log.cpp399
-rw-r--r--modules/commands/cs_mode.cpp1012
-rw-r--r--modules/commands/cs_register.cpp124
-rw-r--r--modules/commands/cs_set.cpp1356
-rw-r--r--modules/commands/cs_set_misc.cpp218
-rw-r--r--modules/commands/cs_status.cpp125
-rw-r--r--modules/commands/cs_suspend.cpp285
-rw-r--r--modules/commands/cs_sync.cpp66
-rw-r--r--modules/commands/cs_topic.cpp270
-rw-r--r--modules/commands/cs_xop.cpp635
-rw-r--r--modules/commands/gl_global.cpp60
-rw-r--r--modules/commands/greet.cpp216
-rw-r--r--modules/commands/hs_del.cpp113
-rw-r--r--modules/commands/hs_group.cpp117
-rw-r--r--modules/commands/hs_off.cpp69
-rw-r--r--modules/commands/hs_on.cpp75
-rw-r--r--modules/commands/hs_request.cpp394
-rw-r--r--modules/commands/hs_set.cpp229
-rw-r--r--modules/commands/ms_cancel.cpp81
-rw-r--r--modules/commands/ms_check.cpp87
-rw-r--r--modules/commands/ms_del.cpp151
-rw-r--r--modules/commands/ms_ignore.cpp132
-rw-r--r--modules/commands/ms_info.cpp231
-rw-r--r--modules/commands/ms_list.cpp164
-rw-r--r--modules/commands/ms_read.cpp216
-rw-r--r--modules/commands/ms_rsend.cpp104
-rw-r--r--modules/commands/ms_send.cpp88
-rw-r--r--modules/commands/ms_sendall.cpp70
-rw-r--r--modules/commands/ms_set.cpp315
-rw-r--r--modules/commands/ms_staff.cpp67
-rw-r--r--modules/commands/ns_access.cpp206
-rw-r--r--modules/commands/ns_ajoin.cpp405
-rw-r--r--modules/commands/ns_alist.cpp149
-rw-r--r--modules/commands/ns_cert.cpp407
-rw-r--r--modules/commands/ns_drop.cpp86
-rw-r--r--modules/commands/ns_getemail.cpp74
-rw-r--r--modules/commands/ns_getpass.cpp74
-rw-r--r--modules/commands/ns_group.cpp384
-rw-r--r--modules/commands/ns_identify.cpp128
-rw-r--r--modules/commands/ns_info.cpp282
-rw-r--r--modules/commands/ns_list.cpp301
-rw-r--r--modules/commands/ns_logout.cpp91
-rw-r--r--modules/commands/ns_recover.cpp295
-rw-r--r--modules/commands/ns_register.cpp429
-rw-r--r--modules/commands/ns_resetpass.cpp143
-rw-r--r--modules/commands/ns_set.cpp1341
-rw-r--r--modules/commands/ns_set_misc.cpp233
-rw-r--r--modules/commands/ns_suspend.cpp288
-rw-r--r--modules/commands/ns_update.cpp62
-rw-r--r--modules/commands/os_akill.cpp483
-rw-r--r--modules/commands/os_chankill.cpp119
-rw-r--r--modules/commands/os_dns.cpp949
-rw-r--r--modules/commands/os_forbid.cpp559
-rw-r--r--modules/commands/os_ignore.cpp416
-rw-r--r--modules/commands/os_info.cpp290
-rw-r--r--modules/commands/os_jupe.cpp80
-rw-r--r--modules/commands/os_kick.cpp84
-rw-r--r--modules/commands/os_login.cpp132
-rw-r--r--modules/commands/os_news.cpp464
-rw-r--r--modules/commands/os_oper.cpp293
-rw-r--r--modules/commands/os_reload.cpp67
-rw-r--r--modules/commands/os_session.cpp737
-rw-r--r--modules/commands/os_stats.cpp276
-rw-r--r--modules/commands/os_sxline.cpp732
-rw-r--r--modules/commands/os_update.cpp52
-rw-r--r--modules/database/CMakeLists.txt2
-rw-r--r--modules/database/db_flatfile.cpp415
-rw-r--r--modules/database/db_redis.cpp644
-rw-r--r--modules/database/db_sql.cpp261
-rw-r--r--modules/database/db_sql_live.cpp265
-rw-r--r--modules/database/flatfile.cpp218
-rw-r--r--modules/database/old.cpp (renamed from modules/database/db_old.cpp)614
-rw-r--r--modules/database/redis.cpp445
-rw-r--r--modules/database/sql.cpp445
-rw-r--r--modules/dns.cpp (renamed from modules/m_dns.cpp)113
-rw-r--r--modules/dnsbl.cpp (renamed from modules/m_dnsbl.cpp)54
-rw-r--r--modules/encryption/CMakeLists.txt1
-rw-r--r--modules/encryption/bcrypt.cpp (renamed from modules/encryption/enc_bcrypt.cpp)59
-rw-r--r--modules/encryption/enc_none.cpp69
-rw-r--r--modules/encryption/md5.cpp (renamed from modules/encryption/enc_md5.cpp)67
-rw-r--r--modules/encryption/none.cpp78
-rw-r--r--modules/encryption/old.cpp (renamed from modules/encryption/enc_old.cpp)65
-rw-r--r--modules/encryption/sha1.cpp (renamed from modules/encryption/enc_sha1.cpp)61
-rw-r--r--modules/encryption/sha256.cpp (renamed from modules/encryption/enc_sha256.cpp)65
-rw-r--r--modules/extra/ldap.cpp (renamed from modules/extra/m_ldap.cpp)45
-rw-r--r--modules/extra/ldap_authentication.cpp (renamed from modules/extra/m_ldap_authentication.cpp)111
-rw-r--r--modules/extra/ldap_oper.cpp (renamed from modules/extra/m_ldap_oper.cpp)55
-rw-r--r--modules/extra/m_regex_pcre.cpp83
-rw-r--r--modules/extra/m_regex_posix.cpp84
-rw-r--r--modules/extra/m_regex_tre.cpp85
-rw-r--r--modules/extra/m_sql_oper.cpp180
-rw-r--r--modules/extra/m_sqlite.cpp326
-rw-r--r--modules/extra/mysql.cpp (renamed from modules/extra/m_mysql.cpp)302
-rw-r--r--modules/extra/sasl_dh-aes.cpp184
-rw-r--r--modules/extra/sasl_dh-blowfish.cpp194
-rw-r--r--modules/extra/sql_authentication.cpp (renamed from modules/extra/m_sql_authentication.cpp)50
-rw-r--r--modules/extra/sql_log.cpp (renamed from modules/extra/m_sql_log.cpp)28
-rw-r--r--modules/extra/sql_oper.cpp194
-rw-r--r--modules/extra/sqlite.cpp399
-rw-r--r--modules/extra/ssl_gnutls.cpp (renamed from modules/extra/m_ssl_gnutls.cpp)50
-rw-r--r--modules/extra/ssl_openssl.cpp (renamed from modules/extra/m_ssl_openssl.cpp)53
-rw-r--r--modules/extra/stats/chanstats.cpp (renamed from modules/extra/stats/m_chanstats.cpp)88
-rw-r--r--modules/extra/stats/cs_fantasy_stats.cpp18
-rw-r--r--modules/extra/stats/cs_fantasy_top.cpp16
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.cpp20
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.h50
-rw-r--r--modules/fantasy.cpp81
-rw-r--r--modules/global/CMakeLists.txt1
-rw-r--r--modules/global/global.cpp68
-rw-r--r--modules/global/main/CMakeLists.txt1
-rw-r--r--modules/global/main/global.cpp119
-rw-r--r--modules/greet.cpp223
-rw-r--r--modules/help.cpp (renamed from modules/commands/help.cpp)72
-rw-r--r--modules/helpchan.cpp45
-rw-r--r--modules/hostserv/CMakeLists.txt1
-rw-r--r--modules/hostserv/del.cpp111
-rw-r--r--modules/hostserv/group.cpp127
-rw-r--r--modules/hostserv/list.cpp (renamed from modules/commands/hs_list.cpp)69
-rw-r--r--modules/hostserv/main/CMakeLists.txt1
-rw-r--r--modules/hostserv/main/hostserv.cpp148
-rw-r--r--modules/hostserv/off.cpp71
-rw-r--r--modules/hostserv/on.cpp81
-rw-r--r--modules/hostserv/request.cpp432
-rw-r--r--modules/hostserv/set.cpp224
-rw-r--r--modules/httpd.cpp (renamed from modules/m_httpd.cpp)61
-rw-r--r--modules/m_helpchan.cpp32
-rw-r--r--modules/m_proxyscan.cpp379
-rw-r--r--modules/m_sasl.cpp329
-rw-r--r--modules/memoserv/CMakeLists.txt1
-rw-r--r--modules/memoserv/cancel.cpp98
-rw-r--r--modules/memoserv/check.cpp88
-rw-r--r--modules/memoserv/del.cpp153
-rw-r--r--modules/memoserv/ignore.cpp155
-rw-r--r--modules/memoserv/info.cpp227
-rw-r--r--modules/memoserv/list.cpp171
-rw-r--r--modules/memoserv/main/CMakeLists.txt1
-rw-r--r--modules/memoserv/main/ignore.cpp46
-rw-r--r--modules/memoserv/main/ignore.h39
-rw-r--r--modules/memoserv/main/ignoretype.cpp29
-rw-r--r--modules/memoserv/main/ignoretype.h29
-rw-r--r--modules/memoserv/main/memo.cpp85
-rw-r--r--modules/memoserv/main/memo.h53
-rw-r--r--modules/memoserv/main/memoinfo.cpp82
-rw-r--r--modules/memoserv/main/memoinfo.h47
-rw-r--r--modules/memoserv/main/memoinfotype.cpp29
-rw-r--r--modules/memoserv/main/memoinfotype.h29
-rw-r--r--modules/memoserv/main/memoserv.cpp305
-rw-r--r--modules/memoserv/main/memotype.cpp33
-rw-r--r--modules/memoserv/main/memotype.h32
-rw-r--r--modules/memoserv/read.cpp217
-rw-r--r--modules/memoserv/rsend.cpp114
-rw-r--r--modules/memoserv/send.cpp89
-rw-r--r--modules/memoserv/sendall.cpp68
-rw-r--r--modules/memoserv/set.cpp322
-rw-r--r--modules/memoserv/staff.cpp65
-rw-r--r--modules/nickserv/CMakeLists.txt1
-rw-r--r--modules/nickserv/access.cpp272
-rw-r--r--modules/nickserv/ajoin.cpp396
-rw-r--r--modules/nickserv/alist.cpp142
-rw-r--r--modules/nickserv/cert.cpp391
-rw-r--r--modules/nickserv/drop.cpp96
-rw-r--r--modules/nickserv/getemail.cpp70
-rw-r--r--modules/nickserv/group.cpp389
-rw-r--r--modules/nickserv/identify.cpp133
-rw-r--r--modules/nickserv/info.cpp284
-rw-r--r--modules/nickserv/list.cpp299
-rw-r--r--modules/nickserv/logout.cpp109
-rw-r--r--modules/nickserv/main/CMakeLists.txt1
-rw-r--r--modules/nickserv/main/account.cpp136
-rw-r--r--modules/nickserv/main/account.h58
-rw-r--r--modules/nickserv/main/accounttype.cpp60
-rw-r--r--modules/nickserv/main/accounttype.h42
-rw-r--r--modules/nickserv/main/identifyrequest.cpp81
-rw-r--r--modules/nickserv/main/identifyrequest.h33
-rw-r--r--modules/nickserv/main/mode.cpp42
-rw-r--r--modules/nickserv/main/mode.h37
-rw-r--r--modules/nickserv/main/modetype.h33
-rw-r--r--modules/nickserv/main/nick.cpp199
-rw-r--r--modules/nickserv/main/nick.h72
-rw-r--r--modules/nickserv/main/nickserv.cpp693
-rw-r--r--modules/nickserv/main/nicktype.cpp64
-rw-r--r--modules/nickserv/main/nicktype.h51
-rw-r--r--modules/nickserv/maxemail.cpp (renamed from modules/ns_maxemail.cpp)52
-rw-r--r--modules/nickserv/recover.cpp307
-rw-r--r--modules/nickserv/register.cpp445
-rw-r--r--modules/nickserv/resetpass.cpp150
-rw-r--r--modules/nickserv/set.cpp1261
-rw-r--r--modules/nickserv/set_misc.cpp239
-rw-r--r--modules/nickserv/status.cpp (renamed from modules/commands/ns_status.cpp)43
-rw-r--r--modules/nickserv/suspend.cpp348
-rw-r--r--modules/nickserv/update.cpp71
-rw-r--r--modules/operserv/CMakeLists.txt1
-rw-r--r--modules/operserv/akill.cpp455
-rw-r--r--modules/operserv/chankill.cpp134
-rw-r--r--modules/operserv/config.cpp (renamed from modules/commands/os_config.cpp)53
-rw-r--r--modules/operserv/defcon.cpp (renamed from modules/commands/os_defcon.cpp)166
-rw-r--r--modules/operserv/dns.cpp1051
-rw-r--r--modules/operserv/forbid.cpp602
-rw-r--r--modules/operserv/ignore.cpp410
-rw-r--r--modules/operserv/info.cpp280
-rw-r--r--modules/operserv/jupe.cpp80
-rw-r--r--modules/operserv/kick.cpp89
-rw-r--r--modules/operserv/kill.cpp (renamed from modules/commands/os_kill.cpp)38
-rw-r--r--modules/operserv/list.cpp (renamed from modules/commands/os_list.cpp)72
-rw-r--r--modules/operserv/login.cpp156
-rw-r--r--modules/operserv/logsearch.cpp (renamed from modules/commands/os_logsearch.cpp)65
-rw-r--r--modules/operserv/main/CMakeLists.txt1
-rw-r--r--modules/operserv/main/operserv.cpp329
-rw-r--r--modules/operserv/mode.cpp (renamed from modules/commands/os_mode.cpp)55
-rw-r--r--modules/operserv/modinfo.cpp (renamed from modules/commands/os_modinfo.cpp)71
-rw-r--r--modules/operserv/module.cpp (renamed from modules/commands/os_module.cpp)81
-rw-r--r--modules/operserv/news.cpp478
-rw-r--r--modules/operserv/noop.cpp (renamed from modules/commands/os_noop.cpp)53
-rw-r--r--modules/operserv/oline.cpp (renamed from modules/commands/os_oline.cpp)42
-rw-r--r--modules/operserv/oper.cpp257
-rw-r--r--modules/operserv/reload.cpp70
-rw-r--r--modules/operserv/session.cpp785
-rw-r--r--modules/operserv/set.cpp (renamed from modules/commands/os_set.cpp)108
-rw-r--r--modules/operserv/shutdown.cpp (renamed from modules/commands/os_shutdown.cpp)51
-rw-r--r--modules/operserv/stats.cpp327
-rw-r--r--modules/operserv/svs.cpp (renamed from modules/commands/os_svs.cpp)77
-rw-r--r--modules/operserv/sxline.cpp701
-rw-r--r--modules/operserv/update.cpp57
-rw-r--r--modules/protocol/CMakeLists.txt2
-rw-r--r--modules/protocol/bahamut.cpp272
-rw-r--r--modules/protocol/charybdis.cpp439
-rw-r--r--modules/protocol/hybrid.cpp662
-rw-r--r--modules/protocol/inspircd12.cpp1383
-rw-r--r--modules/protocol/inspircd20.cpp1581
-rw-r--r--modules/protocol/ngircd.cpp239
-rw-r--r--modules/protocol/plexus.cpp432
-rw-r--r--modules/protocol/ratbox.cpp364
-rw-r--r--modules/protocol/unreal.cpp824
-rw-r--r--modules/protocol/unreal4.cpp1468
-rw-r--r--modules/pseudoclients/chanserv.cpp479
-rw-r--r--modules/pseudoclients/global.cpp96
-rw-r--r--modules/pseudoclients/hostserv.cpp122
-rw-r--r--modules/pseudoclients/memoserv.cpp223
-rw-r--r--modules/pseudoclients/nickserv.cpp575
-rw-r--r--modules/pseudoclients/operserv.cpp299
-rw-r--r--modules/redis.cpp (renamed from modules/m_redis.cpp)88
-rw-r--r--modules/rewrite.cpp (renamed from modules/m_rewrite.cpp)42
-rw-r--r--modules/sasl.cpp391
-rw-r--r--modules/third/language/CMakeLists.txt10
-rw-r--r--modules/webcpanel/pages/chanserv/access.cpp54
-rw-r--r--modules/webcpanel/pages/chanserv/access.h22
-rw-r--r--modules/webcpanel/pages/chanserv/akick.cpp47
-rw-r--r--modules/webcpanel/pages/chanserv/akick.h22
-rw-r--r--modules/webcpanel/pages/chanserv/drop.cpp35
-rw-r--r--modules/webcpanel/pages/chanserv/drop.h20
-rw-r--r--modules/webcpanel/pages/chanserv/info.cpp20
-rw-r--r--modules/webcpanel/pages/chanserv/info.h20
-rw-r--r--modules/webcpanel/pages/chanserv/modes.cpp36
-rw-r--r--modules/webcpanel/pages/chanserv/modes.h22
-rw-r--r--modules/webcpanel/pages/chanserv/set.cpp112
-rw-r--r--modules/webcpanel/pages/chanserv/set.h22
-rw-r--r--modules/webcpanel/pages/chanserv/utils.cpp39
-rw-r--r--modules/webcpanel/pages/chanserv/utils.h20
-rw-r--r--modules/webcpanel/pages/confirm.cpp18
-rw-r--r--modules/webcpanel/pages/confirm.h20
-rw-r--r--modules/webcpanel/pages/hostserv/request.cpp26
-rw-r--r--modules/webcpanel/pages/hostserv/request.h20
-rw-r--r--modules/webcpanel/pages/index.cpp47
-rw-r--r--modules/webcpanel/pages/index.h20
-rw-r--r--modules/webcpanel/pages/logout.cpp20
-rw-r--r--modules/webcpanel/pages/logout.h20
-rw-r--r--modules/webcpanel/pages/memoserv/memos.cpp92
-rw-r--r--modules/webcpanel/pages/memoserv/memos.h20
-rw-r--r--modules/webcpanel/pages/nickserv/access.cpp29
-rw-r--r--modules/webcpanel/pages/nickserv/access.h20
-rw-r--r--modules/webcpanel/pages/nickserv/alist.cpp50
-rw-r--r--modules/webcpanel/pages/nickserv/alist.h20
-rw-r--r--modules/webcpanel/pages/nickserv/cert.cpp33
-rw-r--r--modules/webcpanel/pages/nickserv/cert.h20
-rw-r--r--modules/webcpanel/pages/nickserv/info.cpp96
-rw-r--r--modules/webcpanel/pages/nickserv/info.h20
-rw-r--r--modules/webcpanel/pages/operserv/akill.cpp50
-rw-r--r--modules/webcpanel/pages/operserv/akill.h22
-rw-r--r--modules/webcpanel/pages/register.cpp18
-rw-r--r--modules/webcpanel/pages/register.h20
-rw-r--r--modules/webcpanel/static_fileserver.cpp20
-rw-r--r--modules/webcpanel/static_fileserver.h20
-rw-r--r--modules/webcpanel/template_fileserver.cpp26
-rw-r--r--modules/webcpanel/template_fileserver.h18
-rw-r--r--modules/webcpanel/templates/default/confirm.html2
-rw-r--r--modules/webcpanel/templates/default/footer.html2
-rw-r--r--modules/webcpanel/templates/default/login.html2
-rw-r--r--modules/webcpanel/templates/default/register.html2
-rw-r--r--modules/webcpanel/webcpanel.cpp97
-rw-r--r--modules/webcpanel/webcpanel.h46
-rw-r--r--modules/xmlrpc.cpp (renamed from modules/m_xmlrpc.cpp)39
-rw-r--r--modules/xmlrpc_main.cpp (renamed from modules/m_xmlrpc_main.cpp)58
-rw-r--r--src/CMakeLists.txt89
-rw-r--r--src/access.cpp476
-rw-r--r--src/accessgroup.cpp125
-rw-r--r--src/account.cpp91
-rw-r--r--src/base.cpp40
-rw-r--r--src/base64.cpp20
-rw-r--r--src/bots.cpp278
-rw-r--r--src/channels.cpp141
-rw-r--r--src/command.cpp103
-rw-r--r--src/config.cpp596
-rw-r--r--src/event.cpp35
-rw-r--r--src/extensible.cpp61
-rw-r--r--src/hashcomp.cpp134
-rw-r--r--src/init.cpp94
-rw-r--r--src/language.cpp40
-rw-r--r--src/logger.cpp73
-rw-r--r--src/mail.cpp47
-rw-r--r--src/main.cpp37
-rw-r--r--src/memos.cpp141
-rw-r--r--src/messages.cpp88
-rw-r--r--src/misc.cpp140
-rw-r--r--src/modes.cpp166
-rw-r--r--src/module.cpp31
-rw-r--r--src/modulemanager.cpp260
-rw-r--r--src/nickalias.cpp217
-rw-r--r--src/nickcore.cpp270
-rw-r--r--src/opertype.cpp98
-rw-r--r--src/pipeengine.cpp25
-rw-r--r--src/process.cpp54
-rw-r--r--src/protocol.cpp102
-rw-r--r--src/regchannel.cpp695
-rw-r--r--src/serialize.cpp328
-rw-r--r--src/servers.cpp182
-rw-r--r--src/service.cpp67
-rw-r--r--src/service_manager.cpp138
-rw-r--r--src/socket_clients.cpp18
-rw-r--r--src/socket_transport.cpp22
-rw-r--r--src/socketengines/socketengine_epoll.cpp8
-rw-r--r--src/socketengines/socketengine_kqueue.cpp6
-rw-r--r--src/socketengines/socketengine_poll.cpp4
-rw-r--r--src/socketengines/socketengine_select.cpp4
-rw-r--r--src/sockets.cpp20
-rw-r--r--src/threadengine.cpp119
-rw-r--r--src/timers.cpp19
-rw-r--r--src/tools/CMakeLists.txt44
-rw-r--r--src/tools/anoperc.in6
-rw-r--r--src/tools/anopesmtp.cpp492
-rw-r--r--src/uplink.cpp79
-rw-r--r--src/users.cpp259
-rw-r--r--src/version.sh6
-rw-r--r--src/win32/Config.cs363
-rw-r--r--src/win32/anope_windows.h12
-rw-r--r--src/win32/dir/dir.cpp7
-rw-r--r--src/win32/dir/dir.h7
-rw-r--r--src/win32/dl/dl.cpp5
-rw-r--r--src/win32/dl/dl.h5
-rw-r--r--src/win32/pipe/pipe.cpp8
-rw-r--r--src/win32/pipe/pipe.h5
-rw-r--r--src/win32/pthread/pthread.cpp119
-rw-r--r--src/win32/pthread/pthread.h35
-rw-r--r--src/win32/resource.h10
-rw-r--r--src/win32/sigaction/sigaction.cpp17
-rw-r--r--src/win32/sigaction/sigaction.h28
-rw-r--r--src/win32/socket.cpp7
-rw-r--r--src/win32/socket.h5
-rw-r--r--src/win32/win32.rc.cmake2
-rw-r--r--src/win32/windows.cpp12
-rw-r--r--src/xline.cpp423
607 files changed, 62114 insertions, 60926 deletions
diff --git a/.gitignore b/.gitignore
index 83ee1f848..662177e14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
config.cache
include/sysconf.h
build/
+Makefile
+nbproject
diff --git a/.travis.yml b/.travis.yml
index 84753c2d8..15657dadf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,10 @@
language: cpp
-compiler:
- - gcc
-
before_script:
+ - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+ - sudo apt-get update -qq
+ - sudo apt-get install -y g++-4.8
+ - export CXX="g++-4.8" CC="gcc-4.8"
- mkdir build
- cd build
- cmake -DINSTDIR:STRING=~/services -DDEFUMASK:STRING=077 -DCMAKE_BUILD_TYPE:STRING=DEBUG -DUSE_RUN_CC_PL:BOOLEAN=ON ..
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b514e7f2f..9e05bffb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,197 +1,29 @@
-# This usage of CMake requires at least version 2.4 (checks are made to determine what to use when certain versions lack functions)
-cmake_minimum_required(VERSION 2.4 FATAL_ERROR)
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
- if(POLICY CMP0026)
- cmake_policy(SET CMP0026 OLD)
- endif(POLICY CMP0026)
- if(POLICY CMP0007)
- cmake_policy(SET CMP0007 OLD)
- endif(POLICY CMP0007)
-endif(COMMAND cmake_policy)
+# This usage of CMake requires at least version 3.0
+cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+
+cmake_policy(SET CMP0003 NEW)
+if(POLICY CMP0026)
+ cmake_policy(SET CMP0026 OLD)
+endif()
+if(POLICY CMP0007)
+ cmake_policy(SET CMP0007 OLD)
+endif()
# Set the project as C++ primarily, but have C enabled for the checks required later
project(Anope CXX)
enable_language(C)
-# Detect the version of CMake for the later conditional checks
-execute_process(COMMAND ${CMAKE_COMMAND} --version OUTPUT_VARIABLE VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
-string(REGEX REPLACE "cmake version 2\\.(.*)" "\\1" ONLY_VERSION "${VERSION}")
-string(REGEX MATCH "-patch .*$" HAS_PATCH "${ONLY_VERSION}")
-if(HAS_PATCH)
- string(REGEX REPLACE "(.*)-patch .*" "\\1" MINOR_VERSION "${ONLY_VERSION}")
- string(REGEX REPLACE ".*-patch (.*)" "\\1" PATCH_VERSION "${ONLY_VERSION}")
-else(HAS_PATCH)
- string(REGEX MATCH "\\." HAS_DOT "${ONLY_VERSION}")
- if(HAS_DOT)
- string(REGEX REPLACE "(.*)\\..*" "\\1" MINOR_VERSION "${ONLY_VERSION}")
- string(REGEX REPLACE ".*\\.(.*)" "\\1" PATCH_VERSION "${ONLY_VERSION}")
- else(HAS_DOT)
- string(REGEX REPLACE "(.*)-beta" "\\1" MINOR_VERSION "${ONLY_VERSION}")
- if(MINOR_VERSION STREQUAL "4-1\n")
- set(PATCH_VERSION 1)
- else(MINOR_VERSION STREQUAL "4-1\n")
- set(PATCH_VERSION 0)
- endif(MINOR_VERSION STREQUAL "4-1\n")
- set(MINOR_VERSION 4)
- endif(HAS_DOT)
-endif(HAS_PATCH)
-
-# Detect is we are using CMake 2.6 or better, these versions include functions that require less work than CMake 2.4 does
-if(MINOR_VERSION GREATER 5)
- set(CMAKE26_OR_BETTER TRUE)
- set(CMAKE248_OR_BETTER TRUE)
- set(CMAKE244_OR_BETTER TRUE)
- set(CMAKE242_OR_BETTER TRUE)
-else(MINOR_VERSION GREATER 5)
- set(CMAKE26_OR_BETTER FALSE)
- # Also detect if we are using CMake 2.4.8 or better, the FIND sub-command of list() is non-existent in earlier versions
- if(PATCH_VERSION GREATER 7)
- set(CMAKE248_OR_BETTER TRUE)
- set(CMAKE244_OR_BETTER TRUE)
- set(CMAKE242_OR_BETTER TRUE)
- else(PATCH_VERSION GREATER 7)
- set(CMAKE248_OR_BETTER FALSE)
- # Also detect if we are using CMake 2.4.4 or better, the CheckCXXCompilerFlag module and SORT sub-command of list() are non-existent in earlier versions
- if(PATCH_VERSION GREATER 3)
- set(CMAKE244_OR_BETTER TRUE)
- set(CMAKE242_OR_BETTER TRUE)
- else(PATCH_VERSION GREATER 3)
- set(CMAKE244_OR_BETTER FALSE)
- # ALSO detect if we are using CMake 2.4.2 or better, the APPEND sub-command of list() is non-existent in earlier versions
- if(PATCH_VERSION GREATER 1)
- set(CMAKE242_OR_BETTER TRUE)
- else(PATCH_VERSION GREATER 1)
- set(CMAKE242_OR_BETTER FALSE)
- endif(PATCH_VERSION GREATER 1)
- endif(PATCH_VERSION GREATER 3)
- endif(PATCH_VERSION GREATER 7)
-endif(MINOR_VERSION GREATER 5)
-
# Override the module include path to include our directory, for our Anope.cmake, as well as we are using our own version of the NSIS template
-set(CMAKE_MODULE_PATH ${Anope_SOURCE_DIR}/cmake)
+list(APPEND CMAKE_MODULE_PATH "${Anope_SOURCE_DIR}/cmake")
-include(Anope)
+include("Anope")
+include("CheckFunctionExists")
+include("CheckLibraryExists")
+include("CheckCXXCompilerFlag")
# Force the locale to C for later uses of things like gcc so the messages come up in English, not the user's default language
set(ENV{LC_ALL} C)
-# Start with empty defaults for library and include directories, to be used by GNU compilers only
-set(DEFAULT_LIBRARY_DIRS)
-set(DEFAULT_INCLUDE_DIRS)
-
-# Check that we aren't running on an ancient broken GCC
-if(CMAKE_COMPILER_IS_GNUCXX)
- execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_FULL_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REGEX REPLACE "^(\\d+\\.\\d+)" "\\1" GCC_VERSION ${GCC_FULL_VERSION})
- if(GCC_VERSION LESS 4.2)
- message(FATAL_ERROR "Your compiler is too old to build Anope. Upgrade to GCC 4.2 or newer!")
- endif(GCC_VERSION LESS 4.2)
- if(GCC_VERSION GREATER 6.0 OR GCC_VERSION EQUAL 6.0)
- set(CXXFLAGS "${CXXFLAGS} -fno-delete-null-pointer-checks")
- endif(GCC_VERSION GREATER 6.0 OR GCC_VERSION EQUAL 6.0)
-endif(CMAKE_COMPILER_IS_GNUCXX)
-
-# If we are using a GNU compiler (have to use CXX because it seems to fail on C), we will be able to determine it's default paths for libraries and includes
-if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$")
- # First look for the compiler's default library directories
- execute_process(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs OUTPUT_VARIABLE LINES OUTPUT_STRIP_TRAILING_WHITESPACE)
- # Find only the part after "libraries: "
- string(REGEX REPLACE ".*\nlibraries: (.*)$" "\\1" LINE "${LINES}")
- # Replace the colons in the list with semicolons (only when not on MinGW, which uses semicolons already), and if on MinGW, just copy the line
- if(NOT MINGW)
- string(REGEX REPLACE ":" ";" LIBRARIES ${LINE})
- else(NOT MINGW)
- set(LIBRARIES "${LINE}")
- endif(NOT MINGW)
- # Iterate through the libraries
- foreach(LIBRARY ${LIBRARIES})
- # Check if the first character is an equal sign, and skip that library directory as it is (I believe) the primary default and shows up later in the list anyways
- string(SUBSTRING ${LIBRARY} 0 1 FIRST_CHAR)
- if(NOT FIRST_CHAR STREQUAL "=")
- # If the directory had no = in front of it, make sure it's absolute and add it to the list of default library directories
- get_filename_component(LIBRARY ${LIBRARY} ABSOLUTE)
- append_to_list(DEFAULT_LIBRARY_DIRS ${LIBRARY})
- endif(NOT FIRST_CHAR STREQUAL "=")
- endforeach(LIBRARY)
- # Remove duplicate entries from the list
- if(DEFAULT_LIBRARY_DIRS)
- remove_list_duplicates(DEFAULT_LIBRARY_DIRS)
- endif(DEFAULT_LIBRARY_DIRS)
- # Create a temporary file to test for the default include directories
- FILE(WRITE empty.cpp "")
- # Next, we look for the compiler's default include directories
- # Run the command to find the default include directories
- execute_process(COMMAND ${CMAKE_C_COMPILER} -v -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp ERROR_VARIABLE LINES OUTPUT_QUIET ERROR_STRIP_TRAILING_WHITESPACE)
- # Remove the empty file, it is no longer needed
- FILE(REMOVE empty.cpp)
- # Convert the new lines to semicolons
- string(REGEX REPLACE "\n" ";" LINES ${LINES})
- # Temporary variable saying if we are in the search list or not
- set(IN_SEARCH_LIST FALSE)
- # Iterate through the lines
- foreach(LINE ${LINES})
- # If the line has the following on it, the next lines will contain directory names
- if(LINE STREQUAL "#include <...> search starts here:")
- set(IN_SEARCH TRUE)
- else(LINE STREQUAL "#include <...> search starts here:")
- # If the line has the following on it, we hit the end of the list
- if(LINE STREQUAL "End of search list.")
- set(IN_SEARCH FALSE)
- else(LINE STREQUAL "End of search list.")
- # If we are within the block between the above two lines...
- if(IN_SEARCH)
- # Get everything but the first character of the line
- string(LENGTH ${LINE} LINE_LENGTH)
- math(EXPR LINE_LENGTH "${LINE_LENGTH} - 1")
- string(SUBSTRING ${LINE} 1 ${LINE_LENGTH} INCLUDE)
- # For systems like Mac OS X, look for include paths that say " (framework directory)" at the end of them and strip that off
- string(REGEX REPLACE " \\(framework directory\\)$" "" INCLUDE ${INCLUDE})
- # Convert the path to an absolute one, just in case it wasn't
- get_filename_component(INCLUDE ${INCLUDE} ABSOLUTE)
- # Add that directory to the list of default include directories
- append_to_list(DEFAULT_INCLUDE_DIRS ${INCLUDE})
- endif(IN_SEARCH)
- endif(LINE STREQUAL "End of search list.")
- endif(LINE STREQUAL "#include <...> search starts here:")
- endforeach(LINE)
- # Remove duplicate entries from the list
- if(DEFAULT_INCLUDE_DIRS)
- remove_list_duplicates(DEFAULT_INCLUDE_DIRS)
- endif(DEFAULT_INCLUDE_DIRS)
-endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$")
-
-# If we are using Visual Studio, locate the path of the Windows Server 2008 SDK or Windows Server 2003 Platform SDK, depending on which is installed
-if(MSVC)
- # If the path comes up as "/registry" from any of these, the path wasn't found, otherwise, we'll set WSDK_PATH to the corresponding path
- # Look for the 2008 SDK under HKLM first
- get_filename_component(WSDK2008_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" ABSOLUTE CACHE)
- if(WSDK2008_PATH STREQUAL "/registry")
- # If not found, look for the 2003 SDK under HKLM
- get_filename_component(WSDK2003_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1;Install Dir]" ABSOLUTE CACHE)
- if(WSDK2003_PATH STREQUAL "/registry")
- # If not found, look for the 2008 SDK under HKCU
- get_filename_component(WSDK2008_PATH "[HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" ABSOLUTE CACHE)
- if(WSDK2008_PATH STREQUAL "/registry")
- # If not found, look for the 2003 SDK under HKCU
- get_filename_component(WSDK2003_PATH "[HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1;Install Dir]" ABSOLUTE CACHE)
- if(WSDK2003_PATH STREQUAL "/registry")
- # The SDK was never found, set the path to nothing
- set(WSDK_PATH "")
- else(WSDK2003_PATH STREQUAL "/registry")
- set(WSDK_PATH "${WSDK2003_PATH}")
- endif(WSDK2003_PATH STREQUAL "/registry")
- else(WSDK2008_PATH STREQUAL "/registry")
- set(WSDK_PATH "${WSDK2008_PATH}")
- endif(WSDK2008_PATH STREQUAL "/registry")
- else(WSDK2003_PATH STREQUAL "/registry")
- set(WSDK_PATH "${WSDK2003_PATH}")
- endif(WSDK2003_PATH STREQUAL "/registry")
- else(WSDK2008_PATH STREQUAL "/registry")
- set(WSDK_PATH "${WSDK2008_PATH}")
- endif(WSDK2008_PATH STREQUAL "/registry")
-endif(MSVC)
-
# If the user specifies -DCMAKE_BUILD_TYPE on the command line, take their definition
# and dump it in the cache along with proper documentation, otherwise set CMAKE_BUILD_TYPE
# to Debug
@@ -199,48 +31,41 @@ endif(MSVC)
if(NOT MSVC)
if(CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
- else(CMAKE_BUILD_TYPE)
+ else()
set(CMAKE_BUILD_TYPE DEBUG CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
- endif(CMAKE_BUILD_TYPE)
-endif(NOT MSVC)
-
-# If running under MinGW, we have to force the resource compiler settings (hopefully this will be fixed in a later version of CMake)
-if(MINGW)
- set(CMAKE_RC_COMPILER_INIT windres)
- enable_language(RC)
- set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>")
-endif(MINGW)
-
-# Include the checking functions used later in this CMakeLists.txt
-include(CheckFunctionExists)
-include(CheckIncludeFile)
-include(CheckTypeSize)
-include(CheckLibraryExists)
-if(CMAKE244_OR_BETTER)
- include(CheckCXXCompilerFlag)
-else(CMAKE244_OR_BETTER)
- include(TestCXXAcceptsFlag)
-endif(CMAKE244_OR_BETTER)
+ endif()
+
+ check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11)
+ if(NOT COMPILER_SUPPORTS_CXX11)
+ message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a newer compiler.")
+ endif()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+endif()
# If extra include directories were specified, tell cmake about them.
if(EXTRA_INCLUDE)
include_directories(${EXTRA_INCLUDE})
-endif(EXTRA_INCLUDE)
+endif()
# If extra library directories were specified, tell cmake about them.
if(EXTRA_LIBS)
link_directories(${EXTRA_LIBS})
-endif(EXTRA_LIBS)
+endif()
# Find gettext
find_package(Gettext)
+# FindBoost.cmake warns even if you specify QUIET, so
+find_path(BOOST_LOCALE_HEADER_FILE NAMES boost/locale.hpp)
+if(BOOST_LOCALE_HEADER_FILE)
+ find_package(Boost COMPONENTS locale)
+endif()
-option(USE_PCH "Use precompiled headers" OFF)
+if(Boost_FOUND)
+ include_directories(${Boost_INCLUDE_DIRS})
+endif()
# Use the following directories as includes
-# Note that it is important the binary include directory comes before the
-# source include directory so the precompiled headers work correctly.
-include_directories(${Anope_BINARY_DIR}/include ${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/language ${Anope_SOURCE_DIR}/modules/pseudoclients)
+include_directories(${Anope_BINARY_DIR}/include ${Anope_SOURCE_DIR}/include)
# Pass on REPRODUCIBLE_BUILD
if(REPRODUCIBLE_BUILD)
@@ -252,7 +77,7 @@ if(WIN32)
add_definitions(-D_WIN32)
# And include the windows specific folder for our anope_windows.h
include_directories(${Anope_SOURCE_DIR}/src/win32)
-endif(WIN32)
+endif()
# If using Visual Studio, set the C++ flags accordingly
if(MSVC)
@@ -264,105 +89,76 @@ if(MSVC)
set(CXXFLAGS "${CXXFLAGS} /W4 /wd4100 /wd4127 /wd4250 /wd4251 /wd4355 /wd4706 /wd4800 /wd4996 /EHs")
add_definitions(-DMSVCPP -D_CRT_SECURE_NO_WARNINGS)
# Otherwise, we're not using Visual Studio
-else(MSVC)
+else()
# Set the compile flags to have all warnings on (including shadowed variables)
set(CXXFLAGS "${CXXFLAGS} -Wall -Wshadow")
# If on a *nix system, also set the compile flags to remove GNU extensions (favor ISO C++) as well as reject non-ISO C++ code, also remove all leading underscores in exported symbols (only on GNU compiler)
if(UNIX)
- set(CXXFLAGS "${CXXFLAGS} -ansi -pedantic ${CMAKE_CXX_FLAGS}")
- if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set(CXXFLAGS "${CXXFLAGS} -Wno-long-long -fno-leading-underscore")
- endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- # If we aren't on a *nix system, we are using MinGW
- else(UNIX)
- # Also, if we are building under MinGW, add another define for MinGW
- if(MINGW)
- add_definitions(-DMINGW)
- endif(MINGW)
- endif(UNIX)
-endif(MSVC)
+ set(CXXFLAGS "${CXXFLAGS} -pedantic ${CMAKE_CXX_FLAGS}")
+ if(${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang")
+ set(CXXFLAGS "${CXXFLAGS} -stdlib=libc++")
+ set(LDFLAGS "${LDFLAGS} -stdlib=libc++")
+ endif()
+ endif()
+endif()
# If CMake has found that the given system requires a special library for dl* calls, include it with the linker flags
if(CMAKE_DL_LIBS)
- append_to_list(LINK_LIBS ${CMAKE_DL_LIBS})
-endif(CMAKE_DL_LIBS)
-
-# Under MinGW, the -shared flag isn't properly set in the module-specific linker flags, add it from the C flags for shared libraries
-if(MINGW)
- set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}")
-endif(MINGW)
+ list(APPEND LINK_LIBS ${CMAKE_DL_LIBS})
+endif()
if(NOT PROGRAM_NAME)
- # Under Windows, we set the executable name for Anope to be anope
- if(WIN32)
- set(PROGRAM_NAME anope)
- # Under *nix, we set the executable name for Anope to be services
- else(WIN32)
- set(PROGRAM_NAME services)
- endif(WIN32)
-endif(NOT PROGRAM_NAME)
+ set(PROGRAM_NAME anope)
+endif()
# If we are not using Visual Studio, we'll run the following checks
if(NOT MSVC)
# Check if the C++ compiler can accept the -pipe flag, and add it to the compile flags if it works
- if(CMAKE244_OR_BETTER)
- # If using CMake 2.4.4 or better, we can use check_cxx_compiler_flag
- check_cxx_compiler_flag(-pipe HAVE_PIPE_FLAG)
- else(CMAKE244_OR_BETTER)
- # If using CMake 2.4.3 or older, we will use check_cxx_accepts_flags instead
- check_cxx_accepts_flag(-pipe HAVE_PIPE_FLAG)
- endif(CMAKE244_OR_BETTER)
+ check_cxx_compiler_flag(-pipe HAVE_PIPE_FLAG)
# If the flag was accepted, add it to the list of flags
if(HAVE_PIPE_FLAG)
set(CXXFLAGS "${CXXFLAGS} -pipe")
- endif(HAVE_PIPE_FLAG)
+ endif()
# The following are additional library checks, they are not required for Windows
if(NOT WIN32)
# Check if socket is within the socket library (if the library exists), and add it to the linker flags if needed
check_library_exists(socket socket "" HAVE_SOCKET_LIB)
if(HAVE_SOCKET_LIB)
- append_to_list(LINK_LIBS socket)
- endif(HAVE_SOCKET_LIB)
+ list(APPEND LINK_LIBS socket)
+ endif()
# Check if inet_addr is within the nsl library (if the library exists), and add it to the linker flags if needed
check_library_exists(nsl inet_addr "" HAVE_NSL_LIB)
if(HAVE_NSL_LIB)
- append_to_list(LINK_LIBS nsl)
- endif(HAVE_NSL_LIB)
+ list(APPEND LINK_LIBS nsl)
+ endif()
# Check if pthread_create is within the pthread library (if the library exists), and add it to the linker flags if needed
check_library_exists(pthread pthread_create "" HAVE_PTHREAD)
if(HAVE_PTHREAD)
if(NOT APPLE)
set(LDFLAGS "${LDFLAGS} -pthread")
- endif(NOT APPLE)
- else(HAVE_PTHREAD)
+ endif()
+ else()
message(FATAL_ERROR "The pthread library is required to build Anope")
- endif(HAVE_PTHREAD)
- endif(NOT WIN32)
-endif(NOT MSVC)
+ endif()
+ endif()
+endif()
# If DEFUMASK wasn't passed to CMake, set a default depending on if RUNGROUP was passed in or not
if(NOT DEFUMASK)
if(RUNGROUP)
set(DEFUMASK "007")
- else(RUNGROUP)
+ else()
set(DEFUMASK "077")
- endif(RUNGROUP)
-endif(NOT DEFUMASK)
+ endif()
+endif()
# Set the DEBUG_BUILD for sysconf.h
if(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
set(DEBUG_BUILD TRUE)
-endif(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
-
-# Check for the existence of the following include files
-check_include_file(cstdint HAVE_CSTDINT)
-check_include_file(stdint.h HAVE_STDINT_H)
-check_include_file(strings.h HAVE_STRINGS_H)
+endif()
-# Check for the existence of the following functions
-check_function_exists(strcasecmp HAVE_STRCASECMP)
-check_function_exists(stricmp HAVE_STRICMP)
+# Check for the existance of the following functions
check_function_exists(umask HAVE_UMASK)
check_function_exists(epoll_wait HAVE_EPOLL)
check_function_exists(poll HAVE_POLL)
@@ -370,52 +166,48 @@ check_function_exists(kqueue HAVE_KQUEUE)
# Strip the leading and trailing spaces from the compile flags
if(CXXFLAGS)
- strip_string(${CXXFLAGS} CXXFLAGS)
-endif(CXXFLAGS)
+ string(STRIP ${CXXFLAGS} CXXFLAGS)
+endif()
# Strip the leading and trailing spaces from the linker flags
if(LDFLAGS)
- strip_string(${LDFLAGS} LDFLAGS)
-endif(LDFLAGS)
+ string(STRIP ${LDFLAGS} LDFLAGS)
+endif()
# Search for the following programs
-find_program(GREP grep)
-find_program(SH sh)
find_program(CHGRP chgrp)
find_program(CHMOD chmod)
-# If a INSTDIR was passed in to CMake, use it as the install prefix, otherwise set the default install prefix to the services directory under the user's home directory
-if(INSTDIR)
- set(CMAKE_INSTALL_PREFIX "${INSTDIR}")
-elseif(NOT CMAKE_INSTALL_PREFIX)
- set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/services")
-endif(INSTDIR)
+# If CMAKE_INSTALL_PREFIX was not passed in to CMake set the default install prefix to the "anope" directory under the user's home directory
+if(NOT CMAKE_INSTALL_PREFIX)
+ set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/anope")
+endif()
# Set default paths for various directories if not already defined
if(NOT BIN_DIR)
set(BIN_DIR "bin")
-endif(NOT BIN_DIR)
+endif()
if(NOT DB_DIR)
set(DB_DIR "data")
-endif(NOT DB_DIR)
+endif()
if(NOT DOC_DIR)
set(DOC_DIR "doc")
-endif(NOT DOC_DIR)
+endif()
if(NOT CONF_DIR)
set(CONF_DIR "conf")
-endif(NOT CONF_DIR)
+endif()
if(NOT LIB_DIR)
set(LIB_DIR "lib")
-endif(NOT LIB_DIR)
+endif()
if(NOT LOCALE_DIR)
set(LOCALE_DIR "locale")
-endif(NOT LOCALE_DIR)
+endif()
if(NOT LOGS_DIR)
set(LOGS_DIR "logs")
-endif(NOT LOGS_DIR)
+endif()
# Version number processing
# Find all lines in src/version.sh that start with VERSION_
-read_from_file(${Anope_SOURCE_DIR}/src/version.sh "^VERSION_" VERSIONS)
+file(STRINGS ${Anope_SOURCE_DIR}/src/version.sh VERSIONS REGEX "^VERSION_")
# Iterate through the strings found
foreach(VERSION_STR ${VERSIONS})
string(REGEX REPLACE "^VERSION_([A-Z]+)=\"?([^\"]*)\"?$" "\\1;\\2" VERSION_OUT ${VERSION_STR})
@@ -425,8 +217,8 @@ foreach(VERSION_STR ${VERSIONS})
if(${VERSION_LEN} GREATER 1)
list(GET VERSION_OUT 1 VERSION_DATA)
set(VERSION_${VERSION_TYPE} ${VERSION_DATA})
- endif(${VERSION_LEN} GREATER 1)
-endforeach(VERSION_STR ${VERSIONS})
+ endif()
+endforeach()
# Default build version to 0
set(VERSION_BUILD 0)
@@ -434,7 +226,7 @@ set(VERSION_BUILD 0)
# Only change the build number if version.h exists
if(EXISTS "${Anope_SOURCE_DIR}/include/version.h")
# Attempt to read the build number from include/version.h
- read_from_file(${Anope_SOURCE_DIR}/include/version.h "^#define VERSION_BUILD" VERSIONS)
+ file(STRINGS ${Anope_SOURCE_DIR}/include/version.h VERSIONS REGEX "^#defineVERSION_BUILD")
foreach(VERSION_STR ${VERSIONS})
# Get the length of the string
string(LENGTH ${VERSION_STR} VERSION_LEN)
@@ -444,8 +236,8 @@ if(EXISTS "${Anope_SOURCE_DIR}/include/version.h")
string(SUBSTRING ${VERSION_STR} 22 ${VERSION_NUM_LEN} VERSION)
# Set VERSION_BUILD correctly
set(VERSION_BUILD ${VERSION})
- endforeach(VERSION_STR ${VERSIONS})
-endif(EXISTS "${Anope_SOURCE_DIR}/include/version.h")
+ endforeach()
+endif()
# Set the version variables based on what was found above
set(VERSION_COMMA "${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_BUILD}")
@@ -458,7 +250,7 @@ set(VERSION_FULL_NOBUILD "${VERSION_DOTTED_NOBUILD}${VERSION_EXTRA}")
if(WIN32)
# Generate the win32.rc file using the above variables
configure_file(${Anope_SOURCE_DIR}/src/win32/win32.rc.cmake ${Anope_BINARY_DIR}/src/win32/win32.rc)
-endif(WIN32)
+endif()
# Add the initial files to ignore which will be ignored regardless of if you are building in-source or out-of-source
add_to_cpack_ignored_files(".git\;config.cache\;CMakeFiles\;sysconf.h$\;build" TRUE)
@@ -473,8 +265,8 @@ if(${Anope_SOURCE_DIR} STREQUAL ${Anope_BINARY_DIR})
# If using Visual Studio, add these files as well
if(MSVC)
add_to_cpack_ignored_files(".vcproj$\;.sln$\;.ncb$\;.suo$\;.dir$\;.ilk$\;.exp$\;.pdb$\;.lib$\;/debug$;/release$;/relwithdebinfo$;/minsizerel$" TRUE)
- endif(MSVC)
-endif(${Anope_SOURCE_DIR} STREQUAL ${Anope_BINARY_DIR})
+ endif()
+endif()
# Go into the following directories and run their CMakeLists.txt as well
add_subdirectory(data)
@@ -493,13 +285,13 @@ install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${DB_D
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LOGS_DIR}\")")
if(WIN32)
install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DB_DIR}/runtime\")")
-endif(WIN32)
+endif()
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the below directories, as well as the group of the data directory
if(NOT WIN32 AND RUNGROUP)
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/\${DB_DIR}/backups\")")
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/\${LOGS_DIR}\")")
install(CODE "execute_process(COMMAND ${CHGRP} -R ${RUNGROUP} \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}\")")
-endif(NOT WIN32 AND RUNGROUP)
+endif()
# On Windows platforms, install extra files
if(WIN32)
install(FILES ${Anope_SOURCE_DIR}/src/win32/anope.bat
@@ -509,7 +301,7 @@ if(WIN32)
# Package any DLLs in src/win/
file(GLOB EXTRA_DLLS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${Anope_SOURCE_DIR}/src/win32/*.dll")
install(FILES ${EXTRA_DLLS} DESTINATION ${BIN_DIR})
-endif(WIN32)
+endif()
install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/modules\")")
@@ -528,9 +320,9 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
# The following is primarily for NSIS
if(WIN32)
# By default, do not warn when built on machines using only VS Express:
- IF(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
- SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
- ENDIF(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ if(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
+ endif()
# Also for Windows, include installing the MSVCRT library
include(InstallRequiredSystemLibraries)
set(CPACK_GENERATOR "NSIS")
@@ -550,10 +342,10 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
set(CPACK_NSIS_INSTALLED_ICON_NAME "${SERVICES_BINARY}")
set(CPACK_NSIS_URL_INFO_ABOUT "http://www.anope.org/")
set(CPACK_NSIS_COMPRESSOR "/SOLID lzma")
- endif(WIN32)
+ endif()
set(CPACK_SOURCE_PACKAGE_FILE_NAME "anope-${VERSION_FULL_NOBUILD}-source")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES "$ENV{CPACK_IGNORED_FILES}")
set(CPACK_MONOLITHIC_INSTALL TRUE)
include(CPack)
-endif(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
+endif()
diff --git a/Config b/Config
index 13d345e57..f1cd4e317 100755
--- a/Config
+++ b/Config
@@ -2,7 +2,7 @@
#
# Configuration script for Services.
#
-# Anope (c) 2003-2016 Anope Team
+# Anope (c) 2003-2014 Anope Team
# Contact us at team@anope.org
#
# This program is free but copyrighted software; see the file COPYING for
@@ -42,10 +42,9 @@ Run_Build_System () {
WITH_PERM=""
EXTRA_INCLUDE=""
EXTRA_LIBS=""
- GEN_TYPE=""
if [ "$INSTDIR" != "" ] ; then
- WITH_INST="-DINSTDIR:STRING=$INSTDIR"
+ WITH_INST="-DCMAKE_INSTALL_PREFIX:STRING=$INSTDIR"
fi
if [ "$RUNGROUP" != "" ] ; then
@@ -57,15 +56,9 @@ Run_Build_System () {
fi
if [ "$DEBUG" = "yes" ] ; then
- BUILD_TYPE="-DCMAKE_BUILD_TYPE:STRING=DEBUG"
+ BUILD_TYPE="-DCMAKE_BUILD_TYPE:STRING=DEBUG -Wdev"
else
- BUILD_TYPE="-DCMAKE_BUILD_TYPE:STRING=RELEASE"
- fi
-
- if [ "$USE_PCH" = "yes" ] ; then
- PCH="-DUSE_PCH:BOOLEAN=ON"
- else
- PCH="-DUSE_PCH:BOOLEAN=OFF"
+ BUILD_TYPE="-DCMAKE_BUILD_TYPE:STRING=RELEASE -Wno-dev"
fi
if [ "$EXTRA_INCLUDE_DIRS" != "" ] ; then
@@ -76,12 +69,6 @@ Run_Build_System () {
EXTRA_LIBS="-DEXTRA_LIBS:STRING=$EXTRA_LIB_DIRS"
fi
- case `uname -s` in
- MINGW*)
- GEN_TYPE="-G\"MSYS Makefiles\""
- ;;
- esac
-
if [ "$SOURCE_DIR" = "." ] ; then
pwdsave=`pwd`
test -d build || mkdir build
@@ -91,9 +78,9 @@ Run_Build_System () {
REAL_SOURCE_DIR="$SOURCE_DIR"
fi
- echo "cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $PCH $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR"
+ echo "cmake $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR"
- cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $PCH $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR
+ cmake $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR
echo ""
if [ "$SOURCE_DIR" = "." ] ; then
@@ -121,11 +108,10 @@ export ECHO2 ECHO2SUF
# Init values
###########################################################################
-INSTDIR=$HOME/services
+INSTDIR=$HOME/anope
RUNGROUP=
UMASK=
DEBUG="no"
-USE_PCH="no"
EXTRA_INCLUDE_DIRS=
EXTRA_LIB_DIRS=
EXTRA_CONFIG_ARGS=
@@ -314,25 +300,6 @@ echo ""
####
-TEMP_YN="n"
-if [ "$USE_PCH" = "yes" ] ; then
- TEMP_YN="y"
-fi
-echo "Do you want to build using precompiled headers? This can speed up"
-echo "the build, but uses more disk space."
-echo2 "[$TEMP_YN] "
-read YN
-if [ "$YN" ] ; then
- if [ "$YN" = "y" ] ; then
- USE_PCH="yes"
- else
- USE_PCH="no"
- fi
-fi
-echo ""
-
-####
-
echo "Are there any extra include directories you wish to use?"
echo "You may only need to do this if CMake is unable to locate"
echo "missing dependencies without hints."
@@ -395,7 +362,6 @@ INSTDIR="$INSTDIR"
RUNGROUP="$RUNGROUP"
UMASK=$UMASK
DEBUG="$DEBUG"
-USE_PCH="$USE_PCH"
EXTRA_INCLUDE_DIRS="$EXTRA_INCLUDE_DIRS"
EXTRA_LIB_DIRS="$EXTRA_LIB_DIRS"
EXTRA_CONFIG_ARGS="$EXTRA_CONFIG_ARGS"
diff --git a/Config.exe b/Config.exe
deleted file mode 100644
index d61814427..000000000
--- a/Config.exe
+++ /dev/null
Binary files differ
diff --git a/cmake/Anope.cmake b/cmake/Anope.cmake
index f93384cc0..ccc734ed9 100644
--- a/cmake/Anope.cmake
+++ b/cmake/Anope.cmake
@@ -1,422 +1,4 @@
###############################################################################
-# strip_string(<input string> <output string>)
-#
-# A macro to handle stripping the leading and trailing spaces from a string,
-# uses string(STRIP) if using CMake 2.6.x or better, otherwise uses
-# string(REGEX REPLACE).
-###############################################################################
-macro(strip_string INPUT_STRING OUTPUT_STRING)
- if(CMAKE26_OR_BETTER)
- # For CMake 2.6.x or better, we can just use the STRIP sub-command of string()
- string(STRIP ${INPUT_STRING} ${OUTPUT_STRING})
- else(CMAKE26_OR_BETTER)
- # For CMake 2.4.x, we will have to use the REGEX REPLACE sub-command of string() instead
- # First check if the input string is empty or not
- if (${INPUT_STRING} STREQUAL "")
- set(${OUTPUT_STRING} "")
- else(${INPUT_STRING} STREQUAL "")
- # Determine if the string is entirely empty or not
- string(REGEX MATCH "^[ \t]*$" EMPTY_STRING "${INPUT_STRING}")
- if(EMPTY_STRING)
- set(${OUTPUT_STRING} "")
- else(EMPTY_STRING)
- # We detect if there is any leading whitespace and remove any if there is
- string(SUBSTRING "${INPUT_STRING}" 0 1 FIRST_CHAR)
- if(FIRST_CHAR STREQUAL " " OR FIRST_CHAR STREQUAL "\t")
- string(REGEX REPLACE "^[ \t]+" "" TEMP_STRING "${INPUT_STRING}")
- else(FIRST_CHAR STREQUAL " " OR FIRST_CHAR STREQUAL "\t")
- set(TEMP_STRING "${INPUT_STRING}")
- endif(FIRST_CHAR STREQUAL " " OR FIRST_CHAR STREQUAL "\t")
- # Next we detect if there is any trailing whitespace and remove any if there is
- string(LENGTH "${TEMP_STRING}" STRING_LEN)
- math(EXPR STRING_LEN "${STRING_LEN} - 1")
- string(SUBSTRING "${TEMP_STRING}" ${STRING_LEN} 1 LAST_CHAR)
- if(LAST_CHAR STREQUAL " " OR LAST_CHAR STREQUAL "\t")
- string(REGEX REPLACE "[ \t]+$" "" ${OUTPUT_STRING} "${TEMP_STRING}")
- else(LAST_CHAR STREQUAL " " OR LAST_CHAR STREQUAL "\t")
- set(${OUTPUT_STRING} "${TEMP_STRING}")
- endif(LAST_CHAR STREQUAL " " OR LAST_CHAR STREQUAL "\t")
- endif(EMPTY_STRING)
- endif(${INPUT_STRING} STREQUAL "")
- endif(CMAKE26_OR_BETTER)
-endmacro(strip_string)
-
-###############################################################################
-# append_to_list(<list> <args>...)
-#
-# A macro to handle appending to lists, uses list(APPEND) if using CMake 2.4.2
-# or better, otherwise uses set() instead.
-###############################################################################
-macro(append_to_list LIST)
- if(CMAKE242_OR_BETTER)
- # For CMake 2.4.2 or better, we can just use the APPEND sub-command of list()
- list(APPEND ${LIST} ${ARGN})
- else(CMAKE242_OR_BETTER)
- # For CMake 2.4.x before 2.4.2, we have to do this manually use set() instead
- set(${LIST} ${${LIST}} ${ARGN})
- endif(CMAKE242_OR_BETTER)
-endmacro(append_to_list)
-
-###############################################################################
-# find_in_list(<list> <value> <output variable>)
-#
-# A macro to handle searching within a list, will store the result in the
-# given <output variable>, uses list(FIND) if using CMake 2.6.x or better
-# (or CMake 2.4.8 or better), otherwise it iterates through the list to find
-# the item.
-###############################################################################
-macro(find_in_list LIST ITEM_TO_FIND FOUND)
- if(CMAKE248_OR_BETTER)
- # For CMake 2.4.8 or better, we can use the FIND sub-command of list()
- list(FIND ${LIST} ${ITEM_TO_FIND} ITEM_FOUND)
- else(CMAKE248_OR_BETTER)
- # For CMake 2.4.x before 2.4.8, we have to do this ourselves (NOTE: This is very slow due to a lack of break() as well)
- # Firstly we set the position to -1 indicating nothing found, we also use a temporary position
- set(ITEM_FOUND -1)
- set(POS 0)
- # Iterate through the list
- foreach(ITEM ${${LIST}})
- # If the item we are looking at is the item we are trying to find, set that we've found the item
- if(${ITEM} STREQUAL ${ITEM_TO_FIND})
- set(ITEM_FOUND ${POS})
- endif(${ITEM} STREQUAL ${ITEM_TO_FIND})
- # Increase the position value by 1
- math(EXPR POS "${POS} + 1")
- endforeach(ITEM)
- endif(CMAKE248_OR_BETTER)
- # Set the given FOUND variable to the result
- set(${FOUND} ${ITEM_FOUND})
-endmacro(find_in_list)
-
-###############################################################################
-# remove_list_duplicates(<list>)
-#
-# A macro to handle removing duplicates from a list, uses
-# list(REMOVE_DUPLICATES) if using CMake 2.6.x or better, otherwise it uses
-# a slower method of creating a temporary list and only adding to it when
-# a duplicate item hasn't been found.
-###############################################################################
-macro(remove_list_duplicates LIST)
- if(CMAKE26_OR_BETTER)
- # For CMake 2.6.x or better, this can be done automatically
- list(REMOVE_DUPLICATES ${LIST})
- else(CMAKE26_OR_BETTER)
- # For CMake 2.4.x, we have to do this ourselves, firstly we'll clear a temporary list
- set(NEW_LIST)
- # Iterate through the old list
- foreach(ITEM ${${LIST}})
- # Check if the item is in the new list
- find_in_list(NEW_LIST ${ITEM} FOUND_ITEM)
- if(FOUND_ITEM EQUAL -1)
- # If the item was not found, append it to the list
- append_to_list(NEW_LIST ${ITEM})
- endif(FOUND_ITEM EQUAL -1)
- endforeach(ITEM)
- # Replace the old list with the new list
- set(${LIST} ${NEW_LIST})
- endif(CMAKE26_OR_BETTER)
-endmacro(remove_list_duplicates)
-
-###############################################################################
-# remove_item_from_list(<list> <value>)
-#
-# A macro to handle removing a value from a list, uses list(REMOVE_ITEM) in
-# both cases, but can remove the value itself using CMake 2.4.2 or better,
-# while older versions use a slower method of iterating the list to find the
-# index of the value to remove.
-###############################################################################
-macro(remove_item_from_list LIST VALUE)
- if(CMAKE242_OR_BETTER)
- # For CMake 2.4.2 or better, this can be done automatically
- list(REMOVE_ITEM ${LIST} ${VALUE})
- else(CMAKE242_OR_BETTER)
- # For CMake 2.4.x before 2.4.2, we have to do this ourselves, firstly we set the index and a variable to indicate if the item was found
- set(INDEX 0)
- set(FOUND FALSE)
- # Iterate through the old list
- foreach(ITEM ${${LIST}})
- # If the item hasn't been found yet, but the current item is the same, remove it
- if(NOT FOUND)
- if(ITEM STREQUAL ${VALUE})
- set(FOUND TRUE)
- list(REMOVE_ITEM ${LIST} ${INDEX})
- endif(ITEM STREQUAL ${VALUE})
- endif(NOT FOUND)
- # Increase the index value by 1
- math(EXPR INDEX "${INDEX} + 1")
- endforeach(ITEM)
- endif(CMAKE242_OR_BETTER)
-endmacro(remove_item_from_list)
-
-###############################################################################
-# sort_list(<list>)
-#
-# A macro to handle sorting a list, uses list(SORT) if using CMake 2.4.4 or
-# better, otherwise it uses a slower method of creating a temporary list and
-# adding elements in alphabetical order.
-###############################################################################
-macro(sort_list LIST)
- if(CMAKE244_OR_BETTER)
- # For CMake 2.4.4 or better, this can be done automatically
- list(SORT ${LIST})
- else(CMAKE244_OR_BETTER)
- # For CMake 2.4.x before 2.4.4, we have to do this ourselves, firstly we'll create a teporary list
- set(NEW_LIST)
- # Iterate through the old list
- foreach(ITEM ${${LIST}})
- # Temporary index position for the new list, as well as temporary value to store if the item was ever found
- set(INDEX 0)
- set(FOUND FALSE)
- # Iterate through the new list
- foreach(NEW_ITEM ${NEW_LIST})
- # Compare the items, only if nothing was found before
- if(NOT FOUND)
- if(NEW_ITEM STRGREATER "${ITEM}")
- set(FOUND TRUE)
- list(INSERT NEW_LIST ${INDEX} ${ITEM})
- endif(NEW_ITEM STRGREATER "${ITEM}")
- endif(NOT FOUND)
- # Increase the index value by 1
- math(EXPR INDEX "${INDEX} + 1")
- endforeach(NEW_ITEM)
- # If the item was never found, just append it to the end
- if(NOT FOUND)
- append_to_list(NEW_LIST ${ITEM})
- endif(NOT FOUND)
- endforeach(ITEM)
- # Replace the old list with the new list
- set(${LIST} ${NEW_LIST})
- endif(CMAKE244_OR_BETTER)
-endmacro(sort_list)
-
-###############################################################################
-# read_from_file(<filename> <regex> <output variable>)
-#
-# A macro to handle reading specific lines from a file, uses file(STRINGS) if
-# using CMake 2.6.x or better, otherwise we read in the entire file and
-# perform a string(REGEX MATCH) on each line of the file instead. This
-# macro can also be used to read in all the lines of a file if REGEX is set
-# to "".
-###############################################################################
-macro(read_from_file FILE REGEX STRINGS)
- if(CMAKE26_OR_BETTER)
- # For CMake 2.6.x or better, we can just use the STRINGS sub-command to get the lines that match the given regular expression (if one is given, otherwise get all lines)
- if(REGEX STREQUAL "")
- file(STRINGS ${FILE} RESULT)
- else(REGEX STREQUAL "")
- file(STRINGS ${FILE} RESULT REGEX ${REGEX})
- endif(REGEX STREQUAL "")
- else(CMAKE26_OR_BETTER)
- # For CMake 2.4.x, we need to do this manually, firstly we read the file in
- execute_process(COMMAND ${CMAKE_COMMAND} -DFILE:STRING=${FILE} -P ${Anope_SOURCE_DIR}/cmake/ReadFile.cmake ERROR_VARIABLE ALL_STRINGS)
- # Next we replace all newlines with semicolons
- string(REGEX REPLACE "\n" ";" ALL_STRINGS ${ALL_STRINGS})
- if(REGEX STREQUAL "")
- # For no regular expression, just set the result to all the lines
- set(RESULT ${ALL_STRINGS})
- else(REGEX STREQUAL "")
- # Clear the result list
- set(RESULT)
- # Iterate through all the lines of the file
- foreach(STRING ${ALL_STRINGS})
- # Check for a match against the given regular expression
- string(REGEX MATCH ${REGEX} STRING_MATCH ${STRING})
- # If we had a match, append the match to the list
- if(STRING_MATCH)
- append_to_list(RESULT ${STRING})
- endif(STRING_MATCH)
- endforeach(STRING)
- endif(REGEX STREQUAL "")
- endif(CMAKE26_OR_BETTER)
- # Set the given STRINGS variable to the result
- set(${STRINGS} ${RESULT})
-endmacro(read_from_file)
-
-###############################################################################
-# extract_include_filename(<line> <output variable> [<optional output variable of quote type>])
-#
-# This macro will take a #include line and extract the filename.
-###############################################################################
-macro(extract_include_filename INCLUDE FILENAME)
- # Strip the leading and trailing spaces from the include line
- strip_string(${INCLUDE} INCLUDE_STRIPPED)
- # Make sure to only do the following if there is a string
- if(INCLUDE_STRIPPED STREQUAL "")
- set(FILE "")
- else(INCLUDE_STRIPPED STREQUAL "")
- # Extract the filename including the quotes or angle brackets
- string(REGEX REPLACE "^.*([\"<].*[\">]).*$" "\\1" FILE "${INCLUDE_STRIPPED}")
- # If an optional 3rd argument is given, we'll store if the quote style was quoted or angle bracketed
- if(${ARGC} GREATER 2)
- string(SUBSTRING ${FILE} 0 1 QUOTE)
- if(QUOTE STREQUAL "<")
- set(${ARGV2} "angle brackets")
- else(QUOTE STREQUAL "<")
- set(${ARGV2} "quotes")
- endif(QUOTE STREQUAL "<")
- endif(${ARGC} GREATER 2)
- # Now remove the quotes or angle brackets
- string(REGEX REPLACE "^[\"<](.*)[\">]$" "\\1" FILE "${FILE}")
- endif(INCLUDE_STRIPPED STREQUAL "")
- # Set the filename to the the given variable
- set(${FILENAME} "${FILE}")
-endmacro(extract_include_filename)
-
-###############################################################################
-# find_includes(<source filename> <output variable>)
-#
-# This macro will search through a file for #include lines, regardless of
-# whitespace, but only returns the lines that are valid for the current
-# platform CMake is running on.
-###############################################################################
-macro(find_includes SRC INCLUDES)
- # Read all lines from the file that start with #, regardless of whitespace before the #
- read_from_file(${SRC} "^[ \t]*#.*$" LINES)
- # Set that any #include lines found are valid, and create temporary variables for the last found #ifdef/#ifndef
- set(VALID_LINE TRUE)
- set(LAST_DEF)
- set(LAST_CHECK)
- # Create an empty include list
- set(INCLUDES_LIST)
- # Iterate through all the # lines
- foreach(LINE ${LINES})
- # Search for #ifdef, #ifndef, #else, #endif, and #include
- string(REGEX MATCH "^[ \t]*#[ \t]*ifdef[ \t]*.*$" FOUND_IFDEF ${LINE})
- string(REGEX MATCH "^[ \t]*#[ \t]*ifndef[ \t]*.*$" FOUND_IFNDEF ${LINE})
- string(REGEX MATCH "^[ \t]*#[ \t]*else.*$" FOUND_ELSE ${LINE})
- string(REGEX MATCH "^[ \t]*#[ \t]*endif.*$" FOUND_ENDIF ${LINE})
- string(REGEX MATCH "^[ \t]*#[ \t]*include[ \t]*[\"<].*[\">][\ t]*.*$" FOUND_INCLUDE ${LINE})
- # If we found a #ifdef on the line, extract the data after the #ifdef and set if the lines after it are valid based on the variables in CMake
- if(FOUND_IFDEF)
- # Extract the define
- string(REGEX REPLACE "^[ \t]*#[ \t]*ifdef[ \t]*(.*)$" "\\1" DEFINE ${LINE})
- # Replace _WIN32 with WIN32, so we can check if the WIN32 variable of CMake is set instead of _WIN32
- if(DEFINE STREQUAL "_WIN32")
- set(DEFINE WIN32)
- endif(DEFINE STREQUAL "_WIN32")
- # Set the last define to this one, and set the last check to true, so when #else is encountered, we can do an opposing check
- set(LAST_DEF ${DEFINE})
- set(LAST_CHECK TRUE)
- # If the define is true (it either exists or is a non-false result), the lines following will be checked, otherwise they will be skipped
- if(${DEFINE})
- set(VALID_LINE TRUE)
- else(${DEFINE})
- set(VALID_LINE FALSE)
- endif(${DEFINE})
- else(FOUND_IFDEF)
- # If we found a #ifndef on the line, the same thing as #ifdef is done, except with the checks in the opposite direction
- if(FOUND_IFNDEF)
- # Extract the define
- string(REGEX REPLACE "^[ \t]*#[ \t]*ifndef[ \t]*(.*)$" "\\1" DEFINE ${LINE})
- # Replace _WIN32 with WIN32, so we can check if the WIN32 variable of CMake is set instead of _WIN32
- if(DEFINE STREQUAL "_WIN32")
- set(DEFINE WIN32)
- endif(DEFINE STREQUAL "_WIN32")
- # Set the last define to this one, and set the last check to false, so when #else is encountered, we can do an opposing check
- set(LAST_DEF ${DEFINE})
- set(LAST_CHECK FALSE)
- # If the define is not true (it either doesn't exists or is a false result), the lines following will be checked, otherwise they will be skipped
- if(${DEFINE})
- set(VALID_LINE FALSE)
- else(${DEFINE})
- set(VALUE_LINE TRUE)
- endif(${DEFINE})
- else(FOUND_IFNDEF)
- # If we found a #else on the line, we check the last define in the opposite direction
- if(FOUND_ELSE)
- # When LAST_CHECK is true, we were inside a #ifdef, now act as if we are entering a #ifndef section by doing an opposing check
- if(LAST_CHECK)
- if(${LAST_DEF})
- set(VALID_LINE FALSE)
- else(${LAST_DEF})
- set(VALID_LINE TRUE)
- endif(${LAST_DEF})
- # When LAST_CHECK is false, we were inside a #ifndef, now act as if we are entering a #ifdef section by doing an opposing check
- else(LAST_CHECK)
- if(${LAST_DEF})
- set(VALID_LINE TRUE)
- else(${LAST_DEF})
- set(VALID_LINE FALSE)
- endif(${LAST_DEF})
- endif(LAST_CHECK)
- else(FOUND_ELSE)
- # If we found a #endif on the line, we'll assume everything following the line is valid until we meet another one of the above lines
- if(FOUND_ENDIF)
- set(VALID_LINE TRUE)
- else(FOUND_ENDIF)
- # If we found a #include on the line, add the entire line to the list of includes unless the line isn't valid
- if(FOUND_INCLUDE)
- if(VALID_LINE)
- append_to_list(INCLUDES_LIST "${LINE}")
- endif(VALID_LINE)
- endif(FOUND_INCLUDE)
- endif(FOUND_ENDIF)
- endif(FOUND_ELSE)
- endif(FOUND_IFNDEF)
- endif(FOUND_IFDEF)
- endforeach(LINE)
- set(${INCLUDES} ${INCLUDES_LIST})
-endmacro(find_includes)
-
-###############################################################################
-# calculate_depends(<source filename> [<optional output variable for includes>])
-#
-# This macro is used in most of the src (sub)directories to calculate the
-# header file dependencies for the given source file.
-###############################################################################
-macro(calculate_depends SRC)
- # Temporarily set that we didn't get a 3rd argument before we actually check if we did get one or not
- set(CHECK_ANGLE_INCLUDES FALSE)
- # Check for a third argument
- if(${ARGC} GREATER 1)
- set(CHECK_ANGLE_INCLUDES TRUE)
- endif(${ARGC} GREATER 1)
- # Find all the lines in the given source file that have any form of #include on them, regardless of whitespace, but only if they are valid for the platform we are on
- find_includes(${SRC} INCLUDES)
- # Reset the list of headers to empty
- set(HEADERS)
- # Iterate through the strings containing #include (if any)
- foreach(INCLUDE ${INCLUDES})
- # Extract the filename from the #include line
- extract_include_filename(${INCLUDE} FILENAME QUOTE_TYPE)
- if(QUOTE_TYPE STREQUAL "angle brackets")
- # The following checks will only be done if there was a request for angle includes to be checked
- if(CHECK_ANGLE_INCLUDES)
- # Find the path of the include file
- if(DEFAULT_INCLUDE_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
- find_path(FOUND_${FILENAME}_INCLUDE NAMES ${FILENAME} PATHS ${DEFAULT_INCLUDE_DIRS} ${WSDK_PATH}/include $ENV{VCINSTALLDIR}/include ${EXTRA_INCLUDE})
- else(DEFAULT_INCLUDE_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
- find_path(FOUND_${FILENAME}_INCLUDE NAMES ${FILENAME} ${EXTRA_INCLUDE})
- endif(DEFAULT_INCLUDE_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
- # If the include file was found, add it's path to the list of include paths, but only if it doesn't already exist and isn't in the defaults for the compiler
- if(FOUND_${FILENAME}_INCLUDE)
- # This used to be find_in_list, but it was changed to this loop to do a find on each default include directory, this fixes Mac OS X trying to get it's framework directories in here
- set(FOUND_IN_DEFAULTS -1)
- foreach(DEFAULT_INCLUDE_DIR ${DEFAULT_INCLUDE_DIRS})
- string(REGEX REPLACE "\\+" "\\\\+" DEFAULT_INCLUDE_DIR ${DEFAULT_INCLUDE_DIR})
- string(REGEX MATCH ${DEFAULT_INCLUDE_DIR} FOUND_DEFAULT ${FOUND_${FILENAME}_INCLUDE})
- if(FOUND_DEFAULT)
- set(FOUND_IN_DEFAULTS 0)
- endif(FOUND_DEFAULT)
- endforeach(DEFAULT_INCLUDE_DIR)
- if(FOUND_IN_DEFAULTS EQUAL -1)
- find_in_list(${ARGV1} "${FOUND_${FILENAME}_INCLUDE}" FOUND_IN_INCLUDES)
- if(FOUND_IN_INCLUDES EQUAL -1)
- append_to_list(${ARGV1} "${FOUND_${FILENAME}_INCLUDE}")
- endif(FOUND_IN_INCLUDES EQUAL -1)
- endif(FOUND_IN_DEFAULTS EQUAL -1)
- else(FOUND_${FILENAME}_INCLUDE)
- # XXX
- if(NOT ${FILENAME} STREQUAL "libintl.h")
- message(FATAL_ERROR "${SRC} needs header file ${FILENAME} but we were unable to locate that header file! Check that the header file is within the search path of your OS.")
- endif(NOT ${FILENAME} STREQUAL "libintl.h")
- endif(FOUND_${FILENAME}_INCLUDE)
- endif(CHECK_ANGLE_INCLUDES)
- endif(QUOTE_TYPE STREQUAL "angle brackets")
- endforeach(INCLUDE)
-endmacro(calculate_depends)
-
-###############################################################################
# calculate_libraries(<source filename> <output variable for linker flags> <output variable for extra depends>)
#
# This macro is used in most of the module (sub)directories to calculate the
@@ -433,10 +15,10 @@ macro(calculate_libraries SRC SRC_LDFLAGS EXTRA_DEPENDS)
set(LIBRARIES)
# Check to see if there are any lines matching: /* RequiredLibraries: [something] */
if(WIN32)
- read_from_file(${SRC} "/\\\\*[ \t]*RequiredWindowsLibraries:[ \t]*.*[ \t]*\\\\*/" REQUIRED_LIBRARIES)
- else(WIN32)
- read_from_file(${SRC} "/\\\\*[ \t]*RequiredLibraries:[ \t]*.*[ \t]*\\\\*/" REQUIRED_LIBRARIES)
- endif(WIN32)
+ file(STRINGS ${SRC} REQUIRED_LIBRARIES REGEX "/\\*[ \t]*RequiredWindowsLibraries:[ \t]*.*[ \t]*\\*/")
+ else()
+ file(STRINGS ${SRC} REQUIRED_LIBRARIES REGEX "/\\*[ \t]*RequiredLibraries:[ \t]*.*[ \t]*\\*/")
+ endif()
# Iterate through those lines
foreach(REQUIRED_LIBRARY ${REQUIRED_LIBRARIES})
# Strip off the /* RequiredLibraries: and */ from the line
@@ -446,82 +28,44 @@ macro(calculate_libraries SRC SRC_LDFLAGS EXTRA_DEPENDS)
# Iterate through the libraries given
foreach(LIBRARY ${REQUIRED_LIBRARY})
# Locate the library to see if it exists
- if(DEFAULT_LIBRARY_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
- find_library(FOUND_${LIBRARY}_LIBRARY NAMES ${LIBRARY} PATHS ${DEFAULT_LIBRARY_DIRS} ${WSDK_PATH}/lib $ENV{VCINSTALLDIR}/lib ${EXTRA_INCLUDE} ${EXTRA_LIBS})
- else(DEFAULT_LIBRARY_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
- find_library(FOUND_${LIBRARY}_LIBRARY NAMES ${LIBRARY} PATHS ${EXTRA_INCLUDE} ${EXTRA_LIBS} NO_DEFAULT_PATH)
- find_library(FOUND_${LIBRARY}_LIBRARY NAMES ${LIBRARY} PATHS ${EXTRA_INCLUDE} ${EXTRA_LIBS})
- endif(DEFAULT_LIBRARY_DIRS OR WSDK_PATH OR DEFINED $ENV{VCINSTALLDIR})
+ find_library(FOUND_${LIBRARY}_LIBRARY NAMES ${LIBRARY} PATHS $ENV{VCINSTALLDIR}/lib ${EXTRA_INCLUDE} ${EXTRA_LIBS})
# If the library was found, we will add it to the linker flags
if(FOUND_${LIBRARY}_LIBRARY)
# Get the path only of the library, to add it to linker flags
get_filename_component(LIBRARY_PATH ${FOUND_${LIBRARY}_LIBRARY} PATH)
if(MSVC)
# For Visual Studio, instead of editing the linker flags, we'll add the library to a separate list of extra dependencies
- append_to_list(EXTRA_DEPENDENCIES "${FOUND_${LIBRARY}_LIBRARY}")
- else(MSVC)
+ list(APPEND EXTRA_DEPENDENCIES "${FOUND_${LIBRARY}_LIBRARY}")
+ else()
# For all others, add the library paths and libraries
- append_to_list(LIBRARY_PATHS "${LIBRARY_PATH}")
- append_to_list(LIBRARIES "${LIBRARY}")
- endif(MSVC)
- else(FOUND_${LIBRARY}_LIBRARY)
+ list(APPEND LIBRARY_PATHS "${LIBRARY_PATH}")
+ list(APPEND LIBRARIES "${LIBRARY}")
+ endif()
+ else()
# In the case of the library not being found, we fatally error so CMake stops trying to generate
message(FATAL_ERROR "${SRC} needs library ${LIBRARY} but we were unable to locate that library! Check that the library is within the search path of your OS.")
- endif(FOUND_${LIBRARY}_LIBRARY)
- endforeach(LIBRARY)
- endforeach(REQUIRED_LIBRARY)
+ endif()
+ endforeach()
+ endforeach()
# Remove duplicates from the library paths
if(LIBRARY_PATHS)
- remove_list_duplicates(LIBRARY_PATHS)
- endif(LIBRARY_PATHS)
+ list(REMOVE_DUPLICATES LIBRARY_PATHS)
+ endif()
# Remove diplicates from the libraries
if(LIBRARIES)
- remove_list_duplicates(LIBRARIES)
- endif(LIBRARIES)
+ list(REMOVE_DUPLICATES LIBRARIES)
+ endif()
# Iterate through library paths and add them to the linker flags
foreach(LIBRARY_PATH ${LIBRARY_PATHS})
- find_in_list(DEFAULT_LIBRARY_DIRS "${LIBRARY_PATH}" FOUND_IN_DEFAULTS)
- if(FOUND_IN_DEFAULTS EQUAL -1)
- set(THIS_LDFLAGS "${THIS_LDFLAGS} -L${LIBRARY_PATH}")
- endif(FOUND_IN_DEFAULTS EQUAL -1)
- endforeach(LIBRARY_PATH)
+ set(THIS_LDFLAGS "${THIS_LDFLAGS} -L${LIBRARY_PATH}")
+ endforeach()
# Iterate through libraries and add them to the linker flags
foreach(LIBRARY ${LIBRARIES})
- append_to_list(EXTRA_DEPENDENCIES "${LIBRARY}")
- endforeach(LIBRARY)
+ list(APPEND EXTRA_DEPENDENCIES "${LIBRARY}")
+ endforeach()
set(${SRC_LDFLAGS} "${THIS_LDFLAGS}")
set(${EXTRA_DEPENDS} "${EXTRA_DEPENDENCIES}")
-endmacro(calculate_libraries)
-
-###############################################################################
-# check_functions(<source filename> <output variable set to TRUE on success>)
-#
-# This macro is used in most of the module (sub)directories to calculate the
-# fcuntion dependencies for the given source file.
-###############################################################################
-macro(check_functions SRC SUCCESS)
- # Default to true
- set(${SUCCESS} TRUE)
- # Check to see if there are any lines matching: /* RequiredFunctions: [something] */
- read_from_file(${SRC} "/\\\\*[ \t]*RequiredFunctions:[ \t]*.*[ \t]*\\\\*/" REQUIRED_FUNCTIONS)
- # Iterate through those lines
- foreach(REQUIRED_FUNCTION ${REQUIRED_FUNCTIONS})
- # Strip off the /* RequiredFunctions: and */ from the line
- string(REGEX REPLACE "/\\*[ \t]*RequiredFunctions:[ \t]*([^ \t]*)[ \t]*\\*/" "\\1" REQUIRED_FUNCTION ${REQUIRED_FUNCTION})
- # Replace all commas with semicolons
- string(REGEX REPLACE "," ";" REQUIRED_FUNCTION ${REQUIRED_FUNCTION})
- # Iterate through the functions given
- foreach(FUNCTION ${REQUIRED_FUNCTION})
- # Check if the function exists
- check_function_exists(${REQUIRED_FUNCTION} HAVE_${REQUIRED_FUNCTION})
- # If we don't have the function warn the user and set SUCCESS to FALSE
- if(NOT HAVE_${REQUIRED_FUNCTION})
- message("${SRC} needs function ${REQUIRED_FUNCTION} but we were unable to locate that function!")
- set(${SUCCESS} FALSE)
- endif(NOT HAVE_${REQUIRED_FUNCTION})
- endforeach(FUNCTION)
- endforeach(REQUIRED_FUNCTION)
-endmacro(check_functions)
+endmacro()
###############################################################################
# add_to_cpack_ignored_files(<item> [TRUE])
@@ -536,12 +80,27 @@ macro(add_to_cpack_ignored_files ITEM)
# If we have 2+ arguments, assume that the second one was something like TRUE (doesn't matter really) and convert periods so they will be \\. for CPack
if(${ARGC} GREATER 1)
string(REPLACE "." "\\\\." REAL_ITEM ${REAL_ITEM})
- endif(${ARGC} GREATER 1)
+ endif()
# If the environment variable is already defined, just tack the item to the end
if(DEFINED ENV{CPACK_IGNORED_FILES})
set(ENV{CPACK_IGNORED_FILES} "$ENV{CPACK_IGNORED_FILES};${REAL_ITEM}")
# Otherwise set the environment variable to the item
- else(DEFINED ENV{CPACK_IGNORED_FILES})
+ else()
set(ENV{CPACK_IGNORED_FILES} "${REAL_ITEM}")
- endif(DEFINED ENV{CPACK_IGNORED_FILES})
-endmacro(add_to_cpack_ignored_files)
+ endif()
+endmacro()
+
+macro(calculate_dependencies SRC DEPENDENCIES)
+ file(STRINGS ${SRC} REQUIRED_LIBRARIES REGEX "/\\*[ \t]*Dependencies:[ \t]*.*[ \t]*\\*/")
+ # Iterate through those lines
+ foreach(REQUIRED_LIBRARY ${REQUIRED_LIBRARIES})
+ string(REGEX REPLACE "/\\*[ \t]*Dependencies:[ \t]*([^ \t]*)[ \t]*\\*/" "\\1" REQUIRED_LIBRARY ${REQUIRED_LIBRARY})
+ # Replace all commas with semicolons
+ string(REGEX REPLACE "," ";" REQUIRED_LIBRARY ${REQUIRED_LIBRARY})
+ # Iterate through the libraries given
+ foreach(LIBRARY ${REQUIRED_LIBRARY})
+ list(APPEND ${DEPENDENCIES} "${LIBRARY}")
+ endforeach()
+ endforeach()
+endmacro()
+
diff --git a/cmake/FindGettext.cmake b/cmake/FindGettext.cmake
index 975294d21..b0f4f9486 100644
--- a/cmake/FindGettext.cmake
+++ b/cmake/FindGettext.cmake
@@ -7,20 +7,20 @@ if(NOT WIN32)
set(GETTEXT_FOUND TRUE)
if(GETTEXT_LIBRARY)
set(GETTEXT_LIBRARIES ${GETTEXT_LIBRARY})
- endif(GETTEXT_LIBRARY)
- endif(GETTEXT_INCLUDE AND GETTEXT_MSGFMT)
-else(NOT WIN32)
+ endif()
+ endif()
+else()
find_path(GETTEXT_INCLUDE libintl.h ${DEFAULT_INCLUDE_DIRS} ${WSDK_PATH}/include $ENV{VCINSTALLDIR}/include gettext/include ${EXTRA_INCLUDE})
find_library(GETTEXT_LIBRARY libintl PATHS ${DEFAULT_LIBRARY_DIRS} ${WSDK_PATH}/lib $ENV{VCINSTALLDIR}/lib gettext/lib ${EXTRA_LIBS})
find_program(GETTEXT_MSGFMT msgfmt PATHS ${DEFAULT_INCLUDE_DIRS} ${WSDK_PATH}/bin $ENV{VCINSTALLDIR}/bin gettext/bin ${EXTRA_INCLUDE})
if(GETTEXT_INCLUDE AND GETTEXT_LIBRARY AND GETTEXT_MSGFMT)
set(GETTEXT_FOUND TRUE)
set(GETTEXT_LIBRARIES ${GETTEXT_LIBRARY})
- endif(GETTEXT_INCLUDE AND GETTEXT_LIBRARY AND GETTEXT_MSGFMT)
-endif(NOT WIN32)
+ endif()
+endif()
# If we found everything we need set variables correctly for lang/CMakeLists.txt to use
if(GETTEXT_FOUND)
include_directories("${GETTEXT_INCLUDE}")
set(GETTEXT_MSGFMT_EXECUTABLE ${GETTEXT_MSGFMT})
-endif(GETTEXT_FOUND)
+endif()
diff --git a/cmake/ReadFile.cmake b/cmake/ReadFile.cmake
deleted file mode 100644
index be60f1fa7..000000000
--- a/cmake/ReadFile.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is external to the read_from_file macro in Anope.cmake in order to
-# get around a possible memory leak in older versions of CMake.
-
-file(READ "${FILE}" RESULT)
-message("${RESULT}")
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
index 8bb635dcf..2515bc082 100644
--- a/data/CMakeLists.txt
+++ b/data/CMakeLists.txt
@@ -1,6 +1,4 @@
-# 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 botserv.example.conf example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf)
-install(FILES ${DATA}
+file(GLOB DATA_EXAMPLECONFS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.conf")
+install(FILES example.chk ${DATA_EXAMPLECONFS}
DESTINATION ${CONF_DIR}
)
diff --git a/data/example.conf b/data/anope.example.conf
index 763eed4c7..2391f19ec 100644
--- a/data/example.conf
+++ b/data/anope.example.conf
@@ -1,8 +1,8 @@
/*
- * Example configuration file for Services. After making the appropriate
- * changes to this file, place it in the Services conf directory (as
- * specified in the "configure" script, default /home/username/services/conf)
- * under the name "services.conf".
+ * Example configuration file for Anope. After making the appropriate
+ * changes to this file, place it in the Anope conf directory (as
+ * specified in the "configure" script, default /home/username/anope/conf)
+ * under the name "anope.conf".
*
* The format of this file is fairly simple: three types of comments are supported:
* - All text after a '#' on a line is ignored, as in shell scripting
@@ -53,7 +53,7 @@
* included to indicate whether an option is required:
*
* [REQUIRED]
- * Indicates a directive which must be given. Without it, Services will
+ * Indicates a directive which must be given. Without it, Anope will
* not start.
*
* [RECOMMENDED]
@@ -71,7 +71,7 @@
*
* [DEPRECATED]
* Indicates a directive which will disappear in a future version of
- * Services, usually because its functionality has been either
+ * Anope, usually because its functionality has been either
* superseded by that of other directives or incorporated into the main
* program.
*/
@@ -110,7 +110,7 @@ define
#include
{
type = "executable"
- name = "/usr/bin/wget -q -O - http://some.misconfigured.network.com/services.conf"
+ name = "/usr/bin/wget -q -O - http://some.misconfigured.network.com/anope.conf"
}
/*
@@ -120,7 +120,7 @@ define
* This section can be included multiple times, and Anope will attempt to
* connect to each server until it finally connects.
*
- * Each uplink IRCd should have a corresponding configuration to allow Services
+ * Each uplink IRCd should have a corresponding configuration to allow services
* to link to it.
*
* An example configuration for InspIRCd that is compatible with the below uplink
@@ -154,20 +154,20 @@ define
uplink
{
/*
- * The IP or hostname of the IRC server you wish to connect Services to.
- * Usually, you will want to connect Services over 127.0.0.1 (aka localhost).
+ * The IP or hostname of the IRC server you wish to connect Anope to.
+ * Usually, you will want to connect over 127.0.0.1 (aka localhost).
*
* NOTE: On some shell providers, this will not be an option.
*/
host = "127.0.0.1"
/*
- * Enable if Services should connect using IPv6.
+ * Enable if Anope should connect using IPv6.
*/
ipv6 = no
/*
- * Enable if Services should connect using SSL.
+ * Enable if Anope should connect using SSL.
* You must have an SSL module loaded for this to work.
*/
ssl = no
@@ -193,12 +193,12 @@ uplink
/*
* [REQUIRED] Server Information
*
- * This section contains information about the Services server.
+ * This section contains information about the services server.
*/
serverinfo
{
/*
- * The hostname that Services will be seen as, it must have no conflicts with any
+ * The hostname that services will be seen as, it must have no conflicts with any
* other server names on the rest of your IRC network. Note that it does not have
* to be an existing hostname, just one that isn't on your network already.
*/
@@ -208,11 +208,11 @@ serverinfo
* The text which should appear as the server's information in /whois and similar
* queries.
*/
- description = "Services for IRC Networks"
+ description = "Anope IRC Services"
/*
- * The local address that Services will bind to before connecting to the remote
- * server. This may be useful for multihomed hosts. If omitted, Services will let
+ * The local address that services will bind to before connecting to the remote
+ * server. This may be useful for multihomed hosts. If omitted, services will let
* the Operating System choose the local address. This directive is optional.
*
* If you don't know what this means or don't need to use it, just leave this
@@ -228,86 +228,69 @@ serverinfo
#id = "00A"
/*
- * The filename containing the Services process ID. The path is relative to the
+ * The filename containing the Anope process ID. The path is relative to the
* services root directory.
*/
- pid = "data/services.pid"
+ pid = "data/anope.pid"
/*
* The filename containing the Message of the Day. The path is relative to the
* services root directory.
*/
- motd = "conf/services.motd"
+ motd = "conf/motd.txt"
}
/*
- * [REQUIRED] Protocol module
+ * [REQUIRED] Protocol configuration.
*
* This directive tells Anope which IRCd Protocol to speak when connecting.
- * You MUST modify this to match the IRCd you run.
+ * You MUST modify this to match the IRCd you run. You may want to modify
+ * the protocol configuration file to tune protocol specific features.
*
* Supported:
* - bahamut
* - charybdis
* - hybrid
- * - inspircd12
* - inspircd20
* - ngircd
* - plexus
* - ratbox
- * - unreal (for 3.2.x)
- * - unreal4
+ * - unreal
*/
-module
+include
{
- name = "inspircd20"
-
- /*
- * Some protocol modules can enforce mode locks server-side. This reduces the spam caused by
- * services immediately reversing mode changes for locked modes.
- *
- * If the protocol module you have loaded does not support this, this setting will have no effect.
- */
- use_server_side_mlock = yes
-
- /*
- * Some protocol modules can enforce topic locks server-side. This reduces the spam caused by
- * services immediately reversing topic changes.
- *
- * If the protocol module you have loaded does not support this, this setting will have no effect.
- */
- use_server_side_topiclock = yes
+ name = "inspircd20.example.conf"
}
/*
* [REQUIRED] Network Information
*
- * This section contains information about the IRC network that Services will be
+ * This section contains information about the IRC network that Anope will be
* connecting to.
*/
networkinfo
{
/*
- * This is the name of the network that Services will be running on.
+ * This is the name of the network that Anope will be running on.
*/
networkname = "LocalNet"
/*
* Set this to the maximum allowed nick length on your network.
* Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
+ * services being disconnected from the network.
*/
nicklen = 31
/* Set this to the maximum allowed ident length on your network.
* Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
+ * services being disconnected from the network.
*/
userlen = 10
/* Set this to the maximum allowed hostname length on your network.
* Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
+ * services being disconnected from the network.
*/
hostlen = 64
@@ -323,7 +306,7 @@ networkinfo
/*
* Characters allowed in nicknames. This always includes the characters described
* in RFC1459, and so does not need to be set for normal behavior. Changing this to
- * include characters your IRCd doesn't support will cause your IRCd and/or Services
+ * include characters your IRCd doesn't support will cause your IRCd and/or services
* to break. Multibyte characters are not supported, nor are escape sequences.
*
* It is recommended you DON'T change this.
@@ -335,7 +318,7 @@ networkinfo
* to services, such as BotServ bot hostnames and user vhosts. Changing this is not
* recommended unless you know for sure your IRCd supports whatever characters you are
* wanting to use. Telling services to set a vHost containing characters your IRCd
- * disallows could potentially break the IRCd and/or Services.
+ * disallows could potentially break the IRCd and/or services.
*
* It is recommended you DON'T change this.
*/
@@ -360,32 +343,43 @@ networkinfo
}
/*
- * [REQUIRED] Services Options
+ * [REQUIRED] Anope Options
*
- * This section contains various options which determine how Services will operate.
+ * This section contains various options which determine how Anope will operate.
*/
options
{
/*
* On Linux/UNIX systems Anope can setuid and setgid to this user and group
- * after starting up. This is useful if Anope has to bind to privileged ports
+ * after starting up. This is useful if Anope has to bind to privileged ports.
*/
#user = "anope"
#group = "anope"
/*
- * The case mapping used by services. This must be set to a valid locale name
- * installed on your machine. Services use this case map to compare, with
- * case insensitivity, things such as nick names, channel names, etc.
+ * Chooses the configuration file used to configure casemaps for Anope.
+ * Anope uses this case map to compare, with case insensitivity,
+ * nick names and channel names.
+ *
+ * Two casemaps shipped with Anope are ascii and rfc1459.
+ *
+ * You may create your own instead by defining casemapping directives
+ * similar to how ascii.conf and rfc1459.conf do. However, they are
+ * limited to single byte characters only.
*
- * We provide two special casemaps shipped with Anope, ascii and rfc1459.
+ * Alternatively, if you have Boost.Locale installed, instead of configuring
+ * a casemapping configuration file, you may configure a locale name. This
+ * can support variable-length character encodings like utf-8.
*
- * This value should be set to what your IRCd uses, which is probably rfc1459,
- * however Anope has always used ascii for comparison, so the default is ascii.
+ * The casemapping you use should be set to what your IRCd uses, which is
+ * probably rfc1459. However, Anope has always used ascii for comparison,
+ * so the default is ascii.
*
* Changing this value once set is not recommended.
*/
casemap = "ascii"
+ #casemap = "rfc1459"
+ #locale = "utf-8"
/*
* This key is used to initiate the random number generator. This number
@@ -401,10 +395,10 @@ options
#seed = 9866235
/*
- * If set, Services will perform more stringent checks on passwords. If this
- * isn't set, Services will only disallow a password if it is the same as the
+ * If set, services will perform more stringent checks on passwords. If this
+ * isn't set, services will only disallow a password if it is the same as the
* entity (nickname name) with which it is associated. When set, however,
- * Services will also check that the password is at least five
+ * services will also check that the password is at least five
* characters long, and in the future will probably check other things
* as well.
*
@@ -413,11 +407,11 @@ options
strictpasswords = yes
/*
- * Sets the number of invalid password tries before Services removes a user
+ * Sets the number of invalid password tries before services removes a user
* from the network. If a user enters a number of invalid passwords equal to
- * the given amount for any Services function or combination of functions
- * during a single IRC session (subject to badpasstimeout, below), Services
- * will issues a /KILL for the user. If not given, Services will ignore
+ * the given amount for any services function or combination of functions
+ * during a single IRC session (subject to badpasstimeout, below), services
+ * will issues a /KILL for the user. If not given, services will ignore
* failed password attempts (though they will be logged in any case).
*
* This directive is optional, but recommended.
@@ -459,7 +453,7 @@ options
/*
* Sets the (maximum) frequency at which the timeout list is checked. This,
* combined with readtimeout above, determines how accurately timed events,
- * such as nick kills, occur; it also determines how much CPU time Services
+ * such as nick kills, occur; it also determines how much CPU time services
* will use doing this. Higher values will cause less accurate timing but
* less CPU usage.
*
@@ -472,7 +466,7 @@ options
timeoutcheck = 3s
/*
- * If set, this will allow users to let Services send PRIVMSGs to them
+ * If set, this will allow users to let services send PRIVMSGs to them
* instead of NOTICEs. Also see the "msg" option of nickserv:defaults,
* which also toggles the default communication (PRIVMSG or NOTICE) to
* use for unregistered users.
@@ -485,7 +479,7 @@ options
#useprivmsg = yes
/*
- * If set, will force Services to only respond to PRIVMSGs addresses to
+ * If set, will force services to only respond to PRIVMSGs addresses to
* Nick@ServerName - e.g. NickServ@localhost.net. This should be used in
* conjunction with IRCd aliases. This directive is optional.
*
@@ -494,14 +488,14 @@ options
#usestrictprivmsg = yes
/*
- * If set, Services will only show /stats o to IRC Operators. This directive
+ * If set, services will only show /stats o to IRC Operators. This directive
* is optional.
*/
#hidestatso = yes
/*
* A space-separated list of ulined servers on your network, it is assumed that
- * the servers in this list are allowed to set channel modes and Services will
+ * the servers in this list are allowed to set channel modes and services will
* not attempt to reverse their mode changes.
*
* WARNING: Do NOT put your normal IRC user servers in this directive.
@@ -516,23 +510,23 @@ options
retrywait = 60s
/*
- * If set, Services will hide commands that users don't have the privilege to execute
+ * If set, services will hide commands that users don't have the privilege to execute
* from HELP output.
*/
hideprivilegedcommands = yes
/*
- * If set, Services will hide commands that users can't execute because they are not
+ * If set, services will hide commands that users can't execute because they are not
* logged in from HELP output.
*/
hideregisteredcommands = yes
- /* The regex engine to use, as provided by the regex modules.
- * Leave commented to disable regex matching.
+ /*
+ * The grammar regular expressions should use. Options are "ecmascript", "basic", "extended", "awk", "grep", and "egrep".
*
- * Note for this to work the regex module providing the regex engine must be loaded.
+ * This directive is optional.
*/
- regexengine = "regex/pcre"
+ regexengine = "ecmascript"
/*
* A list of languages to load on startup that will be available in /nickserv set language.
@@ -737,7 +731,7 @@ log
log
{
target = "globops"
- admin = "global/* operserv/chankill operserv/mode operserv/kick operserv/akill operserv/s*line operserv/noop operserv/jupe operserv/oline operserv/set operserv/svsnick operserv/svsjoin operserv/svspart nickserv/getpass */drop"
+ admin = "global/* operserv/chankill operserv/mode operserv/kick operserv/akill operserv/s*line operserv/noop operserv/jupe operserv/oline operserv/set operserv/svsnick operserv/svsjoin operserv/svspart */drop"
servers = "squit"
users = "oper"
other = "expire/* bados akill/*"
@@ -775,7 +769,7 @@ log
* nickserv/drop - Can drop other users nicks
* operserv/config - Can modify services's configuration
* operserv/oper/modify - Can add and remove operators with at most the same privileges
- * protected - Can not be kicked from channels by Services
+ * protected - Can not be kicked from channels by services
*
* Available commands:
* botserv/bot/del botserv/bot/add botserv/bot/change botserv/set/private
@@ -793,8 +787,7 @@ log
*
* memoserv/sendall memoserv/staff
*
- * nickserv/getpass nickserv/getemail nickserv/suspend nickserv/ajoin
- * nickserv/list
+ * nickserv/getemail nickserv/suspend nickserv/ajoin nickserv/list
*
* nickserv/saset/autoop nickserv/saset/email nickserv/saset/greet nickserv/saset/password
* nickserv/saset/display nickserv/saset/kill nickserv/saset/language nickserv/saset/message
@@ -880,10 +873,10 @@ opertype
* After defining different types of operators in the above opertype section, we now define who is in these groups
* through 'oper' blocks, similar to ircd access.
*
- * The default is to comment these out (so NOBODY will have Services access).
+ * The default is to comment these out (so NOBODY will have access).
* You probably want to add yourself and a few other people at minimum.
*
- * As with all permissions, make sure to only give trustworthy people access to Services.
+ * As with all permissions, make sure to only give trustworthy people access.
*/
#oper
@@ -894,7 +887,7 @@ opertype
/* The opertype this person will have */
type = "Services Root"
- /* If set, the user must be an oper on the IRCd to gain their Services
+ /* If set, the user must be an oper on the IRCd to gain their
* oper privileges.
*/
require_oper = yes
@@ -929,7 +922,7 @@ opertype
/*
* [OPTIONAL] Mail Config
*
- * This section contains settings related to the use of e-mail from Services.
+ * This section contains settings related to the use of e-mail from services.
* If the usemail directive is set to yes, unless specified otherwise, all other
* directives are required.
*
@@ -940,7 +933,7 @@ opertype
mail
{
/*
- * If set, this option enables the mail commands in Services. You may choose
+ * If set, this option enables the mail commands in Anope. You may choose
* to disable it if you have no Sendmail-compatible mailer installed. Whilst
* this directive (and entire block) is optional, it is required if
* nickserv:registration is set to yes.
@@ -971,7 +964,7 @@ mail
* another e-mail after they have sent one. It also controls the minimum time
* a user must wait before they can receive another e-mail.
*
- * This feature prevents users from being mail bombed using Services and
+ * This feature prevents users from being mail bombed using services and
* it is highly recommended that it be used.
*
* This directive is optional, but highly recommended.
@@ -979,7 +972,7 @@ mail
delay = 5m
/*
- * If set, Services will not attempt to put quotes around the TO: fields
+ * If set, Anope will not put quotes around the TO: fields
* in e-mails.
*
* This directive is optional, and as far as we know, it's only needed
@@ -1057,7 +1050,7 @@ mail
*/
#module
{
- name = "db_old"
+ name = "database/old"
/*
* This is the encryption type used by the databases. This must be set correctly or
@@ -1075,7 +1068,7 @@ mail
*/
module
{
- name = "db_flatfile"
+ name = "database/flatfile"
/*
* The database name db_flatfile should use
@@ -1084,18 +1077,18 @@ module
/*
* Sets the number of days backups of databases are kept. If you don't give it,
- * or if you set it to 0, Services won't backup the databases.
+ * or if you set it to 0, Anope won't backup the databases.
*
- * NOTE: Services must run 24 hours a day for this feature to work.
+ * NOTE: Anope must run 24 hours a day for this feature to work.
*
* This directive is optional, but recommended.
*/
keepbackups = 3
/*
- * Allows Services to continue file write operations (i.e. database saving)
+ * Allows Anope to continue file write operations (i.e. database saving)
* even if the original file cannot be backed up. Enabling this option may
- * allow Services to continue operation under conditions where it might
+ * allow Anope to continue operation under conditions where it might
* otherwise fail, such as a nearly-full disk.
*
* NOTE: Enabling this option can cause irrecoverable data loss under some
@@ -1104,83 +1097,44 @@ module
* This directive is optional, and you are discouraged against enabling it.
*/
#nobackupokay = yes
-
- /*
- * If enabled, services will fork a child process to save databases.
- *
- * This is only useful with very large databases, with hundreds
- * of thousands of objects, that have a noticeable delay from
- * writing databases.
- *
- * If your database is large enough cause a noticeable delay when
- * saving you should consider a more powerful alternative such
- * as db_sql or db_redis, which incrementally update their
- * databases asynchronously in real time.
- */
- fork = no
}
/*
- * db_sql and db_sql_live
+ * db_sql
*
- * db_sql module allows saving and loading databases using one of the SQL engines.
- * This module loads the databases once on startup, then incrementally updates
- * objects in the database as they are changed within Anope in real time. Changes
- * to the SQL tables not done by Anope will have no effect and will be overwritten.
- *
- * db_sql_live module allows saving and loading databases using one of the SQL engines.
+ * db_sql allows saving and loading databases using one of the SQL engines.
* This module reads and writes to SQL in real time. Changes to the SQL tables
- * will be immediately reflected into Anope. This module should not be loaded
- * in conjunction with db_sql.
+ * will be immediately reflected into Anope.
*
*/
#module
{
- name = "db_sql"
- #name = "db_sql_live"
+ name = "database/sql"
/*
- * The SQL service db_sql(_live) should use, these are configured in modules.conf.
+ * The SQL service database/sql should use, these are configured in modules.conf.
* For MySQL, this should probably be mysql/main.
*/
engine = "sqlite/main"
/*
* An optional prefix to prepended to the name of each created table.
- * Do not use the same prefix for other programs.
*/
#prefix = "anope_db_"
-
- /* Whether or not to import data from another database module in to SQL on startup.
- * If you enable this, be sure that the database services is configured to use is
- * empty and that another database module to import from is loaded before db_sql.
- * After you enable this and do a database import you should disable it for
- * subsequent restarts.
- *
- * Note that you can not import databases using db_sql_live. If you want to import
- * databases and use db_sql_live you should import them using db_sql, then shut down
- * and start services with db_sql_live.
- */
- import = false
}
/*
* db_redis.
*
* This module allows using Redis (http://redis.io) as a database backend.
- * This module requires that m_redis is loaded and configured properly.
- *
- * Redis 2.8 supports keyspace notifications which allows Redis to push notifications
- * to Anope about outside modifications to the database. This module supports this and
- * will internally reflect any changes made to the database immediately once notified.
- * See docs/REDIS for more information regarding this.
+ * This module requires the module redis to be loaded and configured properly.
*/
#module
{
- name = "db_redis"
+ name = "database/redis"
/*
- * Redis database to use. This must be configured with m_redis.
+ * Redis database to use. This must be configured with the module redis.
*/
engine = "redis/main"
}
@@ -1194,9 +1148,9 @@ module
*
* Without any encryption modules loaded users will not be able to authenticate unless
* there is another module loaded that provides authentication checking, such as
- * m_ldap_authentication or m_sql_authentication.
+ * ldap_authentication or sql_authentication.
*
- * With enc_none, passwords will be stored in plain text, allowing for passwords
+ * With encryption/none, passwords will be stored in plain text, allowing for passwords
* to be recovered later but it isn't secure and therefore is not recommended.
*
* The other encryption modules use one-way encryption, so the passwords can not
@@ -1206,36 +1160,20 @@ module
* encrypted by this module. Old passwords stored in another encryption method are
* automatically re-encrypted by the primary encryption module on next identify.
*
- * NOTE: enc_old is Anope's previous (broken) MD5 implementation which is present in
- * versions prior to Anope 1.7.17. If your databases were made using that module,
- * use this and not enc_md5.
- *
- * NOTE: enc_sha1 relies on how the OS stores 2+ byte data internally, and is
- * potentially broken when moving between 2 different OSes, such as moving from
- * Linux to Windows. It is recommended that you use enc_sha256 instead if you want
- * to use an SHA-based encryption. If you choose to do so, it is also recommended
- * that you first try to get everyone's passwords converted to enc_sha256 before
- * switching OSes by placing enc_sha256 at the beginning of the list.
- *
*/
-#module { name = "enc_bcrypt" }
-module { name = "enc_sha256" }
-#module { name = "enc_md5" }
-#module { name = "enc_sha1" }
-
-/*
- * When using enc_none, passwords will be stored without encryption. This isn't secure
- * therefore it is not recommended.
- */
-#module { name = "enc_none" }
+#module { name = "encryption/bcrypt" }
+module { name = "encryption/sha256" }
/*
- * enc_old is Anope's previous (broken) MD5 implementation used from 1.4.x to 1.7.16.
- * If your databases were made using that module, load it here to allow conversion to the primary
- * encryption method.
+ * [DEPRECATED] Deprecated encryption modules. You can only use these for compatibility with
+ * old databases and will need to load one of the above modules as your primary encryption
+ * module.
*/
-#module { name = "enc_old" }
+#module { name = "encryption/md5" }
+#module { name = "encryption/sha1" }
+#module { name = "encryption/old" }
+#module { name = "encryption/none" }
/* Extra (optional) modules. */
diff --git a/data/ascii.conf b/data/ascii.conf
new file mode 100644
index 000000000..1bfcb33f0
--- /dev/null
+++ b/data/ascii.conf
@@ -0,0 +1,157 @@
+
+casemap
+{
+ lower = "a"
+ upper = "A"
+}
+
+casemap
+{
+ lower = "b"
+ upper = "B"
+}
+
+casemap
+{
+ lower = "c"
+ upper = "C"
+}
+
+casemap
+{
+ lower = "d"
+ upper = "D"
+}
+
+casemap
+{
+ lower = "e"
+ upper = "E"
+}
+
+casemap
+{
+ lower = "f"
+ upper = "F"
+}
+
+casemap
+{
+ lower = "g"
+ upper = "G"
+}
+
+casemap
+{
+ lower = "h"
+ upper = "H"
+}
+
+casemap
+{
+ lower = "i"
+ upper = "I"
+}
+
+casemap
+{
+ lower = "j"
+ upper = "J"
+}
+
+casemap
+{
+ lower = "k"
+ upper = "K"
+}
+
+casemap
+{
+ lower = "l"
+ upper = "L"
+}
+
+casemap
+{
+ lower = "m"
+ upper = "M"
+}
+
+casemap
+{
+ lower = "n"
+ upper = "N"
+}
+
+casemap
+{
+ lower = "o"
+ upper = "O"
+}
+
+casemap
+{
+ lower = "p"
+ upper = "P"
+}
+
+casemap
+{
+ lower = "q"
+ upper = "Q"
+}
+
+casemap
+{
+ lower = "r"
+ upper = "R"
+}
+
+casemap
+{
+ lower = "s"
+ upper = "S"
+}
+
+casemap
+{
+ lower = "t"
+ upper = "T"
+}
+
+casemap
+{
+ lower = "u"
+ upper = "U"
+}
+
+casemap
+{
+ lower = "v"
+ upper = "V"
+}
+
+casemap
+{
+ lower = "w"
+ upper = "W"
+}
+
+casemap
+{
+ lower = "x"
+ upper = "X"
+}
+
+casemap
+{
+ lower = "y"
+ upper = "Y"
+}
+
+casemap
+{
+ lower = "z"
+ upper = "Z"
+}
+
diff --git a/data/bahamut.example.conf b/data/bahamut.example.conf
new file mode 100644
index 000000000..894d03411
--- /dev/null
+++ b/data/bahamut.example.conf
@@ -0,0 +1,170 @@
+
+module
+{
+ name = "protocol/bahamut"
+}
+
+usermode
+{
+ name = "SERV_ADMIN"
+ character = "A"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGPRIF"
+ character = "R"
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "DEAF"
+ character = "d"
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "OP"
+ character = "o"
+ status = "@"
+ level = 2
+}
+
+channelmode
+{
+ name = "BLOCKCOLOR"
+ character = "c"
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "FLOOD"
+ character = "f"
+ param_regex = "\*?\d+:\d+"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
diff --git a/data/botserv.example.conf b/data/botserv.example.conf
index fbb8f166d..817188bc8 100644
--- a/data/botserv.example.conf
+++ b/data/botserv.example.conf
@@ -52,13 +52,21 @@ service
#modes = "+o"
/*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
+ * Channels this service should join. Outside of log channels this is not very useful,
+ * as the service will just idle in the specified channels, and will not accept any types of commands.
*
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
+ * Status modes mave be given for the channel in the form of mode characters or prefix symbols.
*/
- #channels = "@#services,#mychan"
+ channel
+ {
+ modes = "o"
+ name = "#services"
+ }
+
+ channel
+ {
+ name = "#mychan"
+ }
}
/*
@@ -68,7 +76,7 @@ service
*/
module
{
- name = "botserv"
+ name = "botserv/main"
/*
* The name of the client that should be BotServ.
@@ -140,7 +148,7 @@ module
command { service = "BotServ"; name = "HELP"; command = "generic/help"; }
/*
- * bs_assign
+ * botserv/gassign
*
* Provides the commands:
* botserv/assign - Used to assign BotServ bots to channels
@@ -149,19 +157,19 @@ command { service = "BotServ"; name = "HELP"; command = "generic/help"; }
*
* Used for assigning and unassigning bots to channels.
*/
-module { name = "bs_assign" }
+module { name = "botserv/assign" }
command { service = "BotServ"; name = "ASSIGN"; command = "botserv/assign"; }
command { service = "BotServ"; name = "UNASSIGN"; command = "botserv/unassign"; }
command { service = "BotServ"; name = "SET NOBOT"; command = "botserv/set/nobot"; permission = "botserv/set/nobot"; }
/*
- * bs_autoassign
+ * botserv/gautoassign
*
* Allows service bots to be automatically assigned to channels upon registration.
*/
#module
{
- name = "bs_autoassign"
+ name = "botserv/autoassign"
/*
* Automatically assign ChanServ to channels upon registration.
@@ -170,7 +178,7 @@ command { service = "BotServ"; name = "SET NOBOT"; command = "botserv/set/nobot"
}
/*
- * bs_badwords
+ * botserv/gbadwords
*
* Provides the command botserv/badwords.
*
@@ -178,7 +186,7 @@ command { service = "BotServ"; name = "SET NOBOT"; command = "botserv/set/nobot"
*/
module
{
- name = "bs_badwords"
+ name = "botserv/badwords"
/*
* The maximum number of entries a single bad words list can have.
@@ -195,48 +203,48 @@ module
command { service = "BotServ"; name = "BADWORDS"; command = "botserv/badwords"; }
/*
- * bs_bot
+ * botserv/gbot
*
* Provides the command botserv/bot.
*
* Used for administrating BotServ bots.
*/
-module { name = "bs_bot" }
+module { name = "botserv/gbot" }
command { service = "BotServ"; name = "BOT"; command = "botserv/bot"; permission = "botserv/bot"; }
/*
- * bs_botlist
+ * botserv/gbotlist
*
* Provides the command botserv/botlist.
*
* Used for listing all available bots.
*/
-module { name = "bs_botlist" }
+module { name = "botserv/gbotlist" }
command { service = "BotServ"; name = "BOTLIST"; command = "botserv/botlist"; }
/*
- * bs_control
+ * botserv/gcontrol
*
* Provides the commands botserv/act and botserv/say.
*
* Used for making the bot message a channel.
*/
-module { name = "bs_control" }
+module { name = "botserv/gcontrol" }
command { service = "BotServ"; name = "ACT"; command = "botserv/act"; }
command { service = "BotServ"; name = "SAY"; command = "botserv/say"; }
/*
- * bs_info
+ * botserv/ginfo
*
* Provides the command botserv/info.
*
* Used for getting information on bots or channels.
*/
-module { name = "bs_info" }
+module { name = "botserv/ginfo" }
command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
/*
- * bs_kick
+ * botserv/gkick
*
* Provides the commands:
* botserv/kick - Dummy help wrapper for the KICK command.
@@ -257,7 +265,7 @@ command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
*/
module
{
- name = "bs_kick"
+ name = "botserv/gkick"
/*
* The amount of time that data for a user is valid in BotServ. If the data exceeds this time,
@@ -291,12 +299,12 @@ command { service = "BotServ"; name = "SET DONTKICKVOICES"; command = "botserv/s
/*
- * bs_set
+ * botserv/gset
*
* Provides the commands:
* botserv/set/private - Used to prohibit specific BotServ bots from being assigned to channels.
*/
-module { name = "bs_set" }
+module { name = "botserv/gset" }
command { service = "BotServ"; name = "SET"; command = "botserv/set"; }
command { service = "BotServ"; name = "SET BANEXPIRE"; command = "botserv/set/banexpire"; }
command { service = "BotServ"; name = "SET PRIVATE"; command = "botserv/set/private"; permission = "botserv/set/private"; }
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index 78062d3fb..4c64a8ac3 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "chanserv"
+ name = "chanserv/main"
/*
* The name of the client that should be ChanServ.
@@ -91,7 +82,7 @@ module
* not in use.
* - none: No defaults
*
- * This directive is optional, if left blank, the options will default to keeptopic, cs_secure, securefounder,
+ * This directive is optional, if left blank, the options will default to keeptopic, chanserv/secure, securefounder,
* and signkick. If you really want no defaults, use "none" by itself as the option.
*/
defaults = "keeptopic peace cs_secure securefounder signkick"
@@ -164,11 +155,6 @@ module
disallow_hostmask_access = false
/*
- * If set, prevents channels from being on access lists.
- */
- disallow_channel_access = false
-
- /*
* If set, ChanServ will always lower the timestamp of registered channels to their registration date.
* This prevents several race conditions where unauthorized users can join empty registered channels and set
* modes etc. prior to services deopping them.
@@ -184,14 +170,14 @@ module
* determine how powerful privileges are relative to other privileges, which is used by Anope to determine
* who has greater access in a channel.
*
- * If you load cs_access, you may define a level for the privilege, which is used by chanserv/access and chanserv/levels.
+ * If you load chanserv/access, you may define a level for the privilege, which is used by chanserv/access and chanserv/levels.
* The levels defined will be used as the default levels for newly registered channels.
* The level "founder" is a special level which means anyone with the privilege FOUNDER on the channel
* has that permission. Additionally, the level "disabled" means that no one can use the privilege, including founders.
*
- * If you load cs_flags, you may define a flag associated with that privilege for use in chanserv/flags.
+ * If you load chanserv/flags, you may define a flag associated with that privilege for use in chanserv/flags.
*
- * If you load cs_xop, you may define a XOP command to associate the privilege with.
+ * If you load chanserv/xop, you may define a XOP command to associate the privilege with.
*
* The name of privileges are uesd to associate them with channel modes. If you are using an IRCd that allows you to define additional
* channel status modes, such as InspIRCd, you can associate privileges (and thus access levels, flags, xop) with the mode by naming
@@ -831,7 +817,7 @@ command_group
command { service = "ChanServ"; name = "HELP"; command = "generic/help"; }
/*
- * cs_access
+ * chanserv/access
*
* Provides commands chanserv/access and chanserv/levels.
* Provides the access system "levels".
@@ -840,15 +826,15 @@ command { service = "ChanServ"; name = "HELP"; command = "generic/help"; }
* are representated by given level on a per channel basis.
*
* The "LIST" subcommand of chanserv/access will show every access entry on the channel, including access
- * entries not added by cs_access. The "level" of these entries will be the representation of the access
+ * entries not added by chanserv/access. The "level" of these entries will be the representation of the access
* entry by the other access system, which could be an XOP command name, or a set of flags.
*/
-module { name = "cs_access" }
+module { name = "chanserv/access" }
command { service = "ChanServ"; name = "ACCESS"; command = "chanserv/access"; group = "chanserv/access"; }
command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; group = "chanserv/access"; }
/*
- * cs_akick
+ * chanserv/akick
*
* Provides the command chanserv/akick.
*
@@ -856,7 +842,7 @@ command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; gr
*/
module
{
- name = "cs_akick"
+ name = "chanserv/akick"
/*
* The maximum number of entries on a channel's autokick list.
@@ -871,7 +857,7 @@ module
command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; group = "chanserv/management"; }
/*
- * cs_ban
+ * chanserv/ban
*
* Provides the command chanserv/ban.
*
@@ -883,41 +869,41 @@ command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; grou
*
* Used for banning users from channels.
*/
-module { name = "cs_ban" }
+module { name = "chanserv/ban" }
command { service = "ChanServ"; name = "BAN"; command = "chanserv/ban"; }
/*
- * cs_clone
+ * chanserv/clone
*
* Provides the command chanserv/clone.
*
* Used for copying channel settings from one channel to another.
*/
-module { name = "cs_clone" }
+module { name = "chanserv/clone" }
command { service = "ChanServ"; name = "CLONE"; command = "chanserv/clone"; group = "chanserv/management"; }
/*
- * cs_drop
+ * chanserv/drop
*
* Provides the command chanserv/drop.
*
* Used for unregistering channels.
*/
-module { name = "cs_drop" }
+module { name = "chanserv/drop" }
command { service = "ChanServ"; name = "DROP"; command = "chanserv/drop"; }
/*
- * cs_enforce
+ * chanserv/enforce
*
* Provides the command chanserv/enforce.
*
* Used to enforce various channel settings such as secureops and restricted.
*/
-module { name = "cs_enforce" }
+module { name = "chanserv/enforce" }
command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce"; group = "chanserv/management"; }
/*
- * cs_entrymsg
+ * chanserv/entrymsg
*
* Provides the command chanserv/entrymsg.
*
@@ -925,7 +911,7 @@ command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce";
*/
module
{
- name = "cs_entrymsg"
+ name = "chanserv/entrymsg"
/* The maximum number of entrymsgs allowed per channel. If not set, defaults to 5. */
maxentries = 5
@@ -933,7 +919,7 @@ module
command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; group = "chanserv/management"; }
/*
- * cs_flags
+ * chanserv/flags
*
* Provides the command chanserv/flags.
* Provides the access system "flags".
@@ -941,54 +927,54 @@ command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"
* Used for giving users access in channels.
*
* The "LIST" subcommand of chanserv/flags will show every access entry on the channel, including access
- * entries not added by cs_flags. The "Flags" of these entries will be the flags representation of the
+ * entries not added by chanserv/flags. The "Flags" of these entries will be the flags representation of the
* privilege set granted by the access entry.
*/
-module { name = "cs_flags" }
+module { name = "chanserv/flags" }
command { service = "ChanServ"; name = "FLAGS"; command = "chanserv/flags"; group = "chanserv/access"; }
/*
- * cs_getkey
+ * chanserv/getkey
*
* Provides the command chanserv/getkey.
*
* Used for getting the key for channels.
*/
-module { name = "cs_getkey" }
+module { name = "chanserv/getkey" }
command { service = "ChanServ"; name = "GETKEY"; command = "chanserv/getkey"; }
/*
- * cs_info
+ * chanserv/info
*
* Provides the command chanserv/info.
*
* Used for getting information about channels.
*/
-module { name = "cs_info" }
+module { name = "chanserv/info" }
command { service = "ChanServ"; name = "INFO"; command = "chanserv/info"; }
/*
- * cs_invite
+ * chanserv/invite
*
* Provides the command chanserv/invite.
*
* Used for inviting yourself in to channels.
*/
-module { name = "cs_invite" }
+module { name = "chanserv/invite" }
command { service = "ChanServ"; name = "INVITE"; command = "chanserv/invite"; }
/*
- * cs_kick
+ * chanserv/kick
*
* Provides the command chanserv/kick.
*
* Used for kicking users from channels.
*/
-module { name = "cs_kick" }
+module { name = "chanserv/kick" }
command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
/*
- * cs_list
+ * chanserv/list
*
* Provides the commands:
* chanserv/list - Used for retrieving and searching the registered channel list.
@@ -996,7 +982,7 @@ command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
*/
module
{
- name = "cs_list"
+ name = "chanserv/list"
/*
* The maximum number of channels to be returned for a ChanServ LIST command.
@@ -1009,7 +995,7 @@ command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/pr
/*
- * cs_log
+ * chanserv/log
*
* Provides the command chanserv/log.
*
@@ -1017,7 +1003,7 @@ command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/pr
*/
module
{
- name = "cs_log"
+ name = "chanserv/log"
/* Default log settings for newly registered channels */
@@ -1050,7 +1036,7 @@ module
command { service = "ChanServ"; name = "LOG"; command = "chanserv/log"; group = "chanserv/management"; }
/*
- * cs_mode
+ * chanserv/mode
*
* Provides the command chanserv/mode and chanserv/modes.
*
@@ -1060,7 +1046,7 @@ command { service = "ChanServ"; name = "LOG"; command = "chanserv/log"; group =
*/
module
{
- name = "cs_mode"
+ name = "chanserv/mode"
/*
* Default modes for mode lock, these are set on newly registered channels.
@@ -1095,17 +1081,17 @@ command { service = "ChanServ"; name = "DEVOICE"; command = "chanserv/modes"; gr
/*
- * cs_register
+ * chanserv/register
*
* Provides the commands chanserv/register.
*
* Used for registering channels.
*/
-module { name = "cs_register" }
+module { name = "chanserv/register" }
command { service = "ChanServ"; name = "REGISTER"; command = "chanserv/register"; }
/*
- * cs_seen
+ * chanserv/seen
*
* Provides the commands chanserv/seen and operserv/seen.
*
@@ -1114,7 +1100,7 @@ command { service = "ChanServ"; name = "REGISTER"; command = "chanserv/register"
*/
module
{
- name = "cs_seen"
+ name = "chanserv/seen"
/* If set, uses the older 1.8 style seen, which is less resource intensive */
simple = false
@@ -1128,7 +1114,7 @@ module
command { service = "OperServ"; name = "SEEN"; command = "operserv/seen"; permission = "operserv/seen"; }
/*
- * cs_set
+ * chanserv/set
*
* Provides the commands:
* chanserv/set and chanserv/saset - Dummy help wrappers for the SET commands.
@@ -1151,7 +1137,7 @@ command { service = "OperServ"; name = "SEEN"; command = "operserv/seen"; permis
*/
module
{
- name = "cs_set"
+ name = "chanserv/set"
/*
* The default ban type for newly registered channels.
@@ -1189,30 +1175,30 @@ command { service = "ChanServ"; name = "SET SUCCESSOR"; command = "chanserv/set/
command { service = "ChanServ"; name = "SET NOEXPIRE"; command = "chanserv/saset/noexpire"; permission = "chanserv/saset/noexpire"; }
/*
- * cs_set_misc
+ * chanserv/set_misc
*
* Provides the command chanserv/set/misc.
*
* Allows you to create arbitrary commands to set data, and have that data show up in chanserv/info.
* A field named misc_description may be given for use with help output.
*/
-module { name = "cs_set_misc" }
+module { name = "chanserv/set_misc" }
command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; misc_description = _("Associate a URL with the channel"); }
command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; misc_description = _("Associate an E-mail address with the channel"); }
/*
- * cs_status
+ * chanserv/status
*
* Provides the command chanserv/status.
*
* Used for determining a user's access on a channel and whether
* or not they match any autokick entries.
*/
-module { name = "cs_status" }
+module { name = "chanserv/status" }
command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
/*
- * cs_suspend
+ * chanserv/suspend
*
* Provides the commands chanserv/suspend and chanserv/unsuspend.
*
@@ -1220,7 +1206,7 @@ command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
*/
module
{
- name = "cs_suspend"
+ name = "chanserv/suspend"
/*
* The length of time before a suspended channel expires.
@@ -1241,50 +1227,50 @@ command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend";
command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; permission = "chanserv/suspend"; group = "chanserv/admin"; }
/*
- * cs_sync
+ * chanserv/sync
*
* Provides the command chanserv/sync.
*
* Used to sync users channel status modes with what access they have.
*/
-module { name = "cs_sync" }
+module { name = "chanserv/sync" }
command { service = "ChanServ"; name = "SYNC"; command = "chanserv/sync"; group = "chanserv/management"; }
/*
- * cs_topic
+ * chanserv/topic
*
* Provides the commands:
* chanserv/topic - Used for changing the channel topic. Useful in conjunction with chanserv/set/topiclock.
* chanserv/set/keeptopic - Used for configuring if ChanServ is to restore the channel topic when a channel is created.
*
*/
-module { name = "cs_topic" }
+module { name = "chanserv/topic" }
command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; group = "chanserv/management"; }
command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
/*
- * cs_unban
+ * chanserv/unban
*
* Provides the command chanserv/unban.
*
* Used for unbanning users from channels.
*/
-module { name = "cs_unban" }
+module { name = "chanserv/unban" }
command { service = "ChanServ"; name = "UNBAN"; command = "chanserv/unban"; }
/*
- * cs_updown
+ * chanserv/updown
*
* Provides the commands chanserv/up and chanserv/down.
*
* Used for setting or removing your status modes on a channel.
*/
-module { name = "cs_updown" }
+module { name = "chanserv/updown" }
command { service = "ChanServ"; name = "DOWN"; command = "chanserv/down"; group = "chanserv/status"; }
command { service = "ChanServ"; name = "UP"; command = "chanserv/up"; group = "chanserv/status"; }
/*
- * cs_xop
+ * chanserv/xop
*
* Provides the command chanserv/xop.
* Provides the access system "XOP".
@@ -1297,7 +1283,7 @@ command { service = "ChanServ"; name = "UP"; command = "chanserv/up"; group = "c
* The "LIST" subcommand of chanserv/xop will show only XOP access entries of the given XOP type. You
* can not view the entire access list at once, and instead should use another access system to do that.
*/
-module { name = "cs_xop" }
+module { name = "chanserv/xop" }
command { service = "ChanServ"; name = "QOP"; command = "chanserv/xop"; group = "chanserv/access"; }
command { service = "ChanServ"; name = "SOP"; command = "chanserv/xop"; group = "chanserv/access"; }
command { service = "ChanServ"; name = "AOP"; command = "chanserv/xop"; group = "chanserv/access"; }
@@ -1310,9 +1296,9 @@ command { service = "ChanServ"; name = "VOP"; command = "chanserv/xop"; group =
*/
/*
- * cs_statusupdate
+ * chanserv/statusupdate
*
* This module automatically updates users status on channels when the
* channel's access list is modified.
*/
-module { name = "cs_statusupdate" }
+module { name = "chanserv/statusupdate" }
diff --git a/data/chanstats.example.conf b/data/chanstats.example.conf
index 64f57da30..df19374a2 100644
--- a/data/chanstats.example.conf
+++ b/data/chanstats.example.conf
@@ -5,7 +5,7 @@
module
{
- name = "m_chanstats"
+ name = "chanstats"
/*
* The name of this engine.
diff --git a/data/example.chk b/data/example.chk
index 119b1ca99..e71928f1c 100644
--- a/data/example.chk
+++ b/data/example.chk
@@ -9,16 +9,16 @@
###############################################################
# Anope binary directory
-ANOPATH=/home/ircd/services/bin
+ANOPATH=/home/ircd/anope/bin
# Anope data directory
-ANODATA=/home/ircd/services/data
+ANODATA=/home/ircd/anope/data
# Name of the pid file
-ANOPIDF=services.pid
+ANOPIDF=anope.pid
# Name of the executable
-ANOPROG=services
+ANOPROG=anope
# Parameters to pass to the executable
ANOARGS=""
diff --git a/data/global.example.conf b/data/global.example.conf
index 09534dae7..d6c856aea 100644
--- a/data/global.example.conf
+++ b/data/global.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "global"
+ name = "global/main"
/*
* The name of the client that should be Global.
@@ -105,11 +96,11 @@ module
command { service = "Global"; name = "HELP"; command = "generic/help"; }
/*
- * gl_global
+ * global/global
*
* Provides the command global/global.
*
* Used for sending a message to every online user.
*/
-module { name = "gl_global" }
+module { name = "global/global" }
command { service = "Global"; name = "GLOBAL"; command = "global/global"; permission = "global/global"; }
diff --git a/data/hostserv.example.conf b/data/hostserv.example.conf
index e13e8fdd1..685eb9722 100644
--- a/data/hostserv.example.conf
+++ b/data/hostserv.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "hostserv"
+ name = "hostserv/main"
/*
* The name of the client that should be HostServ.
@@ -86,18 +77,18 @@ module
command { service = "HostServ"; name = "HELP"; command = "generic/help"; }
/*
- * hs_del
+ * hostserv/del
*
* Provides the commands hostserv/del and hostserv/delall.
*
* Used for removing users' vHosts.
*/
-module { name = "hs_del" }
+module { name = "hostserv/del" }
command { service = "HostServ"; name = "DEL"; command = "hostserv/del"; permission = "hostserv/del"; }
command { service = "HostServ"; name = "DELALL"; command = "hostserv/delall"; permission = "hostserv/del"; }
/*
- * hs_group
+ * hostserv/group
*
* Provides the command hostserv/group.
*
@@ -105,7 +96,7 @@ command { service = "HostServ"; name = "DELALL"; command = "hostserv/delall"; pe
*/
module
{
- name = "hs_group"
+ name = "hostserv/group"
/*
* Upon nickserv/group, this option syncs the nick's main vHost to the grouped nick.
@@ -120,37 +111,37 @@ module
command { service = "HostServ"; name = "GROUP"; command = "hostserv/group"; }
/*
- * hs_list
+ * hostserv/list
*
* Provides the command hostserv/list.
*
* Used for listing actively set vHosts.
*/
-module { name = "hs_list" }
+module { name = "hostserv/list" }
command { service = "HostServ"; name = "LIST"; command = "hostserv/list"; permission = "hostserv/list"; }
/*
- * hs_off
+ * hostserv/off
*
* Provides the command hostserv/off.
*
* Used for turning off your vHost.
*/
-module { name = "hs_off" }
+module { name = "hostserv/off" }
command { service = "HostServ"; name = "OFF"; command = "hostserv/off"; }
/*
- * hs_on
+ * hostserv/on
*
* Provides the command hostserv/on.
*
* Used for turning on your vHost.
*/
-module { name = "hs_on" }
+module { name = "hostserv/on" }
command { service = "HostServ"; name = "ON"; command = "hostserv/on"; }
/*
- * hs_request
+ * hostserv/request
*
* Provides the commands hostserv/request, hostserv/activate, hostserv/reject, and hostserv/waiting.
*
@@ -158,7 +149,7 @@ command { service = "HostServ"; name = "ON"; command = "hostserv/on"; }
*/
module
{
- name = "hs_request"
+ name = "hostserv/request"
/*
* If set, Services will send a memo to the user requesting a vHost when it's been
@@ -177,12 +168,12 @@ command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; pe
command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/set"; }
/*
- * hs_set
+ * hostserv/set
*
* Provides the commands hostserv/set and hostserv/setall.
*
* Used for setting users' vHosts.
*/
-module { name = "hs_set" }
+module { name = "hostserv/set" }
command { service = "HostServ"; name = "SET"; command = "hostserv/set"; permission = "hostserv/set"; }
command { service = "HostServ"; name = "SETALL"; command = "hostserv/setall"; permission = "hostserv/set"; }
diff --git a/data/hybrid.example.conf b/data/hybrid.example.conf
new file mode 100644
index 000000000..6e9f4da6f
--- /dev/null
+++ b/data/hybrid.example.conf
@@ -0,0 +1,231 @@
+
+module
+{
+ name = "protocol/hybrid"
+}
+
+usermode
+{
+ name = "ADMIN"
+ character = "a"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "CALLERID"
+ character = "g"
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "LOCOPS"
+ character = "l"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "DEAF"
+ character = "D"
+}
+
+usermode
+{
+ name = "HIDEOPER"
+ character = "H"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGPRIF"
+ character = "R"
+}
+
+usermode
+{
+ name = "SSL"
+ character = "S"
+ setable = no
+}
+
+usermode
+{
+ name = "CLOAK"
+ character = "x"
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channemode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "HALFOP"
+ characater = "h"
+ status = "%"
+ level = 2
+}
+
+channelmode
+{
+ name = "OP"
+ character = "o"
+ status = "@"
+ level = 3
+}
+
+channelmode
+{
+ name = "BLOCKCOLOR"
+ character = "c"
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
+channelmode
+{
+ name = "SSL"
+ character = "S"
+}
+
+channelmode
+{
+ name = "NONOTICE"
+ character = "T"
+}
+
diff --git a/data/inspircd20.example.conf b/data/inspircd20.example.conf
new file mode 100644
index 000000000..347fb52ea
--- /dev/null
+++ b/data/inspircd20.example.conf
@@ -0,0 +1,547 @@
+
+module
+{
+ name = "protocol/inspircd20"
+
+ /*
+ * Enables mode locks server-side. This reduces the spam caused by
+ * services immediately reversing mode changes for locked modes.
+ */
+ use_server_side_mlock = yes
+
+ /*
+ * Enforces topic locks server-side. This reduces the spam caused by
+ * services immediately reversing topic changes.
+ */
+ use_server_side_topiclock = yes
+}
+
+usermode
+{
+ name = "BOT"
+ character = "B"
+}
+
+usermode
+{
+ name = "CALLERID"
+ character = "g"
+}
+
+usermode
+{
+ name = "CLOAK"
+ character = "x"
+}
+
+usermode
+{
+ name = "DEAF"
+ character = "d"
+}
+
+usermode
+{
+ name = "COMMONCHANS"
+ character = "c"
+}
+
+usermode
+{
+ name = "HELPOP"
+ character = "h"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "PRIV"
+ character = "I"
+}
+
+usermode
+{
+ name = "HIDEOPER"
+ character = "H"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGPRIV"
+ character = "R"
+}
+
+usermode
+{
+ name = "PROTECTED"
+ character = "k"
+ setable = no
+}
+
+usermode
+{
+ name = "WHOIS"
+ character = "W"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "CENSOR"
+ character = "G"
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+usermode
+{
+ name = "STRIPCOLOR"
+ character = "S"
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "PROTECT"
+ character = "a"
+ status = "&"
+ level = 4
+}
+
+channelmode
+{
+ name = "ALLINVITE"
+ character = "A"
+}
+
+channelmode
+{
+ name = "AUDITORIUM"
+ character = "u"
+}
+
+channelmode
+{
+ name = "AUTOOP"
+ character = "w"
+ setable = no
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channelmode
+{
+ name = "BLOCKCAPS"
+ character = "B"
+}
+
+channelmode
+{
+ name = "BLOCKCOLOR"
+ character = "c"
+}
+
+channelmode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = false
+}
+
+channelmode
+{
+ name = "CENSOR"
+ character = "G"
+}
+
+channelmode
+{
+ name = "DELAYEDJOIN"
+ character = "D"
+}
+
+channelmode
+{
+ name = "DELAYMSG"
+ character = "d"
+ param_regex = "[1-9]\d*"
+}
+
+channelmode
+{
+ name = "FILTER"
+ character = "g"
+ list = yes
+}
+
+channelmode
+{
+ name = "FLOOD"
+ character = "f"
+ param_regex = "\*?\d+:\d+"
+}
+
+channelmode
+{
+ name = "OWNER"
+ character = "q"
+ status = "~"
+ level = 5
+}
+
+channelmode
+{
+ name = "HALFOP"
+ character = "h"
+ status = "%"
+ level = 2
+}
+
+channelmode
+{
+ name = "HISTORY"
+ character = "H"
+ param = yes
+}
+
+channelmode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "JOINFLOOD"
+ character = "j"
+ param_regex = "\d+:\d+"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "NOREJOIN"
+ character = "J"
+ param_regex = "\d+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NICKFLOOD"
+ character = "F"
+ param_regex = "\d+:\d+"
+}
+
+channelmode
+{
+ name = "NOCTCP"
+ character = "C"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "NOKICK"
+ character = "Q"
+}
+
+channelmode
+{
+ name = "NOKNOCK"
+ character = "K"
+}
+
+channelmode
+{
+ name = "NONICK"
+ character = "N"
+}
+
+channelmode
+{
+ name = "NONOTICEB"
+ character = "T"
+}
+
+channelmode
+{
+ name = "OP"
+ character = "o"
+ status = "@"
+ level = 3
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "PERM"
+ character = "P"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "REDIRECT"
+ character = "L"
+ param = yes
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "SSLONLY"
+ character = "z"
+}
+
+channelmode
+{
+ name = "STRIPCOLOR"
+ character = "S"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+extban
+{
+ name = "INVITEBAN"
+ type = "entry"
+ base = "BAN"
+ chaacter = "A"
+}
+
+extban
+{
+ name = "BLOCKCAPSBAN"
+ type = "entry"
+ base = "BAN"
+ character = "B"
+}
+
+extban
+{
+ name = "BLOCKCOLORBAN"
+ type = "entry"
+ base = "BAN"
+ character = "c"
+}
+
+extban
+{
+ name = "NOCTCPBAN"
+ type = "entry"
+ base = "BAN"
+ character = "C"
+}
+
+extban
+{
+ name = "NOKICKBAN"
+ type = "entry"
+ base = "BAN"
+ character = "Q"
+}
+
+extban
+{
+ name = "NONICKBAN"
+ type = "entry"
+ base = "BAN"
+ character = "N"
+}
+
+extban
+{
+ name = "NONOTICEBAN"
+ type = "entry"
+ base = "BAN"
+ character = "T"
+}
+
+extban
+{
+ name = "SSLBAN"
+ type = "fingerprint"
+ base = "BAN"
+ character = "z"
+}
+
+extban
+{
+ name = "STRIPCOLORBAN"
+ type = "entry"
+ base = "BAN"
+ character = "S"
+}
+
+extban
+{
+ name = "ACCOUNTBAN"
+ type = "account"
+ base = "BAN"
+ character = "R"
+}
+
+extban
+{
+ name = "UNREGISTEREDBAN"
+ type = "unidentified"
+ base = "BAN"
+ character = "U"
+}
+
+extban
+{
+ name = "CHANNELBAN"
+ type = "channel"
+ base = "BAN"
+ character = "j"
+}
+
+extban
+{
+ name = "REALNAMEBAN"
+ type = "realname"
+ base = "BAN"
+ character = "r"
+}
+
+extban
+{
+ name = "PARTMESSAGEBAN"
+ type = "entry"
+ base = "BAN"
+ character = "p"
+}
+
+extban
+{
+ name = "SERVERBAN"
+ type = "server"
+ base = "BAN"
+ character = "s"
+}
+
+extban
+{
+ name = "QUIET"
+ type = "entry"
+ base = "BAN"
+ character = "m"
+}
+
diff --git a/data/memoserv.example.conf b/data/memoserv.example.conf
index 9f07ec424..cda9a02ae 100644
--- a/data/memoserv.example.conf
+++ b/data/memoserv.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "memoserv"
+ name = "memoserv/main"
/*
* The name of the client that should be MemoServ. Clients are configured
* with the service blocks.
@@ -101,37 +92,37 @@ module
command { service = "MemoServ"; name = "HELP"; command = "generic/help"; }
/*
- * ms_cancel
+ * memoserv/cancel
*
* Provides the command memoserv/cancel.
*
* Used to cancel memos already sent but not yet read.
*/
-module { name = "ms_cancel" }
+module { name = "memoserv/cancel" }
command { service = "MemoServ"; name = "CANCEL"; command = "memoserv/cancel"; }
/*
- * ms_check
+ * memoserv/check
*
* Provides the command memoserv/check.
*
* Used to check if a sent memo has been read.
*/
-module { name = "ms_check" }
+module { name = "memoserv/check" }
command { service = "MemoServ"; name = "CHECK"; command = "memoserv/check"; }
/*
- * ms_del
+ * memoserv/del
*
* Provides the command memoserv/del.
*
* Used to delete your memos.
*/
-module { name = "ms_del" }
+module { name = "memoserv/del" }
command { service = "MemoServ"; name = "DEL"; command = "memoserv/del"; }
/*
- * ms_ignore
+ * memoserv/ignore
*
* Provides the command memoserv/ignore.
*
@@ -139,7 +130,7 @@ command { service = "MemoServ"; name = "DEL"; command = "memoserv/del"; }
*/
module
{
- name = "ms_ignore"
+ name = "memoserv/ignore"
/*
* The maximum number of entries that may be on a memo ignore list.
@@ -151,37 +142,37 @@ module
command { service = "MemoServ"; name = "IGNORE"; command = "memoserv/ignore"; }
/*
- * ms_info
+ * memoserv/info
*
* Provides the command memoserv/info.
*
* Used to show memo related information about an account or a channel.
*/
-module { name = "ms_info" }
+module { name = "memoserv/info" }
command { service = "MemoServ"; name = "INFO"; command = "memoserv/info"; }
/*
- * ms_list
+ * memoserv/list
*
* Provides the command memoserv/list.
*
* Used to list your current memos.
*/
-module { name = "ms_list" }
+module { name = "memoserv/list" }
command { service = "MemoServ"; name = "LIST"; command = "memoserv/list"; }
/*
- * ms_read
+ * memoserv/read
*
* Provides the command memoserv/read.
*
* Used to read your memos.
*/
-module { name = "ms_read" }
+module { name = "memoserv/read" }
command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
/*
- * ms_rsend
+ * memoserv/rsend
*
* Provides the command memoserv/rsend.
*
@@ -191,10 +182,10 @@ command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
*/
#module
{
- name = "ms_rsend"
+ name = "memoserv/rsend"
/*
- * Only allow Services Operators to use ms_rsend.
+ * Only allow Services Operators to use memoserv/rsend.
*
* This directive is optional.
*/
@@ -203,41 +194,41 @@ command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
#command { service = "MemoServ"; name = "RSEND"; command = "memoserv/rsend"; }
/*
- * ms_send
+ * memoserv/send
*
* Provides the command memoserv/send.
*
* Used to send memos.
*/
-module { name = "ms_send" }
+module { name = "memoserv/send" }
command { service = "MemoServ"; name = "SEND"; command = "memoserv/send"; }
/*
- * ms_sendall
+ * memoserv/sendall
*
* Provides the command memoserv/sendall.
*
* Used to send a mass memo to every registered user.
*/
-module { name = "ms_sendall" }
+module { name = "memoserv/sendall" }
command { service = "MemoServ"; name = "SENDALL"; command = "memoserv/sendall"; permission = "memoserv/sendall"; }
/*
- * ms_set
+ * memoserv/set
*
* Provides the command memoserv/set.
*
* Used to set settings such as how you are notified of new memos, and your memo limit.
*/
-module { name = "ms_set" }
+module { name = "memoserv/set" }
command { service = "MemoServ"; name = "SET"; command = "memoserv/set"; }
/*
- * ms_staff
+ * memoserv/staff
*
* Provides the command memoserv/staff.
*
* Used to send a memo to all registered staff members.
*/
-module { name = "ms_staff" }
+module { name = "memoserv/staff" }
command { service = "MemoServ"; name = "STAFF"; command = "memoserv/staff"; permission = "memoserv/staff"; }
diff --git a/data/modules.example.conf b/data/modules.example.conf
index e921c1e0d..89166e619 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -19,14 +19,14 @@
module { name = "help" }
/*
- * m_dns
+ * dns
*
* Adds support for the DNS protocol. By itself this module does nothing useful,
- * but other modules such as m_dnsbl and os_dns require this.
+ * but other modules such as dnsbl and operserv/dns require this.
*/
#module
{
- name = "m_dns"
+ name = "dns"
/*
* The nameserver to use for resolving hostnames, must be an IP or a resolver configuration file.
@@ -42,7 +42,7 @@ module { name = "help" }
timeout = 5
- /* Only edit below if you are expecting to use os_dns or otherwise answer DNS queries. */
+ /* Only edit below if you are expecting to use operserv/dns or otherwise answer DNS queries. */
/*
* The IP and port services use to listen for DNS queries.
@@ -80,7 +80,7 @@ module { name = "help" }
}
/*
- * m_dnsbl
+ * 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
@@ -88,7 +88,7 @@ module { name = "help" }
*/
#module
{
- name = "m_dnsbl"
+ name = "dnsbl"
/*
* If set, Services will check clients against the DNSBLs when services connect to its uplink.
@@ -179,19 +179,19 @@ module { name = "help" }
}
/*
- * m_helpchan
+ * helpchan
*
* Gives users who are op in the specified help channel usermode +h (helpop).
*/
#module
{
- name = "m_helpchan"
+ name = "helpchan"
helpchannel = "#help"
}
/*
- * m_httpd
+ * httpd
*
* Allows services to serve web pages. By itself, this module does nothing useful.
*
@@ -200,7 +200,7 @@ module { name = "help" }
*/
#module
{
- name = "m_httpd"
+ name = "httpd"
httpd
{
@@ -232,13 +232,13 @@ module { name = "help" }
}
/*
- * m_ldap [EXTRA]
+ * ldap [EXTRA]
*
* This module allows other modules to use LDAP. By itself, this module does nothing useful.
*/
#module
{
- name = "m_ldap"
+ name = "ldap"
ldap
{
@@ -253,14 +253,14 @@ module { name = "help" }
}
/*
- * m_ldap_authentication [EXTRA]
+ * ldap_authentication [EXTRA]
*
* This module allows many commands such as IDENTIFY, RELEASE, RECOVER, GHOST, etc. use
- * LDAP to authenticate users. Requires m_ldap.
+ * LDAP to authenticate users. Requires ldap.
*/
#module
{
- name = "m_ldap_authentication"
+ name = "ldap_authentication"
/*
* The distinguished name used for searching for users's accounts.
@@ -313,16 +313,16 @@ module { name = "help" }
}
/*
- * m_ldap_oper [EXTRA]
+ * ldap_oper [EXTRA]
*
* This module dynamically ties users to Anope opertypes when they identify
- * via LDAP group membership. Requires m_ldap.
+ * via LDAP group membership. Requires ldap.
*
* Note that this doesn't give the user privileges on the IRCd, only in Services.
*/
#module
{
- name = "m_ldap_oper"
+ name = "ldap_oper"
/*
* An optional binddn to use when searching for groups.
@@ -354,13 +354,13 @@ module { name = "help" }
}
/*
- * m_mysql [EXTRA]
+ * mysql [EXTRA]
*
* This module allows other modules to use MySQL.
*/
#module
{
- name = "m_mysql"
+ name = "mysql"
mysql
{
@@ -374,13 +374,13 @@ module { name = "help" }
}
}
/*
- * m_redis
+ * redis
*
* This module allows other modules to use Redis.
*/
#module
{
- name = "m_redis"
+ name = "redis"
/* A redis database */
redis
@@ -399,38 +399,16 @@ module { name = "help" }
}
/*
- * m_regex_pcre [EXTRA]
- *
- * Provides the regex engine regex/pcre, which uses the Perl Compatible Regular Expressions library.
- */
-#module { name = "m_regex_pcre" }
-
-/*
- * m_regex_posix [EXTRA]
- *
- * Provides the regex engine regex/posix, which uses the POSIX compliant regular expressions.
- * This is likely the only regex module you will not need extra libraries for.
- */
-#module { name = "m_regex_posix" }
-
-/*
- * m_regex_tre [EXTRA]
- *
- * Provides the regex engine regex/tre, which uses the TRE regex library.
- */
-#module { name = "m_regex_tre" }
-
-/*
- * m_rewrite
+ * rewrite
*
* Allows rewriting commands sent to/from clients.
*/
-#module { name = "m_rewrite" }
+#module { name = "rewrite" }
#command
{
service = "ChanServ"; name = "CLEAR"; command = "rewrite"
- /* Enable m_rewrite. */
+ /* Enable rewrite. */
rewrite = true
/* Source message to match. A $ can be used to match anything. */
@@ -451,111 +429,47 @@ module { name = "help" }
}
/*
- * m_proxyscan
+ * sasl
*
- * This module allows you to scan connecting clients for open proxies.
- * Note that using this will allow users to get the IP of your services.
- *
- * Currently the two supported proxy types are HTTP and SOCKS5.
- *
- * The proxy scanner works by attempting to connect to clients when they
- * connect to the network, and if they have a proxy running instruct it to connect
- * back to services. If services are able to connect through the proxy to itself
- * then it knows it is an insecure proxy, and will ban it.
+ * Some IRCds allow "SASL" authentication to let users identify to Services
+ * during the IRCd user registration process. If this module is loaded, Services will allow
+ * authenticating users through this mechanism. Supported mechanisms are:
+ * PLAIN, EXTERNAL.
*/
-#module
-{
- name = "m_proxyscan"
-
- /*
- * The target IP services tells the proxy to connect back to. This must be a publicly
- * available IP that remote proxies can connect to.
- */
- #target_ip = "127.0.0.1"
-
- /*
- * The port services tells the proxy to connect to.
- */
- target_port = 7226
-
- /*
- * The listen IP services listen on for incoming connections from suspected proxies.
- * This probably will be the same as target_ip, but may not be if you are behind a firewall (NAT).
- */
- #listen_ip = "127.0.0.1"
-
- /*
- * The port services should listen on for incoming connections from suspected proxies.
- * This most likely will be the same as target_port.
- */
- listen_port = 7226
-
- /*
- * An optional notice sent to clients upon connect.
- */
- #connect_notice = "We will now scan your host for insecure proxies. If you do not consent to this scan please disconnect immediately."
-
- /*
- * Who the notice should be sent from.
- */
- #connect_source = "OperServ"
-
- /*
- * If set, OperServ will add infected clients 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 filled up by bots.
- */
- add_to_akill = yes
-
- /*
- * How long before connections should be timed out.
- */
- timeout = 5
-
- proxyscan
- {
- /* The type of proxy to check for. A comma separated list is allowed. */
- type = "HTTP"
-
- /* The ports to check. */
- port = "80,8080"
-
- /* How long to set the ban for. */
- time = 4h
+#module { name = "sasl" }
- /*
- * The reason to ban the user for.
- * %h is replaced with the type of proxy found.
- * %i is replaced with the IP of proxy found.
- * %p is replaced with the port.
- */
- reason = "You have an open proxy running on your host (%t:%i:%p)"
- }
-}
+/*
+ * sasl_dh-aes [EXTRA]
+ *
+ * Add the DH-AES mechanism to SASL.
+ * Requires sasl to be loaded.
+ * Requires openssl.
+ */
+#module { name = "sasl_dh-aes" }
/*
- * m_sasl
+ * sasl_dh-blowfish [EXTRA]
*
- * Some IRCds allow "SASL" authentication to let users identify to Services
- * during the IRCd user registration process. If this module is loaded, Services will allow
- * authenticating users through this mechanism. Supported mechanisms are:
- * PLAIN, EXTERNAL.
+ * Add the DH-BLOWFISH mechanism to SASL.
+ * Requires sasl to be loaded.
+ * Requires openssl.
*/
-#module { name = "m_sasl" }
+#module { name = "sasl_dh-blowfish" }
/*
- * m_ssl_gnutls [EXTRA]
+ * ssl_gnutls [EXTRA]
*
* This module provides SSL services to Anope using GnuTLS, for example to
* connect to the uplink server(s) via SSL.
*
- * You may only load either m_ssl_gnutls or m_ssl_openssl, bot not both.
+ * You may only load either ssl_gnutls or ssl_openssl, bot not both.
*/
#module
{
- name = "m_ssl_gnutls"
+ name = "ssl_gnutls"
/*
- * An optional certificate and key for m_ssl_gnutls to give to the uplink.
+ * An optional certificate and key for ssl_gnutls to give to the uplink.
*
* You can generate your own certificate and key pair by using:
*
@@ -581,20 +495,20 @@ module { name = "help" }
}
/*
- * m_ssl_openssl [EXTRA]
+ * ssl_openssl [EXTRA]
*
* This module provides SSL services to Anope using OpenSSL, for example to
* connect to the uplink server(s) via SSL.
*
- * You may only load either m_ssl_openssl or m_ssl_gnutls, bot not both.
+ * You may only load either ssl_openssl or ssl_gnutls, bot not both.
*
*/
#module
{
- name = "m_ssl_openssl"
+ name = "ssl_openssl"
/*
- * An optional certificate and key for m_ssl_openssl to give to the uplink.
+ * An optional certificate and key for ssl_openssl to give to the uplink.
*
* You can generate your own certificate and key pair by using:
*
@@ -614,16 +528,16 @@ module { name = "help" }
}
/*
- * m_sql_authentication [EXTRA]
+ * sql_authentication [EXTRA]
*
* This module allows authenticating users against an external SQL database using a custom
* query.
*/
#module
{
- name = "m_sql_authentication"
+ name = "sql_authentication"
- /* SQL engine to use. Should be configured elsewhere with m_mysql, m_sqlite, etc. */
+ /* SQL engine to use. Should be configured elsewhere with mysql, sqlite, etc. */
engine = "mysql/main"
/* Query to execute to authenticate. A non empty result from this query is considered a success,
@@ -665,7 +579,7 @@ module { name = "help" }
}
/*
- * m_sql_log [EXTRA]
+ * sql_log [EXTRA]
*
* This module adds an additional target option to log{} blocks
* that allows logging Service's logs to SQL. To log to SQL, add
@@ -682,24 +596,24 @@ module { name = "help" }
* it if it doesn't exist. This module does not create any indexes (keys)
* on the table and it is recommended you add them yourself as necessary.
*/
-#module { name = "m_sql_log" }
+#module { name = "sql_log" }
/*
- * m_sql_oper [EXTRA]
+ * sql_oper [EXTRA]
*
* This module allows granting users services operator privileges and possibly IRC Operator
* privileges based on an external SQL database using a custom query.
*/
#module
{
- name = "m_sql_oper"
+ name = "sql_oper"
- /* SQL engine to use. Should be configured elsewhere with m_mysql, m_sqlite, etc. */
+ /* SQL engine to use. Should be configured elsewhere with mysql, sqlite, etc. */
engine = "mysql/main"
/* Query to execute to determine if a user should have operator privileges.
* A field named opertype must be returned in order to link the user to their oper type.
- * The oper types must be configured earlier in services.conf.
+ * The oper types must be configured earlier in anope.conf.
*
* If a field named modes is returned from this query then those modes are set on the user.
* Without this, only a simple +o is sent.
@@ -711,13 +625,13 @@ module { name = "help" }
}
/*
- * m_sqlite [EXTRA]
+ * sqlite [EXTRA]
*
* This module allows other modules to use SQLite.
*/
#module
{
- name = "m_sqlite"
+ name = "sqlite"
/* A SQLite database */
sqlite
@@ -737,7 +651,7 @@ module { name = "help" }
* as they could over IRC. If you are using the default configuration you should be able to access
* this panel by visiting http://127.0.0.1:8080 in your web browser from the machine Anope is running on.
*
- * This module requires m_httpd.
+ * This module requires httpd.
*/
#module
{
@@ -754,23 +668,23 @@ module { name = "help" }
}
/*
- * m_xmlrpc
+ * 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.
+ * By itself this module does nothing, but allows other modules (xmlrpc_main) to receive and send XMLRPC queries.
*/
#module
{
- name = "m_xmlrpc"
+ name = "xmlrpc"
- /* Web service to use. Requires m_httpd. */
+ /* Web service to use. Requires httpd. */
server = "httpd/main"
}
/*
- * m_xmlrpc_main
+ * xmlrpc_main
*
* Adds the main XMLRPC core functions.
- * Requires m_xmlrpc.
+ * Requires xmlrpc.
*/
-#module { name = "m_xmlrpc_main" }
+#module { name = "xmlrpc_main" }
diff --git a/data/ngircd.example.conf b/data/ngircd.example.conf
new file mode 100644
index 000000000..7df67ce64
--- /dev/null
+++ b/data/ngircd.example.conf
@@ -0,0 +1,234 @@
+
+module
+{
+ name = "protocol/ngircd"
+}
+
+usermode
+{
+ name = "NOCTCP"
+ character = "b"
+}
+
+usermode
+{
+ name = "BOT"
+ character = "B"
+}
+
+usermode
+{
+ name = "COMMONCHANS"
+ character = "C"
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "PROTECTED"
+ character = "q"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "RESTRICTED"
+ character = "r"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "R"
+ setable = no
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "CLOAK"
+ character = "x"
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channemode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "HALFOP"
+ character = "h"
+ status = "%"
+ level = 2
+}
+
+channelmode
+{
+ name = "OP"
+ character = "@"
+ status = "@"
+ level = 3
+}
+
+channelmode
+{
+ name = "PROTECT"
+ character = "a"
+ status = "&"
+ level = 4
+}
+
+channelmode
+{
+ name = "OWNER"
+ character = "q"
+ status = "~"
+ level = 5
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "PERM"
+ character = "P"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "NOKICK"
+ character = "Q"
+}
+
+channelmode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "NOINVITE"
+ character = "V"
+}
+
+channelmode
+{
+ name = "SSL"
+ character = "z"
+}
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf
index ee036d086..1f07831c4 100644
--- a/data/nickserv.example.conf
+++ b/data/nickserv.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "nickserv"
+ name = "nickserv/main"
/*
* The name of the client that should be NickServ.
@@ -109,7 +100,7 @@ module
* - ns_keepmodes: Enables keepmodes, which retains user modes across sessions
* - ns_no_expire: Enables no expire. Unconfirmed expire overrules this.
*
- * This directive is optional, if left blank, the options will default to ns_secure, memo_signon, and
+ * This directive is optional, if left blank, the options will default to nickserv/secure, memo_signon, and
* memo_receive. If you really want no defaults, use "none" by itself as the option.
*/
defaults = "ns_secure ns_private hide_email hide_mask memo_signon memo_receive autoop"
@@ -128,8 +119,8 @@ module
expire = 21d
/*
- * Prevents the use of the ACCESS and CERT (excluding their LIST subcommand), DROP, FORBID, SUSPEND,
- * GETPASS and SET PASSWORD commands by services operators on other services operators.
+ * Prevents the use of the ACCESS and CERT (excluding their LIST subcommand), DROP, FORBID, SUSPEND
+ * and SET PASSWORD commands by services operators on other services operators.
*
* This directive is optional, but recommended.
*/
@@ -239,7 +230,7 @@ command_group
command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
/*
- * ns_access
+ * nickserv/access
*
* Provides the command nickserv/access.
*
@@ -247,7 +238,7 @@ command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
*/
module
{
- name = "ns_access"
+ name = "nickserv/access"
/*
* The maximum number of entries allowed on a nickname's access list.
@@ -266,7 +257,7 @@ module
command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
/*
- * ns_ajoin
+ * nickserv/ajoin
*
* Provides the command nickserv/ajoin.
*
@@ -274,7 +265,7 @@ command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
*/
module
{
- name = "ns_ajoin"
+ name = "nickserv/ajoin"
/*
* The maximum number of channels a user can have on NickServ's AJOIN command.
@@ -284,17 +275,17 @@ module
command { service = "NickServ"; name = "AJOIN"; command = "nickserv/ajoin"; }
/*
- * ns_alist
+ * nickserv/alist
*
* Provides the command nickserv/alist.
*
* Used for viewing what channels you have access to.
*/
-module { name = "ns_alist" }
+module { name = "nickserv/alist" }
command { service = "NickServ"; name = "ALIST"; command = "nickserv/alist"; }
/*
- * ns_cert
+ * nickserv/cert
*
* Provides the command nickserv/cert.
*
@@ -302,7 +293,7 @@ command { service = "NickServ"; name = "ALIST"; command = "nickserv/alist"; }
*/
module
{
- name = "ns_cert"
+ name = "nickserv/cert"
/*
* The maximum number of entries allowed on a nickname's certificate fingerprint list.
@@ -313,39 +304,27 @@ module
command { service = "NickServ"; name = "CERT"; command = "nickserv/cert"; }
/*
- * ns_drop
+ * nickserv/drop
*
* Provides the command nickserv/drop.
*
* Used for unregistering names.
*/
-module { name = "ns_drop" }
+module { name = "nickserv/drop" }
command { service = "NickServ"; name = "DROP"; command = "nickserv/drop"; }
/*
- * ns_getemail
+ * nickserv/getemail
*
* Provides the command nickserv/getemail.
*
* Used for getting registered accounts by searching for emails.
*/
-module { name = "ns_getemail" }
+module { name = "nickserv/getemail" }
command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"; permission = "nickserv/getemail"; group = "nickserv/admin"; }
/*
- * ns_getpass
- *
- * Provides the command nickserv/getpass.
- *
- * Used for getting users passwords.
- *
- * Requires no encryption is being used.
- */
-#module { name = "ns_getpass" }
-#command { service = "NickServ"; name = "GETPASS"; command = "nickserv/getpass"; permission = "nickserv/getpass"; }
-
-/*
- * ns_group
+ * nickserv/group
*
* Provides the commands nickserv/group, nickserv/glist, and nickserv/ungroup.
*
@@ -353,7 +332,7 @@ command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"
*/
module
{
- name = "ns_group"
+ name = "nickserv/group"
/*
* The maximum number of nicks allowed in a group.
@@ -376,7 +355,7 @@ command { service = "NickServ"; name = "GROUP"; command = "nickserv/group"; }
command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup"; }
/*
- * ns_identify
+ * nickserv/identify
*
* Provides the command nickserv/identify.
*
@@ -384,7 +363,7 @@ command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup";
*/
module
{
- name = "ns_identify"
+ name = "nickserv/identify"
/*
* If set, limits the number of concurrent users that can be logged in as a given account at once.
@@ -395,14 +374,14 @@ command { service = "NickServ"; name = "ID"; command = "nickserv/identify"; hide
command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"; }
/*
- * ns_info
+ * nickserv/info
*
* Provides the commands:
* nickserv/info. - Used for gathering information about an account.
* nickserv/set/hide, nickserv/saset/hide - Used for configuring which options are publicly shown in nickserv/info.
*
*/
-module { name = "ns_info" }
+module { name = "nickserv/info" }
command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
@@ -410,7 +389,7 @@ command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/h
/*
- * ns_list
+ * nickserv/list
*
* Provides the commands:
* nickserv/list - Used for retrieving and searching the registered account list.
@@ -419,7 +398,7 @@ command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/h
*/
module
{
- name = "ns_list"
+ name = "nickserv/list"
/*
* The maximum number of nicks to be returned for a NickServ LIST command.
@@ -433,17 +412,17 @@ command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/sase
/*
- * ns_logout
+ * nickserv/logout
*
* Provides the command nickserv/logout.
*
* Used for logging out of your account.
*/
-module { name = "ns_logout" }
+module { name = "nickserv/logout" }
command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
/*
- * ns_recover
+ * nickserv/recover
*
* Provides the command nickserv/recover.
*
@@ -451,7 +430,7 @@ command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
*/
module
{
- name = "ns_recover"
+ name = "nickserv/recover"
/*
* If set, Services will svsnick and svsjoin users who use the recover
@@ -467,7 +446,7 @@ command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover";
#command { service = "NickServ"; name = "RELEASE"; command = "nickserv/recover"; }
/*
- * ns_register
+ * nickserv/register
*
* Provides the commands nickserv/confirm, nickserv/register, and nickserv/resend.
*
@@ -475,7 +454,7 @@ command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover";
*/
module
{
- name = "ns_register"
+ name = "nickserv/register"
/*
* Registration confirmation setting. Set to "none" for no registration confirmation,
@@ -510,17 +489,17 @@ command { service = "NickServ"; name = "REGISTER"; command = "nickserv/register"
command { service = "NickServ"; name = "RESEND"; command = "nickserv/resend"; }
/*
- * ns_resetpass
+ * nickserv/resetpass
*
* Provides the command nickserv/resetpass.
*
* Used for resetting passwords by emailing users a temporary one.
*/
-module { name = "ns_resetpass" }
+module { name = "nickserv/resetpass" }
command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpass"; }
/*
- * ns_set
+ * nickserv/set
*
* Provides the commands:
* nickserv/set, nickserv/saset - Dummy help wrappers for the SET and SASET commands.
@@ -537,7 +516,7 @@ command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpas
*/
module
{
- name = "ns_set"
+ name = "nickserv/set"
/*
* Allow the use of the IMMED option in the NickServ SET KILL command.
@@ -581,14 +560,14 @@ command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/sas
/*
- * ns_set_misc
+ * nickserv/set_misc
*
* Provides the command nickserv/set/misc.
*
* Allows you to create arbitrary commands to set data, and have that data show up in nickserv/info.
* A field named misc_description may be given for use with help output.
*/
-module { name = "ns_set_misc" }
+module { name = "nickserv/set_misc" }
command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc"; misc_description = _("Associate a URL with your account"); }
command { service = "NickServ"; name = "SASET URL"; command = "nickserv/saset/misc"; misc_description = _("Associate a URL with this account"); permission = "nickserv/saset/url"; group = "nickserv/admin"; }
#command { service = "NickServ"; name = "SET ICQ"; command = "nickserv/set/misc"; misc_description = _("Associate an ICQ account with your account"); }
@@ -599,17 +578,17 @@ command { service = "NickServ"; name = "SASET URL"; command = "nickserv/saset/mi
#command { service = "NickServ"; name = "SASET FACEBOOK"; command = "nickserv/saset/misc"; misc_description = _("Associate a Facebook URL with this account"); permission = "nickserv/saset/facebook"; group = "nickserv/admin"; }
/*
- * ns_status
+ * nickserv/status
*
* Provides the nickserv/status command.
*
* Used to determine if a user is recognized or identified by services.
*/
-module { name = "ns_status" }
+module { name = "nickserv/status" }
command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
/*
- * ns_suspend
+ * nickserv/suspend
*
* Provides the commands nickserv/suspend and nickserv/unsuspend.
*
@@ -617,7 +596,7 @@ command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
*/
module
{
- name = "ns_suspend"
+ name = "nickserv/suspend"
/*
* The length of time before a suspended nick becomes unsuspended.
@@ -637,13 +616,13 @@ command { service = "NickServ"; name = "SUSPEND"; command = "nickserv/suspend";
command { service = "NickServ"; name = "UNSUSPEND"; command = "nickserv/unsuspend"; permission = "nickserv/suspend"; group = "nickserv/admin"; }
/*
- * ns_update
+ * nickserv/update
*
* Provides the command nickserv/update.
*
* Used to update your status on all channels, turn on your vHost, etc.
*/
-module { name = "ns_update" }
+module { name = "nickserv/update" }
command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
@@ -652,14 +631,14 @@ command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
*/
/*
- * ns_maxemail
+ * nickserv/maxemail
*
* Limits how many times the same email address may be used in Anope
* to register accounts.
*/
#module
{
- name = "ns_maxemail"
+ name = "nickserv/maxemail"
/*
* The limit to how many registered nicks can use the same e-mail address. If set to 0 or left
diff --git a/data/operserv.example.conf b/data/operserv.example.conf
index 0c82f1e06..6deedddcd 100644
--- a/data/operserv.example.conf
+++ b/data/operserv.example.conf
@@ -40,15 +40,6 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#services,#mychan"
}
/*
@@ -58,7 +49,7 @@ service
*/
module
{
- name = "operserv"
+ name = "operserv/main"
/*
* The name of the client that should be OperServ.
@@ -135,27 +126,27 @@ module
command { service = "OperServ"; name = "HELP"; command = "generic/help"; }
/*
- * os_akill
+ * operserv/akill
*
* Provides the command operserv/akill.
*
* Used to ban users from the network.
*/
-module { name = "os_akill" }
+module { name = "operserv/akill" }
command { service = "OperServ"; name = "AKILL"; command = "operserv/akill"; permission = "operserv/akill"; }
/*
- * os_chankill
+ * operserv/chankill
*
* Provides the command operserv/chankill.
*
* Used to akill users from an entire channel.
*/
-module { name = "os_chankill" }
+module { name = "operserv/chankill" }
command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"; permission = "operserv/chankill"; }
/*
- * os_defcon
+ * operserv/defcon
*
* Provides the command operserv/defcon.
*
@@ -164,7 +155,7 @@ command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"
*/
#module
{
- name = "os_defcon"
+ name = "operserv/defcon"
/*
* Default DefCon level (1-5) to use when starting Services up. Level 5 constitutes normal operation
@@ -263,7 +254,7 @@ command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"
#command { service = "OperServ"; name = "DEFCON"; command = "operserv/defcon"; permission = "operserv/defcon"; }
/*
- * os_dns
+ * operserv/dns
*
* Provides the command operserv/dns.
*
@@ -295,7 +286,7 @@ command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"
*/
#module
{
- name = "os_dns"
+ name = "operserv/dns"
/* TTL for records. This should be very low if your records change often. */
ttl = 1m
@@ -324,99 +315,99 @@ command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"
#command { service = "OperServ"; name = "DNS"; command = "operserv/dns"; permission = "operserv/dns"; }
/*
- * os_config
+ * operserv/config
*
* Provides the command operserv/config.
*
* Used to view and set configuration options while services are running.
*/
-module { name = "os_config" }
+module { name = "operserv/config" }
command { service = "OperServ"; name = "CONFIG"; command = "operserv/config"; permission = "operserv/config"; }
/*
- * os_forbid
+ * operserv/forbid
*
* Provides the command operserv/forbid.
*
* Used to forbid specific nicks, channels, emails, etc. from being used.
*/
-module { name = "os_forbid" }
+module { name = "operserv/forbid" }
command { service = "OperServ"; name = "FORBID"; command = "operserv/forbid"; permission = "operserv/forbid"; }
/*
- * os_ignore
+ * operserv/ignore
*
* Provides the command operserv/ignore.
*
* Used to make Services ignore users.
*/
-module { name = "os_ignore" }
+module { name = "operserv/ignore" }
command { service = "OperServ"; name = "IGNORE"; command = "operserv/ignore"; permission = "operserv/ignore"; }
/*
- * os_info
+ * operserv/info
*
* Provides the command operserv/info.
*
* Used to add oper only notes to users and channels.
*/
-module { name = "os_info" }
+module { name = "operserv/info" }
command { service = "OperServ"; name = "INFO"; command = "operserv/info"; permission = "operserv/info"; }
/*
- * os_jupe
+ * operserv/jupe
*
* Provides the command operserv/jupe.
*
* Used to disconnect servers from the network and prevent them from relinking.
*/
-module { name = "os_jupe" }
+module { name = "operserv/jupe" }
command { service = "OperServ"; name = "JUPE"; command = "operserv/jupe"; permission = "operserv/jupe"; }
/*
- * os_kick
+ * operserv/kick
*
* Provides the command operserv/kick.
*
* Used to kick users from channels.
*/
-module { name = "os_kick" }
+module { name = "operserv/kick" }
command { service = "OperServ"; name = "KICK"; command = "operserv/kick"; permission = "operserv/kick"; }
/*
- * os_kill
+ * operserv/kill
*
* Provides the command operserv/kill.
*
* Used to forcibly disconnect users from the network.
*/
-module { name = "os_kill" }
+module { name = "operserv/kill" }
command { service = "OperServ"; name = "KILL"; command = "operserv/kill"; permission = "operserv/kill"; }
/*
- * os_list
+ * operserv/list
*
* Provides the commands operserv/chanlist and operserv/userlist.
*
* Used to list and search the channels and users currently on the network.
*/
-module { name = "os_list" }
+module { name = "operserv/list" }
command { service = "OperServ"; name = "CHANLIST"; command = "operserv/chanlist"; permission = "operserv/chanlist"; }
command { service = "OperServ"; name = "USERLIST"; command = "operserv/userlist"; permission = "operserv/userlist"; }
/*
- * os_login
+ * operserv/login
*
* Provides the commands operserv/login and operserv/logout.
*
* Used to login to OperServ, only required if your oper block requires this.
*/
-module { name = "os_login" }
+module { name = "operserv/login" }
command { service = "OperServ"; name = "LOGIN"; command = "operserv/login"; }
command { service = "OperServ"; name = "LOGOUT"; command = "operserv/logout"; }
/*
- * os_logsearch
+ * operserv/logsearch
*
* Provides the command operserv/logsearch.
*
@@ -424,7 +415,7 @@ command { service = "OperServ"; name = "LOGOUT"; command = "operserv/logout"; }
*/
module
{
- name = "os_logsearch"
+ name = "operserv/logsearch"
/* The log file name to search. There should be a log{} block configured to log
* to a file of this name.
@@ -434,41 +425,41 @@ module
command { service = "OperServ"; name = "LOGSEARCH"; command = "operserv/logsearch"; permission = "operserv/logsearch"; }
/*
- * os_mode
+ * operserv/mode
*
* Provides the commands operserv/mode and operserv/umode.
*
* Used to change user and channel modes.
*/
-module { name = "os_mode" }
+module { name = "operserv/mode" }
command { service = "OperServ"; name = "UMODE"; command = "operserv/umode"; permission = "operserv/umode"; }
command { service = "OperServ"; name = "MODE"; command = "operserv/mode"; permission = "operserv/mode"; }
/*
- * os_modinfo
+ * operserv/modinfo
*
* Provides the commands operserv/modinfo and operserv/modlist.
*
* Used to show information about loaded modules.
*/
-module { name = "os_modinfo" }
+module { name = "operserv/modinfo" }
command { service = "OperServ"; name = "MODINFO"; command = "operserv/modinfo"; permission = "operserv/modinfo"; }
command { service = "OperServ"; name = "MODLIST"; command = "operserv/modlist"; permission = "operserv/modinfo"; }
/*
- * os_module
+ * operserv/module
*
* Provides the commands operserv/modload, operserv/modreload, and operserv/modunload.
*
* Used to load, reload, and unload modules.
*/
-module { name = "os_module" }
+module { name = "operserv/module" }
command { service = "OperServ"; name = "MODLOAD"; command = "operserv/modload"; permission = "operserv/modload"; }
command { service = "OperServ"; name = "MODRELOAD"; command = "operserv/modreload"; permission = "operserv/modload"; }
command { service = "OperServ"; name = "MODUNLOAD"; command = "operserv/modunload"; permission = "operserv/modload"; }
/*
- * os_news
+ * operserv/news
*
* Provides the commands operserv/logonnews, operserv/opernews, and operserv/randomnews.
*
@@ -476,7 +467,7 @@ command { service = "OperServ"; name = "MODUNLOAD"; command = "operserv/modunloa
*/
module
{
- name = "os_news"
+ name = "operserv/news"
/*
* The service bot names to use to send news to users on connection
@@ -497,48 +488,48 @@ command { service = "OperServ"; name = "OPERNEWS"; command = "operserv/opernews"
command { service = "OperServ"; name = "RANDOMNEWS"; command = "operserv/randomnews"; permission = "operserv/news"; }
/*
- * os_noop
+ * operserv/noop
*
* Provides the command operserv/noop.
*
* Used to NOOP a server, which prevents users from opering on that server.
*/
-module { name = "os_noop" }
+module { name = "operserv/noop" }
command { service = "OperServ"; name = "NOOP"; command = "operserv/noop"; permission = "operserv/noop"; }
/*
- * os_oline
+ * operserv/oline
*
* Provides the command operserv/oline.
*
* Used to set oper flags on users, and is specific to UnrealIRCd.
* See /helpop ?svso on your IRCd for more information.
*/
-module { name = "os_oline" }
+module { name = "operserv/oline" }
command { service = "OperServ"; name = "OLINE"; command = "operserv/oline"; permission = "operserv/oline"; }
/*
- * os_oper
+ * operserv/oper
*
* Provides the command operserv/oper.
*
* Used to configure opers and show information about opertypes.
*/
-module { name = "os_oper" }
+module { name = "operserv/oper" }
command { service = "OperServ"; name = "OPER"; command = "operserv/oper"; permission = "operserv/oper"; }
/*
- * os_reload
+ * operserv/reload
*
* Provides the command operserv/reload.
*
- * Used to reload the services.conf configuration file.
+ * Used to reload the anope.conf configuration file.
*/
-module { name = "os_reload" }
+module { name = "operserv/reload" }
command { service = "OperServ"; name = "RELOAD"; command = "operserv/reload"; permission = "operserv/reload"; }
/*
- * os_session
+ * operserv/session
*
* Provides the commands operserv/exception and operserv/session.
*
@@ -551,25 +542,27 @@ command { service = "OperServ"; name = "RELOAD"; command = "operserv/reload"; pe
*/
module
{
- name = "os_session"
+ name = "operserv/session"
/*
* Default session limit per host. Once a host reaches its session limit, all clients attempting
* to connect from that host will be killed.
*
- * This directive is required if os_session is loaded.
+ * This directive is required if operserv/session is loaded.
*/
defaultsessionlimit = 3
/*
* The maximum session limit that may be set for a host in an exception.
*
- * This directive is required if os_session is loaded.
+ * This directive is required if operserv/session is loaded.
*/
maxsessionlimit = 100
/*
* Sets the default expiry time for session exceptions.
+ *
+ * This directive is required if operserv/session is loaded.
*/
#exceptionexpiry = 1d
@@ -622,7 +615,7 @@ command { service = "OperServ"; name = "EXCEPTION"; command = "operserv/exceptio
command { service = "OperServ"; name = "SESSION"; command = "operserv/session"; permission = "operserv/session"; }
/*
- * os_set
+ * operserv/set
*
* Provides the command operserv/set.
*
@@ -630,7 +623,7 @@ command { service = "OperServ"; name = "SESSION"; command = "operserv/session";
*/
module
{
- name = "os_set"
+ name = "operserv/set"
/*
* If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant
@@ -643,56 +636,56 @@ module
command { service = "OperServ"; name = "SET"; command = "operserv/set"; permission = "operserv/set"; }
/*
- * os_shutdown
+ * operserv/shutdown
*
* Provides the commands operserv/quit, operserv/restart, and operserv/shutdown.
*
* Used to quit, restart, or shutdown services.
*/
-module { name = "os_shutdown" }
+module { name = "operserv/shutdown" }
command { service = "OperServ"; name = "QUIT"; command = "operserv/quit"; permission = "operserv/quit"; }
command { service = "OperServ"; name = "RESTART"; command = "operserv/restart"; permission = "operserv/restart"; }
command { service = "OperServ"; name = "SHUTDOWN"; command = "operserv/shutdown"; permission = "operserv/shutdown"; }
/*
- * os_stats
+ * operserv/stats
*
* Provides the operserv/stats command.
*
* Used to show statistics about services.
*/
-module { name = "os_stats" }
+module { name = "operserv/stats" }
command { service = "OperServ"; name = "STATS"; command = "operserv/stats"; permission = "operserv/stats"; }
/*
- * os_svs
+ * operserv/svs
*
* Provides the commands operserv/svsnick, operserv/svsjoin, and operserv/svspart.
*
* Used to force users to change nicks, join and part channels.
*/
-module { name = "os_svs" }
+module { name = "operserv/svs" }
command { service = "OperServ"; name = "SVSNICK"; command = "operserv/svsnick"; permission = "operserv/svs"; }
command { service = "OperServ"; name = "SVSJOIN"; command = "operserv/svsjoin"; permission = "operserv/svs"; }
command { service = "OperServ"; name = "SVSPART"; command = "operserv/svspart"; permission = "operserv/svs"; }
/*
- * os_sxline
+ * operserv/sxline
*
* Provides the operserv/snline and operserv/sqline commands.
*
* Used to ban real names, nick names, and possibly channels.
*/
-module { name = "os_sxline" }
+module { name = "operserv/sxline" }
command { service = "OperServ"; name = "SNLINE"; command = "operserv/snline"; permission = "operserv/snline"; }
command { service = "OperServ"; name = "SQLINE"; command = "operserv/sqline"; permission = "operserv/sqline"; }
/*
- * os_update
+ * operserv/update
*
* Provides the operserv/update command.
*
* Use to immediately update the databases.
*/
-module { name = "os_update" }
+module { name = "operserv/update" }
command { service = "OperServ"; name = "UPDATE"; command = "operserv/update"; permission = "operserv/update"; }
diff --git a/data/plexus.example.conf b/data/plexus.example.conf
new file mode 100644
index 000000000..9d1204828
--- /dev/null
+++ b/data/plexus.example.conf
@@ -0,0 +1,294 @@
+
+module
+{
+ name = "protocol/plexus"
+}
+
+usermode
+{
+ name = "ADMIN"
+ character = "a"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "NOCTCP"
+ character = "c"
+}
+
+usermode
+{
+ name = "SOFTCALLERID"
+ character = "G"
+}
+
+usermode
+{
+ name = "CALLERID"
+ character = "g"
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "LOCOPS"
+ character = "l"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "NETADMIN"
+ character = "N"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "PRIV"
+ character = "p"
+}
+
+usermode
+{
+ name = "ROUTING"
+ character = "q"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+usermode
+{
+ name = "REGPRIV"
+ character = "R"
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "SSL"
+ character = "S"
+ setable = no
+}
+
+usermode
+{
+ name = "PROTECTEDF"
+ character = "U"
+ setable = no
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "WEBIRC"
+ character = "W"
+ setable = no
+}
+
+usermode
+{
+ name = "CLOAK"
+ character = "x"
+}
+
+usermode
+{
+ name = "OPERWALL"
+ character = "z"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channemode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "HALFOP"
+ characater = "h"
+ status = "%"
+ level = 2
+}
+
+channelmode
+{
+ name = "OP"
+ character = "o"
+ status = "@"
+ level = 3
+}
+
+channelmode
+{
+ name = "PROTECT"
+ character = "a"
+ status = "~"
+ level = 4
+}
+
+channelmode
+{
+ name = "OWNER"
+ character = "q"
+ status = "*"
+ level = 5
+}
+
+_____________
+
+channelmode
+{
+ name = "BANDWIDTHSAVER"
+ character = "B"
+}
+
+channelmode
+{
+ name = "NOCTCP"
+ character = "C"
+}
+
+channelmode
+{
+ name = "BLOCKCOLOR"
+ character = "c"
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
+channelmode
+{
+ name = "SSL"
+ character = "S"
+}
+
+channelmode
+{
+ name = "PERM"
+ character = "z"
+}
+
diff --git a/data/ratbox.example.conf b/data/ratbox.example.conf
new file mode 100644
index 000000000..b5fc4546d
--- /dev/null
+++ b/data/ratbox.example.conf
@@ -0,0 +1,174 @@
+
+module
+{
+ name = "protocol/ratbox"
+}
+
+usermode
+{
+ name = "ADMIN"
+ character = "a"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "CALLERID"
+ character = "g"
+}
+
+usermode
+{
+ name = "DEAF"
+ character = "D"
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "LOCOPS"
+ character = "l"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "PROTECTED"
+ character = "S"
+ setable = no
+}
+
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "OPERWALL"
+ character = "z"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channemode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "OP"
+ character = "o"
+ status = "@"
+ level = 2
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "r"
+}
+
+channelmode
+{
+ name = "SSL"
+ character = "S"
+}
+
+
diff --git a/data/rfc1459.conf b/data/rfc1459.conf
new file mode 100644
index 000000000..81ced1ac0
--- /dev/null
+++ b/data/rfc1459.conf
@@ -0,0 +1,24 @@
+
+include
+{
+ name = "ascii.conf"
+}
+
+casemap
+{
+ lower = "{"
+ upper = "["
+}
+
+casemap
+{
+ lower = "}"
+ upper = "]"
+}
+
+casemap
+{
+ lower = "|"
+ upper = "\""
+}
+
diff --git a/data/stats.standalone.example.conf b/data/stats.standalone.example.conf
deleted file mode 100644
index 8db7c9999..000000000
--- a/data/stats.standalone.example.conf
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Example configuration file for Services. After making the appropriate
- * changes to this file, place it in the Services conf directory (as
- * specified in the "configure" script, default /home/username/services/conf)
- * under the name "services.conf".
- *
- * The format of this file is fairly simple: three types of comments are supported:
- * - All text after a '#' on a line is ignored, as in shell scripting
- * - All text after '//' on a line is ignored, as in C++
- * - A block of text like this one is ignored, as in C
- *
- * Outside of comments, there are three structures: blocks, keys, and values.
- *
- * A block is a named container, which contains a number of key to value pairs
- * - you may think of this as an array.
- *
- * A block is created like so:
- * foobar
- * {
- * moo = "cow"
- * foo = bar
- * }
- *
- * Note that nameless blocks are allowed and are often used with comments to allow
- * easily commenting an entire block, for example:
- * #foobar
- * {
- * moo = "cow"
- * foo = bar
- * }
- * is an entirely commented block.
- *
- * Keys are case insensitive. Values depend on what key - generally, information is
- * given in the key comment. The quoting of values (and most other syntax) is quite
- * flexible, however, please do not forget to quote your strings:
- *
- * "This is a parameter string with spaces in it"
- *
- * If you need to include a double quote inside a quoted string, precede it
- * by a backslash:
- *
- * "This string has \"double quotes\" in it"
- *
- * Time parameters can be specified either as an integer representing a
- * number of seconds (e.g. "3600" = 1 hour), or as an integer with a unit
- * specifier: "s" = seconds, "m" = minutes, "h" = hours, "d" = days.
- * Combinations (such as "1h30m") are not permitted. Examples (all of which
- * represent the same length of time, one day):
- *
- * "86400", "86400s", "1440m", "24h", "1d"
- *
- * In the documentation for each directive, one of the following will be
- * included to indicate whether an option is required:
- *
- * [REQUIRED]
- * Indicates a directive which must be given. Without it, Services will
- * not start.
- *
- * [RECOMMENDED]
- * Indicates a directive which may be omitted, but omitting it may cause
- * undesirable side effects.
- *
- * [OPTIONAL]
- * Indicates a directive which is optional. If not given, the feature
- * will typically be disabled. If this is not the case, more
- * information will be given in the documentation.
- *
- * [DISCOURAGED]
- * Indicates a directive which may cause undesirable side effects if
- * specified.
- *
- * [DEPRECATED]
- * Indicates a directive which will disappear in a future version of
- * Services, usually because its functionality has been either
- * superseded by that of other directives or incorporated into the main
- * program.
- */
-
-/*
- * [OPTIONAL] Defines
- *
- * You can define values to other values, which can be used to easily change
- * many values in the configuration. at once.
- */
-
-/*
- * The services.host define is used in multiple different locations throughout the
- * configuration for services clients hostnames.
- */
-define
-{
- name = "services.host"
- value = "services.localhost.net"
-}
-
-/*
- * [OPTIONAL] Additional Includes
- *
- * You can include additional configuration files here.
- * You may also include executable files, which will be executed and
- * the output from it will be included into your configuration.
- */
-
-#include
-{
- type = "file"
- name = "some.conf"
-}
-
-#include
-{
- type = "executable"
- name = "/usr/bin/wget -q -O - http://some.misconfigured.network.com/services.conf"
-}
-
-/*
- * [REQUIRED] IRCd Config
- *
- * This section is used to set up Anope to connect to your IRC network.
- * This section can be included multiple times, and Anope will attempt to
- * connect to each server until it finally connects.
- *
- * Each uplink IRCd should have a corresponding configuration to allow Services
- * to link to it.
- *
- * An example configuration for InspIRCd that is compatible with the below uplink
- * and serverinfo configuration would look like:
- *
- * <link name="services.localhost.net"
- * ipaddr="127.0.0.1"
- * port="7000"
- * sendpass="mypassword"
- * recvpass="mypassword">
- * <uline server="services.localhost.net" silent="yes">
- * <bind address="127.0.0.1" port="7000" type="servers">
- *
- * An example configuration for UnrealIRCd that is compatible with the below uplink
- * and serverinfo configuration would look like:
- *
- * link services.localhost.net
- * {
- * username *;
- * hostname *;
- * bind-ip "127.0.0.1";
- * port 7000;
- * hub *;
- * password-connect "mypassword";
- * password-receive "mypassword";
- * class servers;
- * };
- * ulines { services.localhost.net; };
- * listen 127.0.0.1:7000;
- */
-uplink
-{
- /*
- * The IP or hostname of the IRC server you wish to connect Services to.
- * Usually, you will want to connect Services over 127.0.0.1 (aka localhost).
- *
- * NOTE: On some shell providers, this will not be an option.
- */
- host = "127.0.0.1"
-
- /*
- * Enable if Services should connect using IPv6.
- */
- ipv6 = no
-
- /*
- * Enable if Services should connect using SSL.
- * You must have an SSL module loaded for this to work.
- */
- ssl = no
-
- /*
- * The port to connect to.
- * The IRCd *MUST* be configured to listen on this port, and to accept
- * server connections.
- *
- * Refer to your IRCd documentation for how this is to be done.
- */
- port = 7000
-
- /*
- * The password to send to the IRC server for authentication.
- * This must match the link block on your IRCd.
- *
- * Refer to your IRCd documentation for more information on link blocks.
- */
- password = "mypassword"
-}
-
-/*
- * [REQUIRED] Server Information
- *
- * This section contains information about the Services server.
- */
-serverinfo
-{
- /*
- * The hostname that Services will be seen as, it must have no conflicts with any
- * other server names on the rest of your IRC network. Note that it does not have
- * to be an existing hostname, just one that isn't on your network already.
- */
- name = "stats.localhost.net"
-
- /*
- * The text which should appear as the server's information in /whois and similar
- * queries.
- */
- description = "Stats for IRC Networks"
-
- /*
- * The local address that Services will bind to before connecting to the remote
- * server. This may be useful for multihomed hosts. If omitted, Services will let
- * the Operating System choose the local address. This directive is optional.
- *
- * If you don't know what this means or don't need to use it, just leave this
- * directive commented out.
- */
- #localhost = "nowhere."
-
- /*
- * What Server ID to use for this connection?
- * Note: This should *ONLY* be used for TS6/P10 IRCds. Refer to your IRCd documentation
- * to see if this is needed.
- */
- #id = "00A"
-
- /*
- * The filename containing the Services process ID. The path is relative to the
- * services root directory.
- */
- pid = "data/services.pid"
-
- /*
- * The filename containing the Message of the Day. The path is relative to the
- * services root directory.
- */
- motd = "conf/services.motd"
-}
-
-/*
- * [REQUIRED] Protocol module
- *
- * This directive tells Anope which IRCd Protocol to speak when connecting.
- * You MUST modify this to match the IRCd you run.
- *
- * Supported:
- * - bahamut
- * - charybdis
- * - hybrid
- * - inspircd12
- * - inspircd20
- * - ngircd
- * - plexus
- * - ratbox
- * - unreal
- */
-module
-{
- name = "inspircd20"
-}
-
-/*
- * [REQUIRED] Network Information
- *
- * This section contains information about the IRC network that Services will be
- * connecting to.
- */
-networkinfo
-{
- /*
- * This is the name of the network that Services will be running on.
- */
- networkname = "LocalNet"
-
- /*
- * Set this to the maximum allowed nick length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
- */
- nicklen = 31
-
- /* Set this to the maximum allowed ident length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
- */
- userlen = 10
-
- /* Set this to the maximum allowed hostname length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Services being disconnected from the network.
- */
- hostlen = 64
-
- /* Set this to the maximum allowed channel length on your network.
- */
- chanlen = 32
-
- /* The maximum number of list modes settable on a channel (such as b, e, I).
- * Comment out or set to 0 to disable.
- */
- modelistsize = 100
-
- /*
- * The characters allowed in hostnames. This is used for validating hostnames given
- * to services, such as BotServ bot hostnames and user vhosts. Changing this is not
- * recommended unless you know for sure your IRCd supports whatever characters you are
- * wanting to use. Telling services to set a vHost containing characters your IRCd
- * disallows could potentially break the IRCd and/or Services.
- *
- * It is recommended you DON'T change this.
- */
- vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
-
- /*
- * If set to true, allows vHosts to not contain dots (.).
- * Newer IRCds generally do not have a problem with this, but the same warning as
- * vhost_chars applies.
- *
- * It is recommended you DON'T change this.
- */
- allow_undotted_vhosts = false
-
- /*
- * The characters that are not allowed to be at the very beginning or very ending
- * of a vHost. The same warning as vhost_chars applies.
- *
- * It is recommended you DON'T change this.
- */
- disallow_start_or_end = ".-"
-}
-
-/*
- * [REQUIRED] Services Options
- *
- * This section contains various options which determine how Services will operate.
- */
-options
-{
- /*
- * On Linux/UNIX systems Anope can setuid and setgid to this user and group
- * after starting up. This is useful if Anope has to bind to privileged ports
- */
- #user = "anope"
- #group = "anope"
-
- /*
- * The case mapping used by services. This must be set to a valid locale name
- * installed on your machine. Services use this case map to compare, with
- * case insensitivity, things such as nick names, channel names, etc.
- *
- * We provide two special casemaps shipped with Anope, ascii and rfc1459.
- *
- * This value should be set to what your IRCd uses, which is probably rfc1459,
- * however Anope has always used ascii for comparison, so the default is ascii.
- *
- * Changing this value once set is not recommended.
- */
- casemap = "ascii"
-
- /*
- * Sets the timeout period for reading from the uplink.
- */
- readtimeout = 5s
-
- /*
- * Sets the interval between sending warning messages for program errors via
- * WALLOPS/GLOBOPS.
- */
- warningtimeout = 4h
-
- /*
- * If set, Services will only show /stats o to IRC Operators. This directive
- * is optional.
- */
- #hidestatso = yes
-
- /*
- * A space-separated list of ulined servers on your network, it is assumed that
- * the servers in this list are allowed to set channel modes and Services will
- * not attempt to reverse their mode changes.
- *
- * WARNING: Do NOT put your normal IRC user servers in this directive.
- *
- * This directive is optional.
- */
- #ulineservers = "services.your.network"
-
- /*
- * How long to wait between connection retries with the uplink(s).
- */
- retrywait = 60s
-}
-
-/*
- * [RECOMMENDED] Logging Configuration
- *
- * This section is used for configuring what is logged and where it is logged to.
- * You may have multiple log blocks if you wish. Remember to properly secure any
- * channels you choose to have Anope log to!
- */
-log
-{
- /*
- * Target(s) to log to, which may be one of the following:
- * - a channel name
- * - a filename
- * - globops
- */
- target = "stats.log"
-
- /* Log to both services.log and the channel #services
- *
- * Note that some older IRCds, such as Ratbox, require services to be in the
- * log channel to be able to message it. To do this, configure service:channels to
- * join your logging channel.
- */
- #target = "stats.log #services"
-
- /*
- * The source(s) to only accept log messages from. Leave commented to allow all sources.
- * This can be a users name, a channel name, one of our clients (eg, OperServ), or a server name.
- */
- #source = ""
-
- /*
- * The bot used to log generic messages which have no predefined sender if there
- * is a channel in the target directive.
- */
- bot = "Global"
-
- /*
- * The number of days to keep logfiles, only useful if you are logging to a file.
- * Set to 0 to never delete old logfiles.
- *
- * Note that Anope must run 24 hours a day for this feature to work correctly.
- */
- logage = 7
-
- /*
- * What types of log messages should be logged by this block. There are nine general categories:
- *
- * servers - Server actions, linking, squitting, etc.
- * channels - Actions in channels such as joins, parts, kicks, etc.
- * users - User actions such as connecting, disconnecting, changing name, etc.
- * other - All other messages without a category.
- * rawio - Logs raw input and output from services
- * debug - Debug messages (log files can become VERY large from this).
- *
- * These options determine what messages from the categories should be logged. Wildcards are accepted, and
- * you can also negate values with a ~. For example, "~operserv/akill operserv/*" would log all operserv
- * messages except for operserv/akill. Note that processing stops at the first matching option, which
- * means "* ~operserv/*" would log everything because * matches everything.
- *
- * Valid server options are:
- * connect, quit, sync, squit
- *
- * Valid channel options are:
- * create, destroy, join, part, kick, leave, mode
- *
- * Valid user options are:
- * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper
- *
- * Rawio and debug are simple yes/no answers, there are no types for them.
- *
- * Note that modules may add their own values to these options.
- */
- servers = "*"
- #channels = "~mode *"
- users = "connect disconnect nick"
- other = "*"
- rawio = no
- debug = no
-}
-
-/*
- * [REQUIRED] MySQL Database configuration.
- *
- * m_mysql
- *
- * This module allows other modules to use MySQL.
- */
-module
-{
- name = "m_mysql"
-
- mysql
- {
- /* The name of this service. */
- name = "mysql/main"
- database = "anope"
- server = "127.0.0.1"
- username = "anope"
- password = "mypassword"
- port = 3306
- }
-}
-
-/*
- * IRC2SQL Gateway
- * This module collects data about users, channels and servers. It doesn't build stats
- * itself, however, it gives you the database, it's up to you how you use it.
- *
- * Requires a MySQL Database and MySQL version 5.5 or higher
- */
-include
-{
- type = "file"
- name = "irc2sql.example.conf"
-}
-
diff --git a/data/unreal.example.conf b/data/unreal.example.conf
new file mode 100644
index 000000000..692790730
--- /dev/null
+++ b/data/unreal.example.conf
@@ -0,0 +1,449 @@
+
+module
+{
+ name = "protocol/unreal"
+
+ /*
+ * Enforces mode locks server-side. This reduces the spam caused by
+ * services immediately reversing mode changes for locked modes.
+ */
+ use_server_side_mlock = yes
+}
+
+usermode
+{
+ name = "BOT"
+ character = "B"
+}
+
+usermode
+{
+ name = "CENSOR"
+ character = "G"
+}
+
+usermode
+{
+ name = "HIDEOPER"
+ character = "H"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "HIDEIDLE"
+ character = "I"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGPRIV"
+ character = "R"
+}
+
+usermode
+{
+ name = "PROTECTED"
+ character = "S"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "NOCTCP"
+ character = "T"
+}
+
+usermode
+{
+ name = "WEBTV"
+ character = "V"
+}
+
+usermode
+{
+ name = "WHOIS"
+ character = "W"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "DEAF"
+ character = "d"
+}
+
+usermode
+{
+ name = "GLOBOPS"
+ character = "g"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "HELPOP"
+ character = "h"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "INVIS"
+ character = "i"
+}
+
+usermode
+{
+ name = "OPER"
+ character = "o"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "PRIV"
+ character = "p"
+}
+
+usermode
+{
+ name = "GOD"
+ character = "q"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "REGISTERED"
+ character = "r"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "SNOMASK"
+ character = "s"
+ oper_only = yes
+}
+
+usermode
+{
+ name = "VHOST"
+ character = "t"
+ setable = no
+}
+
+usermode
+{
+ name = "WALLOPS"
+ character = "w"
+}
+
+usermode
+{
+ name = "CLOAK"
+ character = "x"
+}
+
+usermode
+{
+ name = "SSL"
+ character = "z"
+ setable = no
+}
+
+channelmode
+{
+ name = "VOICE"
+ character = "v"
+ status = "+"
+ level = 1
+}
+
+channelmode
+{
+ name = "HALFOP"
+ character = "h"
+ status = "%"
+ level = 2
+}
+
+channelmode
+{
+ name = "OP"
+ character = "@"
+ status = "@"
+ level = 3
+}
+
+channelmode
+{
+ name = "PROTECT"
+ character = "a"
+ status = "~"
+ level = 4
+}
+
+channelmode
+{
+ name = "OWNER"
+ character = "q"
+ status = "*"
+ level = 5
+}
+
+channelmode
+{
+ name = "BAN"
+ character = "b"
+ list = yes
+}
+
+channelmode
+{
+ name = "EXCEPT"
+ character = "e"
+ list = yes
+}
+
+channemode
+{
+ name = "INVITEOVERRIDE"
+ character = "I"
+ list = yes
+}
+
+channelmode
+{
+ name = "KEY"
+ character = "k"
+ param_regex = "[^:,]+"
+}
+
+channelmode
+{
+ name = "FLOOD"
+ character = "f"
+ param_regex = "\[(?:(?:(?<=\[)|,)\d+[ckmnt](?:#[CiKmNmMRb]\d*)?)+\]:\d+"
+}
+
+channelmode
+{
+ name = "REDIRECT"
+ character = "L"
+ param = yes
+}
+
+channelmode
+{
+ name = "LIMIT"
+ character = "l"
+ param_regex = "\d+"
+ param_unset = no
+}
+
+channelmode
+{
+ name = "DELAYEDJOIN"
+ character = "D"
+}
+
+channelmode
+{
+ name = "PRIVATE"
+ character = "p"
+}
+
+channelmode
+{
+ name = "SECRET"
+ character = "s"
+}
+
+channelmode
+{
+ name = "MODERATED"
+ character = "m"
+}
+
+channelmode
+{
+ name = "NOEXTERNAL"
+ character = "n"
+}
+
+channelmode
+{
+ name = "TOPIC"
+ character = "t"
+}
+
+channelmode
+{
+ name = "INVITE"
+ character = "i"
+}
+
+channelmode
+{
+ name = "REGISTERED"
+ character = "r"
+ setable = no
+}
+
+channelmode
+{
+ name = "REGISTEREDONLY"
+ character = "R"
+}
+
+channelmode
+{
+ name = "BLOCKCOLOR"
+ character = "c"
+}
+
+channelmode
+{
+ name = "OPERONLY"
+ character = "O"
+ oper_only = yes
+}
+
+channelmode
+{
+ name = "PERM"
+ character = "P"
+}
+
+channelmode
+{
+ name = "NOKICK"
+ character = "Q"
+}
+
+channelmode
+{
+ name = "NOKNOCK"
+ character = "K"
+}
+
+channelmode
+{
+ name = "NOINVITE"
+ character = "V"
+}
+
+channelmode
+{
+ name = "NOCTCP"
+ character = "C"
+}
+
+channelmode
+{
+ name = "SSL"
+ character = "z"
+}
+
+channelmode
+{
+ name = "NONICK"
+ character = "N"
+}
+
+channelmode
+{
+ name = "STRIPCOLOR"
+ character = "S"
+}
+
+channelmode
+{
+ name = "REGMODERATED"
+ character = "M"
+}
+
+channelmode
+{
+ name = "NONOTICE"
+ character = "T"
+}
+
+channelmode
+{
+ name = "CENSOR"
+ character = "G"
+}
+
+channelmode
+{
+ name = "SSL2"
+ character = "Z"
+ setable = no
+}
+
+extban
+{
+ name = "CHANNELBAN"
+ type = "channel"
+ character = "c"
+}
+
+extban
+{
+ name = "JOINBAN"
+ type = "entry"
+ character = "j"
+}
+
+extban
+{
+ name = "NONICKBAN"
+ type = "entry"
+ base = "BAN"
+ character = "n"
+}
+
+extban
+{
+ name = "QUIET"
+ type = "entry"
+ base = "BAN"
+ character = "q"
+}
+
+extban
+{
+ name = "REALNAMEBAN"
+ type = "realname"
+ base = "BAN"
+ character = "r"
+}
+
+extban
+{
+ name = "REGISTEREDBAN"
+ type = "registered"
+ base = "BAN"
+ character = "R"
+}
+
+extban
+{
+ name = "ACCOUNTBAN"
+ type = "account"
+ base = "BAN"
+ character = "a"
+}
+
+extban
+{
+ name = "SSLBAN"
+ type = "fingerprint"
+ base = "BAN"
+ character = "S"
+}
+
diff --git a/docs/ASTYLE b/docs/ASTYLE
deleted file mode 100644
index be8cf2325..000000000
--- a/docs/ASTYLE
+++ /dev/null
@@ -1 +0,0 @@
-astyle --style=java --indent=tab --brackets=break-closing --indent-switches --indent-cases --brackets=break
diff --git a/docs/C++CASTING b/docs/C++CASTING
deleted file mode 100644
index e1beb8f06..000000000
--- a/docs/C++CASTING
+++ /dev/null
@@ -1,111 +0,0 @@
-C++-style Casting
-=================
-
-In C, you can cast in one of two ways:
-
-(type)var
-type(var)
-
-The problem with C-style casting is that it allows a programmer to get away
-with too much, and is also not designed to handle C++ classes.
-
-C++ has 4 types of casting in addition to allowing C-style casting. They are:
-
-static_cast
-const_cast
-dynamic_cast
-reinterpret_cast
-
-The syntax is usually *_cast<type>(var).
-
-static_cast
------------
-
-From my experience, this cast is closest to C-style casting for non-pointer
-types as well as between some (but not all) pointer types. This type of cast,
-like C-style casting, is performed at compile-time. static_cast can also do
-a downcast of a derived class to a base class, but only if the base class is
-not a virtual base class. Sometimes the result of this cast can become
-undefined. static_cast is a bit more strict that C-style casting, though. It
-disallows certain class conversions that would've been allowed with a C-style
-cast. static_cast also doesn't allow you to cast to an incomplete type. In
-these cases, I would try either dynamic_cast or reinterpret_cast.
-
-const_cast
-----------
-
-This cast is mainly to add or remove const-ness or volatile-ness from a
-variable. This is safer than using a C-style cast to change the const-ness
-of a variable. In most cases if you try to use one of the other casts and it
-complains about const-ness, you will want to either use this cast instead or
-wrap the other cast around this cast. An example:
-
-const int *a;
-static_cast<void *>(a); <-- This will fail.
-
-To remedy the above, you would might try this:
-
-const int *a;
-const_cast<void *>(a); <-- But this will still fail.
-
-The real solution is this:
-
-const int *a;
-static_cast<void *>(const_cast<int *>(a));
-
-It is not recommended to use const_cast on the this variable within a member
-function of a class that is declared const. Instead you should use the mutable
-keyword on the variable in the class's definition.
-
-dynamic_cast
-------------
-
-This cast can only be used on pointers or references to classes. It can cast a
-derived class to a base class, a derived class to another derived class
-(provided that both are children of the same base class), or a base class to a
-derived class. You can also use this to cast a class to void *. This cast is
-done at run-time as opposed to the other casts, and relies on C++'s RTTI to be
-enabled. It is meant to be used on polymorphic classes, so use static_cast on
-non-polymorphic classes.
-
-derived-to-base conversions are actually done statically, so you use either
-dynamic_cast or static_cast on them, regardless of if the classes are
-polymorphic or not.
-
-derived-to-derived or base-to-derived conversions, however, rely on run-time
-type information, and this cast is used on those classes that are polymorphic.
-This is safer than C-style casting in that an invalid pointer conversion will
-return a NULL pointer, and an invalid reference conversion will throw a
-Bad_cast exception.
-
-Note that in Anope we prefer if Anope::debug_cast is used.
-This uses dynamic_cast (and checks for a NULL pointer return) on debug builds
-and static_cast on release builds, to speed up the program because of dynamic_cast's
-reliance on RTTI.
-
-reinterpret_cast
-----------------
-
-This cast I would use only as a last resort if static_cast isn't allowed on a
-conversion. It allows for conversions between two unrelated types, such as
-going from char * to int *. It can also be used to convert a pointer to an
-integral type and vica versa. The sites I've read mention how the result is
-non-portable, which I assume means the resulting object code is non-portable,
-so since the code is compiled on many systems anyways, I don't see this as
-being a huge issue. It is recommended to only use this if necessary, though.
-
-Links
-=====
-
-The following links are web sites I've used to get this information, and might
-describe some of the above a bit better than I have. :P
-
-http://www.acm.org/crossroads/xrds3-1/ovp3-1.html
-http://www.cplusplus.com/doc/tutorial/typecasting.html
-http://www.codeguru.com/forum/showthread.php?t=312456
-http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/cast.html
-http://msdn.microsoft.com/en-us/library/5f6c9f8h(VS.80).aspx
-http://en.wikibooks.org/wiki/C%2B%2B_Programming/Type_Casting
-http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=134
-
--- CyberBotX, Nov 23, 2008
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 082b1da0e..fd93e81c0 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -6,10 +6,10 @@ if(WIN32)
if(IN_SOURCE)
# Add README.txt to list of files for CPack to ignore
add_to_cpack_ignored_files("README.txt$" TRUE)
- endif(IN_SOURCE)
+ endif()
set(DOCS Changes Changes.conf DEFCON FAQ INSTALL LANGUAGE MODULES NEWS ${CMAKE_CURRENT_BINARY_DIR}/README.txt WIN32.txt)
install(FILES ${DOCS}
DESTINATION ${DOC_DIR}
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/README.txt")
-endif(WIN32)
+endif()
diff --git a/docs/CODING b/docs/CODING
deleted file mode 100644
index 7dbd5afb3..000000000
--- a/docs/CODING
+++ /dev/null
@@ -1,239 +0,0 @@
-Originally pulled from: http://www.inspircd.org/wiki/Coding_Guidelines
-
----
-
-InspIRCd Coding Guidelines
-
-The following are a set of guidelines for writing patches to InspIRCd, or for
-creating modules for distribution with the official package. These guidelines
-were written a time after InspIRCd development started, and so not all code
-yet follows these. This will be rectified with time.
-
-
-1. Comments
-
- * Multi Line
- Multiple line comments should follow the C-style comment, for example:
- /*
- * This is a multiple line comment, huzzah..
- */
-
- * Single Line
- Single line comments should also be in the C style, for example:
- /* This is a boring one-line comment */
-
- * Doxygen commenting
- If you wish your comment to show in doxygen, the comment should be directly
- above the item you are documenting (a class, function, enum, etc) and the
- first line should be "/**". For example:
- /** This is a doxygen multiline comment.
- * Description of thingymebob here.
- */
-
- The first line after the "**" is used as the short description of the item
- (up to the full stop) and everything afterwards as the detailed description.
-
-
-2. Indentation
-
- Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation,
- for example:
- int main()
- {
- <tab>if (condition)
- <tab>{
- <tab><tab>code
- <tab>}
- }
-
-
-3. Separation
-
- Always put a space in between a keyword like if/while and the condition,
- for example:
- if (foo == bar)
- NOT
- if(foo == bar)
-
-
-4. Braces
-
- Always put braces opening and closing blocks on separate lines, see the
- identation example. For example, place braces like this:
- if (apples == "green")
- {
- cout << "Apples are green" << endl;
- }
-
- and not:
- if (apples == "green") {
- cout << "Apples are green" << endl;
- }
-
- The one exception to this is if you are declaring a class method which is
- only one line long, in that case the following is acceptable in most cases:
- class foo : public bar
- {
- foo() { }
- getrandomfoo() { return rand(); }
- };
-
-
-5. Templates
-
- Where possible, use templates rather than #defines. Avoid use of RTTI.
-
-
-6. Structs
-
- Structs should be declared in the following fashion:
- struct BodyPartBasket
- {
- int arms;
- int legs;
- int scrotalsacs;
- };
- and not like this:
- typedef struct
- {
- int arms;
- int legs;
- int scrotalsacs;
- } BodyPartBasket;
-
- The second way is not required in C++ to be able to do this:
- BodyPartBasket mybasket;
-
- Plus, placing the name at the bottom of the declaration makes readability
- more difficult (as you have to scroll down to the bottom of the struct to
- find its name). (where possible, call them classes rather than structs.)
-
-
-7. Variable naming
-
- Class and struct names should be in camel case with a leading capital letter,
- for example "MyBagOfBones" and not "my_bag_of_bones" or "mybagofbones".
- Variable names can be in either camel case with a leading capital letter or
- alternatively all lower case, so long as the same naming convention is
- adhered to throughout the class. No classes or variables should be named in
- capitals unless this makes sense for the name (for example "class DNS").
- Constants and enum values should always be completely in CAPITALS and
- underscores may be used, for example:
- enum DecayState
- {
- DECAYED_MOULDY = 0,
- DECAYED_SMELLY = 1,
- DECAYED_MAGGOTS = 2
- };
- All value names in an enum should be started with the same text which should
- be related in some way to the enum's use. For example "DNS_CNAME, DNS_A,
- DNS_AAAA".
-
-
-8. Use of references
-
- Wherever possible, when dealing with any complex class, pass a const reference
- rather than a copy of the class. For example:
- MyThingy::MyThingy(const std::string &thingyvalue)
- {
- }
- Of course, if you intended to change the string you can just omit the 'const'.
-
-
-9. Use of char pointers
-
- Whenever you use char pointers (char*, char**) try to use const equivalents.
- This is much safer and avoids ugly and dangerous casts. For example:
- MyThingy::Thingify(const char* const* wotsits)
- {
- }
- If it is possible without performance loss, consider avoiding char pointers
- altogether and using std::string instead.
-
-
-10. Use of STL
-
- For more information on use of STL in InspIRCd, please see the separate
- STL FAQ.
-
-
-11. Making copies of data
-
- Never ever make a copy of a piece of data unless it is absolutely necessary.
- For example, don't use strlcpy() to make a copy of the const char* string
- returned by std::string::c_str(), if the change can be done to the std::string
- itself. The same goes for unnecessary variable assignments, especially those
- which assign large classes.
-
-
-12. namespace std
-
- Avoid the following:
- using namespace std;
- It might take a bit more typing, but things work better if you don't set
- (then later assume) the namespace -- specify it explicitly when you want to
- use it.
-
-
-13. Linefeeds
-
- Unix linefeeds only please. We do not like to see our screens covered in ^M.
-
-
-14. Portability
-
- Always make sure your code is portable to all supported operating systems,
- remember of course that as of 1.1.8 this includes windows. Don't write code
- that only works on windows, or only works on Linux. Test your code on all
- platforms or ask for help from other developers who have the platforms you
- want to test on.
-
- * new() and delete(), malloc() and free()
- Apart from the fact that using malloc() and free() is bad practice in C++
- code, you must never use malloc() or free() in InspIRCd, within its modules
- or within the core. This is because if you use malloc() or free() in windows,
- the memory is claimed from the program's local heap.
- In windows, each shared object (module, dll) has its own heap, which is
- protected from other dlls and executables. To get around this issue and
- allow more posix-like memory access from other dlls in the program (other
- modules), InspIRCd overrides the operators new and delete to ensure that
- memory allocated by them comes from the windows global heap. If you use
- malloc() and free() for this, the ircd will segfault when another module
- tries to access the memory you have allocated!
-
- * strdup()
- As with malloc(), above, strdup() should be avoided. Where strdup() is
- absolutely necessary, use strnewdup() which is our strdup() implementation
- that calls operator new instead of using malloc().
- char arrays allocated by strnewdup() should be deleted with operator delete[].
-
- * CoreExport and DllImport
- Prefix all types you want to import or export to other modules with CoreExport
- and DllImport macros. These do nothing in POSIX operating systems, however
- in windows these are expanded to the instructions __declspec(dllimport) and
- __declspec(dllexport) respectively depending on where they are used and how.
-
-
-15. External Dependencies
-
- If a module is compiled as standard, or the code is part of the core, you must
- not use any dependencies that are not available as standard on all supported
- operating systems beyond libstdc++, libc, and whatever else is currently
- required to build the core. Modules which use nonstandard dependencies belong
- in the modules/extra directory.
-
-
-16. Profiling and Performance
-
- It is one thing to assume that code performs bad, it is another thing to prove
- that it actually is. A lot of experienced programmers talk about 'premature
- optimisation', and here is what it means: if you have a piece of code called
- once on startup that takes 10 seconds instead of one second to run, and a
- piece of code that takes 0.05 seconds to run when it should take 0.01, and
- it is called once per second, the second piece of code is the priority.
-
- In other words, make sure that what you think is slow, and a performance
- problem in Insp actually is.
- To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind
- bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the output
- files.
diff --git a/docs/Changes.conf b/docs/Changes.conf
index 49bf6b783..6cb3341e5 100644
--- a/docs/Changes.conf
+++ b/docs/Changes.conf
@@ -1,7 +1,4 @@
-Anope Version 2.0.4-git
--------------------
-
-Anope Version 2.0.3
+Anope Version 2.0.3-git
-------------------
Add operserv/chankill to default globops log
Add ns_identify:maxlogins to limit the max number of concurrent logins per account
diff --git a/docs/EVENTS b/docs/EVENTS
deleted file mode 100644
index ba34f0571..000000000
--- a/docs/EVENTS
+++ /dev/null
@@ -1,35 +0,0 @@
-Anope Internal Events
----------------------
-
-1) Intro
-2) Using Events
-
-1) Introduction to Internal Events
-
- Internal Events are setup to give module developers more information
- about what the core is doing at different times. This information can
- be as complex as data we are feeding to the uplink, to simple triggered
- events such as the databases being saved.
-
- Additionally there is a module included with the core
- which can provide some clue as to how to use the code in your modules.
- The rest of this document assumes that you are used to writing modules.
-
-2) Using Events
-
- Each Event in Anope calls a function.
- You must override these functions in your main modules class.
- The full list of functions and parameters are in modules.h. In this
- case, you would be overriding OnJoinChannel() and OnPartChannel() like so:
-
- void OnJoinChannel(User *u, Channel *c) anope_override { }
- void OnPartChannel(User *u, Channel *c) anope_override { }
-
- Some of these event overrides can be used to prevent or allow things to
- happen that would normally not be allowed or denied. You can also use
- ModuleManager (not explained here) to set control which order the modules
- are queried (when multiple modules hook to the same event).
-
- The "anope_override" identifier is for compatibility with C++11.
- Its usage is highly recommended.
-
diff --git a/docs/FAQ b/docs/FAQ
deleted file mode 100644
index 63a0d1d97..000000000
--- a/docs/FAQ
+++ /dev/null
@@ -1,10 +0,0 @@
-Frequently Asked Questions (FAQ) concerning Anope
-------------------------------------------------
-
-The information in the 1.9 FAQ is subject to change at any
-moment due to new developments. Please visit our website
-for the most up to date information.
-
-An updated version of the FAQ can be found here:
-
-http://wiki.anope.org/index.php/FAQ
diff --git a/docs/INSTALL b/docs/INSTALL
index 0a923ef97..071483b08 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -52,8 +52,8 @@ Note: You should also read the README and FAQ files!
cause trouble on your network if passwords are not encrypted, or read
the memos of any user.
- Now go into the conf directory (by default, ~/services/conf). Copy the example
- configuration file (example.conf) to services.conf, and open the latter
+ Now go into the conf directory (by default, ~/anope/conf). Copy the example
+ configuration file (anope.example.conf) to anope.conf, and open the latter
with your favorite text editor. It contains all the configuration
directives Anope will use at startup. Read the instructions contained in
the file carefully. Using the default values is NOT a good idea, and will
@@ -71,7 +71,7 @@ Note: You should also read the README and FAQ files!
* IMPORTANT: Back up your old databases!
* If you are upgrading to a new major release, ALWAYS restart a
- fresh configuration file from example.conf.
+ fresh configuration file from anope.example.conf.
3) Setting up the IRCd
@@ -83,7 +83,7 @@ Note: You should also read the README and FAQ files!
a shared block), and be sure that the IRCd is listneing on the given port
in the link block.
- Example link configurations can be found in example.conf for some of the
+ Example link configurations can be found in anope.example.conf for some of the
popular IRCds.
Don't forget to /rehash your IRCd to apply changes.
@@ -95,7 +95,7 @@ Note: You should also read the README and FAQ files!
4) Starting Anope
Go into the directory where binaries were installed (by default, this is
- ~/services/bin). Type ./services to launch Anope.
+ ~/anope/bin). Type ./anope to launch Anope.
If there are syntax errors in the configuration file they will be
displayed on the screen. Correct them until there are no errors anymore.
@@ -104,7 +104,7 @@ Note: You should also read the README and FAQ files!
Give Services at least one minute to link to your network, as certain
IRCds on some OSes may be really slow for the link process. If nothing
happens after about a minute, it is probably a configuration problem. Try
- to launch Anope with ./services -debug -nofork to see any errors that it
+ to launch Anope with ./anope -debug -nofork to see any errors that it
encounters, and try to correct them.
If you need help to solve errors, feel free to subscribe to the Anope
@@ -116,7 +116,7 @@ Note: You should also read the README and FAQ files!
still running, and restart it if not.
First rename the example.chk script that is in Anope path (by default,
- this is ~/services/conf) to services.chk and edit it. You'll need to
+ this is ~/anope/conf) to services.chk and edit it. You'll need to
modify the CONFIGURATION part of the file. Then ensure that the file is
marked as executable by typing chmod +x services.chk, and try to launch the
script to see if it works (Anope must not be running when you do this ;))
@@ -125,7 +125,7 @@ Note: You should also read the README and FAQ files!
This will open the default text editor with the crontab file. Enter the
following (with correct path):
- */5 * * * * /home/ircd/services/conf/services.chk >/dev/null 2>&1
+ */5 * * * * /home/ircd/anope/conf/services.chk >/dev/null 2>&1
The */5 at the beginning means "check every 5 minutes". You may replace
the 5 with other another number if you want (but less than 60). Consult
diff --git a/docs/INSTALL.fr b/docs/INSTALL.fr
index f7af3aac8..4cb453d35 100644
--- a/docs/INSTALL.fr
+++ b/docs/INSTALL.fr
@@ -55,9 +55,9 @@ Note : Vous devrez également lire les fichiers README et FAQ !
mots de passe ne sont pas chiffrés, ou lire les mémos de tous les
utilisateurs.
- Allez maintenant dans le répertoire conf (par défaut, ~/services/conf).
- Copiez l'exemple de fichier de configuration (example.conf) en
- services.conf et ouvrez ce dernier avec votre éditeur de texte favori.
+ Allez maintenant dans le répertoire conf (par défaut, ~/anope/conf).
+ Copiez l'exemple de fichier de configuration (anope.example.conf) en
+ anope.conf et ouvrez ce dernier avec votre éditeur de texte favori.
Il contient toutes les directives de configuration qu'Anope va utiliser
en démarrant. Lisez attentivement les instructions contenues dans le
fichier. L'utilisation des valeurs par défaut n'est pas toujours
@@ -78,7 +78,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
* IMPORTANT : Sauvegardez vos anciennes bases de données !
* Si vous mettez à jour vers une nouvelle version majeure,
recommencez *toujours* toute votre configuration à partir du
- fichier example.conf.
+ fichier anope.example.conf.
3) Configuration de l'IRCd
@@ -92,7 +92,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
sur le port donné dans le bloc link.
Des exemples de configurations de bloc link peuvent être trouvés dans
- le fichier example.conf pour certains des IRCd les plus populaires.
+ le fichier anope.example.conf pour certains des IRCd les plus populaires.
Souvenez-vous de /rehash votre IRCd pour appliquer les changements.
@@ -104,7 +104,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
4) Mettre en route Anope
Allez dans le répertoire où les fichiers binaires ont été installés
- (par défaut, ~/services/bin). Tapez ./services pour lancer Anope.
+ (par défaut, ~/anope/bin). Tapez ./anope pour lancer Anope.
S'il y a des erreurs de syntaxe dans le fichier de configuration, elles
seront affichées à l'écran. Corrigez-les jusqu'à ce qu'il n'y en ait
@@ -114,7 +114,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
réseau, car certains IRCds sur certains systèmes peuvent être très
lents pour le processus de liaison. Si rien ne se passe après environ
une minute, il y a probablement un problème de configuration. Essayez
- de lancer Anope en mode debug avec ./services -debug -nofork pour voir
+ de lancer Anope en mode debug avec ./anope -debug -nofork pour voir
toutes les erreurs rencontrées et essayez de les corriger.
Si vous avez besoin d'aide pour résoudre des erreurs, n'hésitez pas à
@@ -127,7 +127,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
est toujours en cours d'exécution et de le redémarrer s'il n'est pas.
D'abord renommez le script example.chk qui est dans les dossiers
- d'Anope (par défaut, ~/services/conf) en services.chk et modifiez-le.
+ d'Anope (par défaut, ~/anope/conf) en services.chk et modifiez-le.
Vous aurez besoin de modifier la partie CONFIGURATION du fichier.
Assurez-vous ensuite que le fichier est marqué comme exécutable en
tapant chmod +x services.chk et essayez de lancer le script pour voir
@@ -138,7 +138,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
crontab -e. Cela va ouvrir l'éditeur de texte par défaut avec le
fichier crontab. Entrez la ligne suivante (avec le chemin correct) :
- */5 * * * * /home/ircd/services/conf/services.chk > /dev/null 2>&1
+ */5 * * * * /home/ircd/anope/conf/services.chk > /dev/null 2>&1
Le */5 au début signifie "vérifier toutes les 5 minutes". Vous pouvez
remplacer le 5 par un autre numéro si vous voulez (mais moins de 60).
diff --git a/docs/LANGUAGE b/docs/LANGUAGE
index 33fa240fd..24c47124f 100644
--- a/docs/LANGUAGE
+++ b/docs/LANGUAGE
@@ -25,7 +25,7 @@ Anope Mutli Language Support
Anope uses gettext (http://www.gnu.org/software/gettext/) to translate messages for users. To add a new language
install gettext and run `msginit -l language -o anope.language.po -i anope.pot`. For example if I was translating to
Spanish I could run `msginit -l es_ES -o anope.es_ES.po -i anope.pot`. Open the newly generating .po file and start
- translating. Once you are done simply rerun ./Config; make && make install and add the language to your services.conf.
+ translating. Once you are done simply rerun ./Config; make && make install and add the language to your anope.conf.
Note that on Windows it is not quite this simple, windows.cpp must be edited and Anope recompiled and restarted.
Poedit (http://www.poedit.net/) is a popular po file editor, and we recommend using it or another editor designed to edit
diff --git a/docs/MODULES b/docs/MODULES
index 1699d2c52..e73412627 100644
--- a/docs/MODULES
+++ b/docs/MODULES
@@ -22,7 +22,7 @@ Anope Modules
1. If modules are supported by your system, they will be configured
automatically when you run ./Config. The modules will be installed
to the modules directory in your data path (by default this will
- be ~/services/data/modules).
+ be ~/anope/data/modules).
2. Compile Anope as usual using ./Config. The "make" process will now
compile module support into Anope, and compile the default sample
@@ -89,7 +89,7 @@ Anope Modules
You can download more useful modules from http://modules.anope.org/. Just
grab the module file (usually with a .cpp extension). Place the module
- file in your modules (anope-1.9.x/modules/third) folder; although any of
+ file in your modules (anope-x.x.x/modules/third) folder; although any of
the other folders within the modules directory will work.
The new modules need to be compiled and installed before you can make
@@ -98,7 +98,7 @@ Anope Modules
1. Make sure you're in the main source directory. (usually anope-1.X.XX/)
2. Run ./Config to find and configure modules, then `cd build`.
3. Run `make` to compile Anope, and any modules.
- 4. Run `make install` to copy the compiled binaries to the ~/services/
+ 4. Run `make install` to copy the compiled binaries to the ~/anope/
directory.
You can now use /msg OperServ MODLOAD to load the new modules.
diff --git a/docs/NEWS b/docs/NEWS
deleted file mode 100644
index 1010816cf..000000000
--- a/docs/NEWS
+++ /dev/null
@@ -1,7 +0,0 @@
-Highlighted News in Anope 1.9
-=============================
-
-* Added in live updating SQL and the ability to execute commands through SQL
-* Re-designed configuration file
-* Code refresh / rewrite into C++
-
diff --git a/docs/README b/docs/README
index a68647d1a..a9cb6ce98 100644
--- a/docs/README
+++ b/docs/README
@@ -9,8 +9,6 @@ This program is free but copyrighted software; see the file COPYING for
details.
Information about Anope may be found at http://www.anope.org/
-Information about Epona may be found at http://www.epona.org/
-Information about Services may be found at http://www.ircservices.esper.net/
Table of Contents
-----------------
@@ -171,11 +169,11 @@ Table of Contents
* Bahamut 1.4.27 or later (including 1.8)
* Charybdis 3.4 or later
* Hybrid 8.1 or later
- * InspIRCd 1.2 or 2.0
+ * InspIRCd 2.0
* ngIRCd 19.2 or later
* Plexus 3 or later
* Ratbox 2.0.6 or later
- * UnrealIRCd 3.2 or 4
+ * UnrealIRCd 4 or later
Anope could also work with some of the daemons derived by the ones listed
above, but there's no support for them if they work or don't work.
diff --git a/docs/REDIS b/docs/REDIS
deleted file mode 100644
index 54358d16f..000000000
--- a/docs/REDIS
+++ /dev/null
@@ -1,160 +0,0 @@
-Starting in Anope 1.9.9, Anope has Redis database support (http://redis.io/).
-This document explains the data structure used by Anope, and explains how
-keyspace notification works.
-
-This is not a tutorial on how to use Redis, see http://redis.io/documentation
-for that.
-
-Table of Contents
------------------
-1) Data structure
-2) Keyspace notifications
-3) Examples of modifying, deleting, and creating objects
-
-1) Data structure
-
- There are 4 key namespaces in Anope, they are:
-
- id - The keys in id are used to atomically create object ids for new
- objects. For example, if I were to create a new BotInfo I would first:
-
- redis 127.0.0.1:6379> INCR id:BotInfo
-
- To get the object ID of the new object.
-
- ids - The keys in ids contain a set of all object ids of the given type.
- For example:
-
- redis 127.0.0.1:6379> SMEMBERS ids:BotInfo
-
- Returns "1", "2", "3", "4", "5", "6", "7", "8" because I have 8 bots that
- have IDs 1, 2, 3, 4, 5, 6, 7, and 8, respectively.
-
- hash - The keys in hash are the actual objects, stored as hashes. For
- example, if I had just looked up all BotInfo ids and wanted to iterate
- over all of them, I woulld start by:
-
- redis 127.0.0.1:6379> HGETALL hash:BotInfo:1
-
- Which gets all keys and values from the hash of type BotInfo with id 1.
- This may return:
-
- "nick" -> "BotServ"
- "user" -> "services"
- "host" -> "services.anope.org"
- "created" -> "1368704765"
-
- value - The keys in value only exist to aid looking up object IDs. They
- are sets of object IDs and are used to map key+value pairs to objects.
- For example:
-
- redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nick:Adam
-
- Returns a set of object ids of NickAlias objects that have the key
- 'nick' set to the value 'Adam' in its hash. Clearly this can only
- ever contain at most one object, since it is not possible to have
- more than one registered nick with the same name, but other keys
- will contain more than one, such as:
-
- redis 127.0.0.1:6379> SMEMBERS value:NickCore:email:adam@anope.org
-
- Which would return all accounts with the email "adam@anope.org".
-
- redis 127.0.0.1:6379> SMEMBERS value:ChanAccess:mask:Adam
-
- Which would return all access entries set on the account "Adam".
-
- Behavior similar to SQL's AND, can be achieved using the
- SINTER command, which does set intersection on one or more sets.
-
-2) Keyspace notifications
-
- Redis 2.7 (unstable) and 2.8 (stable) and newer support keyspace notifications
- (http://redis.io/topics/notifications). This allows Redis to notify Anope of
- any external changes to objects in the database. Once notified, Anope will
- immediately update the object. Otherwise, Anope keeps all objects in memory
- and will not regularly read from the databaes once started.
-
- You can use this to modify objects in Redis and have them immediately reflected
- back into Anope. Additionally you can use this feature to run multiple Anope
- instances simultaneously from the same database (see also, Redis database
- replication).
-
- To use keyspace notifications you MUST execute
-
- redis 127.0.0.1:6379> CONFIG SET notify-keyspace-events KA
- OK
-
- or set notify-keyspace-events in redis.conf properly. Anope always executes
- CONFIG SET when it first connects.
-
- If you do not enable keyspace events properly Anope will be UNABLE to see any
- object modifications you do.
-
- The key space ids and value are managed entirely by Anope, you do
- not (and should not) modify them. Once you modify the object (hash), Anope will
- update them for you to correctly refelect any changes made to the object.
-
- Finally, always use atomic operations. If you are inserting a new object with
- multiple commands, or inserting multiple objects at once, specifically if the
- objects depend on each other, you MUST use a transaction.
-
-3) Examples of modifying, deleting, and creating objects
-
- These examples will ONLY work if you meet the criteria in section 2.
-
- If I want to change the email account 'Adam' to 'Adam@anope.org', I would execute the following:
-
- redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
-
- Which returns a value of "1", which is the object id I want to modify.
- Now to change the email:
-
- redis 127.0.0.1:6379> HSET hash:NickCore:1 email Adam@anope.org
-
- You can now see this in NickServ's INFO command:
- -NickServ- Email address: Adam@anope.org
-
- If I want to drop the account "Adam", I would execute the following:
-
- redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
-
- Which returns a value of "1". I would then check:
-
- redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nc:Adam
-
- To see what nicknames depend on this account to exist, as I will
- have to remove those too. This returns the values "2", and "3".
-
- Finally, I can drop the nick using a transaction via:
-
- redis 127.0.0.1:6379> MULTI
- OK
- redis 127.0.0.1:6379> DEL hash:NickAlias:2
- QUEUED
- redis 127.0.0.1:6379> DEL hash:NickAlias:3
- QUEUED
- redis 127.0.0.1:6379> DEL hash:NickCore:1
- QUEUED
- redis 127.0.0.1:6379> EXEC
-
- Or alternatively simply:
-
- redis 127.0.0.1:6379> DEL hash:NickAlias:2 hash:NickAlias:3 hash:NickCore:1
-
- If I wanted to create a BotServ bot, I would execute the following:
-
- redis 127.0.0.1:6379> INCR id:BotInfo
-
- Which returns a new object ID for me, in this example it will be "8".
- Now I can create the object:
-
- HMSET hash:BotInfo:8 nick redis user redis host services.anope.org realname "Services for IRC Networks"
-
- Note if you are using HSET instead of HMSET you will need to use a transaction, as shown in the above example.
- If you are watching your services logs you will immediately see:
-
- USERS: redis!redis@services.anope.org (Services for IRC Networks) connected to the network (services.anope.org)
-
- And the bot redis will be in BotServ's bot list.
- Notice how ids:BotInfo and the value keys are updated automatically.
diff --git a/docs/TOOLS b/docs/TOOLS
index c8e92fc70..b1132c505 100644
--- a/docs/TOOLS
+++ b/docs/TOOLS
@@ -1,26 +1,4 @@
Anope Bundled Tools
-------------------
-1) Anope SMTP Client
-
- Provided with Anope is a simple SMTP client which can be used instead of
- programs like SendMail in some cases.
-
- The SMTP client can be used instead of sendmail for use with Anope's mail
- options. To use the SMTP client instead of sendmail, find the line in your
- services configuration file (services.conf) that defines sendmailpath. On
- that line, change the path to your services installation directory, then
- followed by "bin/anopesmtp" and the IP address of a valid SMTP server. It
- should look like this:
-
- sendmailpath = "/home/anope/services/bin/anopesmtp 127.0.0.1"
-
- If the SMTP client doesn't send mail, or if there's an other problem with
- it, you can enable debug mode by passing the --debug flag after the server
- address. This should generate a log file of what happened when it tried
- to connect to the SMTP server.
-
- Credits:
- Originally written by Dominick Meglio <codemastr@unrealircd.com>
- Ported to *nix by Trystan Scott Lee <trystan@nomadirc.net>
-
+XXX anoperc?
diff --git a/docs/WIN32.txt b/docs/WIN32.txt
index 071831995..9c3ce91f7 100644
--- a/docs/WIN32.txt
+++ b/docs/WIN32.txt
@@ -103,7 +103,7 @@ Anope for Windows
INSTALL within the Solution Explorer. Right-click on INSTALL and choose Build.
When you have done this, all the files will be installed to where they belong.
- The only thing you need to do is rename "data/example.conf" to be "data/services.conf",
+ The only thing you need to do is rename "data/anope.example.conf" to be "data/anope.conf",
and then follow the steps to set up Anope.
You have now completed the building phase of Anope for Windows. You can
@@ -120,7 +120,7 @@ Anope for Windows
Notepad will cause strange characters to appear, and you may not be able to
edit the file correctly.
- Open services.conf, and read through it carefully and adjust the settings
+ Open anope.conf, and read through it carefully and adjust the settings
you think you need to adjust.
If you are unsure of the settings, you can go to the dos command prompt
diff --git a/docs/XMLRPC/xmlrpc.php b/docs/XMLRPC/xmlrpc.php
index e57a2f145..ba1290b03 100644
--- a/docs/XMLRPC/xmlrpc.php
+++ b/docs/XMLRPC/xmlrpc.php
@@ -3,7 +3,7 @@
/**
* XMLRPC Functions
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2015 Anope Team
* Contact us at team@anope.org
*/
class AnopeXMLRPC
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 1a96d7111..f4ed6a0a4 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -16,49 +16,7 @@ add_to_cpack_ignored_files("${version_BINARY}$" TRUE)
if(NOT WIN32)
add_to_cpack_ignored_files("version.h$" TRUE)
add_to_cpack_ignored_files("build.h$" TRUE)
-endif(NOT WIN32)
-
-set(PCH_SOURCES_GCH "")
-if(USE_PCH AND CMAKE_COMPILER_IS_GNUCXX)
- string(REPLACE " " ";" PCH_CXXFLAGS "${CXXFLAGS} ${CMAKE_CXX_FLAGS}")
-
- file(GLOB PCH_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
- sort_list(PCH_SOURCES)
-
- foreach(PCH_SOURCE ${PCH_SOURCES})
- find_includes(${PCH_SOURCE} INCLUDES)
- set(INCLUDES_LIST)
- append_to_list(INCLUDES_LIST ${PCH_SOURCE})
- foreach(INCLUDE ${INCLUDES})
- # Extract the filename from the #include line
- extract_include_filename(${INCLUDE} FILENAME QUOTE_TYPE)
- if(QUOTE_TYPE STREQUAL "quotes")
- find_in_list(PCH_SOURCES "${FILENAME}" FOUND)
- if(NOT FOUND EQUAL -1)
- append_to_list(INCLUDES_LIST ${FILENAME})
- endif(NOT FOUND EQUAL -1)
- endif(QUOTE_TYPE STREQUAL "quotes")
- endforeach(INCLUDE)
-
- set(PCH_EXTRAFLAGS "")
- if(DEBUG_BUILD)
- set(PCH_EXTRAFLAGS "-g")
- endif(DEBUG_BUILD)
- if(PCH_SOURCE STREQUAL "module.h")
- set(PCH_EXTRAFLAGS ${PCH_EXTRAFLAGS} -fPIC)
- endif(PCH_SOURCE STREQUAL "module.h")
- if(GETTEXT_INCLUDE)
- set(PCH_GETTEXT_INCLUDE "-I${GETTEXT_INCLUDE}")
- endif(GETTEXT_INCLUDE)
-
- set(PCH_SOURCES_GCH "${PCH_SOURCES_GCH};${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch")
- add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
- COMMAND ${CMAKE_CXX_COMPILER} ARGS ${PCH_CXXFLAGS} ${PCH_EXTRAFLAGS}
- ${PCH_GETTEXT_INCLUDE} -I${CMAKE_CURRENT_BINARY_DIR} -I${Anope_SOURCE_DIR}/modules/pseudoclients ${CMAKE_CURRENT_SOURCE_DIR}/${PCH_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
- DEPENDS ${INCLUDES_LIST} VERBATIM
- )
- endforeach(PCH_SOURCE ${PCH_SOURCES})
-endif(USE_PCH AND CMAKE_COMPILER_IS_GNUCXX)
+endif()
# Add a custom target to the above file
-add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version_build ${PCH_SOURCES_GCH})
+add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version_build)
diff --git a/include/access.h b/include/access.h
deleted file mode 100644
index 6f0124928..000000000
--- a/include/access.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *
- * (C) 2003-2016 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.
- */
-
-#ifndef ACCESS_H
-#define ACCESS_H
-
-#include "services.h"
-#include "anope.h"
-#include "serialize.h"
-#include "service.h"
-
-enum
-{
- ACCESS_INVALID = -10000,
- ACCESS_FOUNDER = 10001
-};
-
-/* A privilege, probably configured using a privilege{} block. Most
- * commands require specific privileges to be executed. The AccessProvider
- * backing each ChanAccess determines whether that ChanAccess has a given
- * privilege.
- */
-struct CoreExport Privilege
-{
- Anope::string name;
- Anope::string desc;
- /* Rank relative to other privileges */
- int rank;
-
- Privilege(const Anope::string &name, const Anope::string &desc, int rank);
- bool operator==(const Privilege &other) const;
-};
-
-class CoreExport PrivilegeManager
-{
- static std::vector<Privilege> Privileges;
- public:
- static void AddPrivilege(Privilege p);
- static void RemovePrivilege(Privilege &p);
- static Privilege *FindPrivilege(const Anope::string &name);
- static std::vector<Privilege> &GetPrivileges();
- static void ClearPrivileges();
-};
-
-/* A provider of access. Only used for creating ChanAccesses, as
- * they contain pure virtual functions.
- */
-class CoreExport AccessProvider : public Service
-{
- public:
- AccessProvider(Module *owner, const Anope::string &name);
- virtual ~AccessProvider();
-
- /** Creates a new ChanAccess entry using this provider.
- * @return The new entry
- */
- virtual ChanAccess *Create() = 0;
-
- private:
- static std::list<AccessProvider *> Providers;
- public:
- static const std::list<AccessProvider *>& GetProviders();
-};
-
-/* Represents one entry of an access list on a channel. */
-class CoreExport ChanAccess : public Serializable
-{
- Anope::string mask;
- /* account this access entry is for, if any */
- Serialize::Reference<NickCore> nc;
-
- public:
- typedef std::vector<ChanAccess *> Path;
-
- /* The provider that created this access entry */
- AccessProvider *provider;
- /* Channel this access entry is on */
- Serialize::Reference<ChannelInfo> ci;
- Anope::string creator;
- time_t last_seen;
- time_t created;
-
- ChanAccess(AccessProvider *p);
- virtual ~ChanAccess();
-
- void SetMask(const Anope::string &mask, ChannelInfo *ci);
- const Anope::string &Mask() const;
- NickCore *GetAccount() const;
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-
- static const unsigned int MAX_DEPTH = 4;
-
- /** Check if this access entry matches the given user or account
- * @param u The user
- * @param nc The account
- * @param next Next channel to check if any
- */
- virtual bool Matches(const User *u, const NickCore *nc, ChannelInfo* &next) const;
-
- /** Check if this access entry has the given privilege.
- * @param name The privilege name
- */
- virtual bool HasPriv(const Anope::string &name) const = 0;
-
- /** Serialize the access given by this access entry into a human
- * readable form. chanserv/access will return a number, chanserv/xop
- * will be AOP, SOP, etc.
- */
- virtual Anope::string AccessSerialize() const = 0;
-
- /** Unserialize this access entry from the given data. This data
- * will be fetched from AccessSerialize.
- */
- virtual void AccessUnserialize(const Anope::string &data) = 0;
-
- /* Comparison operators to other Access entries */
- virtual bool operator>(const ChanAccess &other) const;
- virtual bool operator<(const ChanAccess &other) const;
- bool operator>=(const ChanAccess &other) const;
- bool operator<=(const ChanAccess &other) const;
-};
-
-/* A group of access entries. This is used commonly, for example with ChannelInfo::AccessFor,
- * to show what access a user has on a channel because users can match multiple access entries.
- */
-class CoreExport AccessGroup
-{
- public:
- /* access entries + paths */
- std::vector<ChanAccess::Path> paths;
- /* Channel these access entries are on */
- const ChannelInfo *ci;
- /* Account these entries affect, if any */
- const NickCore *nc;
- /* super_admin always gets all privs. founder is a special case where ci->founder == nc */
- bool super_admin, founder;
-
- AccessGroup();
-
- /** Check if this access group has a certain privilege. Eg, it
- * will check every ChanAccess entry of this group for any that
- * has the given privilege.
- * @param priv The privilege
- * @return true if any entry has the given privilege
- */
- bool HasPriv(const Anope::string &priv) const;
-
- /** Get the "highest" access entry from this group of entries.
- * The highest entry is determined by the entry that has the privilege
- * with the highest rank (see Privilege::rank).
- * @return The "highest" entry
- */
- const ChanAccess *Highest() const;
-
- /* Comparison operators to other AccessGroups */
- bool operator>(const AccessGroup &other) const;
- bool operator<(const AccessGroup &other) const;
- bool operator>=(const AccessGroup &other) const;
- bool operator<=(const AccessGroup &other) const;
-
- inline bool empty() const { return paths.empty(); }
-};
-
-#endif
diff --git a/include/accessgroup.h b/include/accessgroup.h
new file mode 100644
index 000000000..bc7e84089
--- /dev/null
+++ b/include/accessgroup.h
@@ -0,0 +1,62 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/chanserv.h"
+
+#pragma once
+
+namespace ChanServ
+{
+
+/* A group of access entries. This is used commonly, for example with ChanServ::Channel::AccessFor,
+ * to show what access a user has on a channel because users can match multiple access entries.
+ */
+class CoreExport AccessGroup : public std::vector<ChanAccess *>
+{
+ public:
+ /* Channel these access entries are on */
+ ChanServ::Channel *ci = nullptr;
+ /* Account these entries affect, if any */
+ const NickServ::Account *nc = nullptr;
+ /* super_admin always gets all privs. founder is a special case where ci->founder == nc */
+ bool super_admin = false, founder = false;
+
+ /** Check if this access group has a certain privilege. Eg, it
+ * will check every ChanAccess entry of this group for any that
+ * has the given privilege.
+ * @param priv The privilege
+ * @return true if any entry has the given privilege
+ */
+ bool HasPriv(const Anope::string &priv);
+
+ /** Get the "highest" access entry from this group of entries.
+ * The highest entry is determined by the entry that has the privilege
+ * with the highest rank (see Privilege::rank).
+ * @return The "highest" entry
+ */
+ ChanAccess *Highest();
+
+ /* Comparison operators to other AccessGroups */
+ bool operator>(AccessGroup &other);
+ bool operator<(AccessGroup &other);
+ bool operator>=(AccessGroup &other);
+ bool operator<=(AccessGroup &other);
+};
+
+} // namespace ChanServ \ No newline at end of file
diff --git a/include/account.h b/include/account.h
deleted file mode 100644
index c49f5f205..000000000
--- a/include/account.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *
- * (C) 2003-2016 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.
- */
-
-#ifndef ACCOUNT_H
-#define ACCOUNT_H
-
-#include "extensible.h"
-#include "serialize.h"
-#include "anope.h"
-#include "memo.h"
-#include "base.h"
-
-typedef Anope::hash_map<NickAlias *> nickalias_map;
-typedef Anope::hash_map<NickCore *> nickcore_map;
-
-extern CoreExport Serialize::Checker<nickalias_map> NickAliasList;
-extern CoreExport Serialize::Checker<nickcore_map> NickCoreList;
-
-/* A registered nickname.
- * It matters that Base is here before Extensible (it is inherited by Serializable)
- */
-class CoreExport NickAlias : public Serializable, public Extensible
-{
- Anope::string vhost_ident, vhost_host, vhost_creator;
- time_t vhost_created;
-
- public:
- Anope::string nick;
- Anope::string last_quit;
- Anope::string last_realname;
- /* Last usermask this nick was seen on, eg user@host */
- Anope::string last_usermask;
- /* Last uncloaked usermask, requires nickserv/auspex to see */
- Anope::string last_realhost;
- time_t time_registered;
- time_t last_seen;
- /* Account this nick is tied to. Multiple nicks can be tied to a single account. */
- Serialize::Reference<NickCore> nc;
-
- /** Constructor
- * @param nickname The nick
- * @param nickcore The nickcore for this nick
- */
- NickAlias(const Anope::string &nickname, NickCore *nickcore);
- ~NickAlias();
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-
- /** Set a vhost for the user
- * @param ident The ident
- * @param host The host
- * @param creator Who created the vhost
- * @param time When the vhost was craated
- */
- void SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created = Anope::CurTime);
-
- /** Remove a users vhost
- **/
- void RemoveVhost();
-
- /** Check if the user has a vhost
- * @return true or false
- */
- bool HasVhost() const;
-
- /** Retrieve the vhost ident
- * @return the ident
- */
- const Anope::string &GetVhostIdent() const;
-
- /** Retrieve the vhost host
- * @return the host
- */
- const Anope::string &GetVhostHost() const;
-
- /** Retrieve the vhost creator
- * @return the creator
- */
- const Anope::string &GetVhostCreator() const;
-
- /** Retrieve when the vhost was created
- * @return the time it was created
- */
- time_t GetVhostCreated() const;
-
- /** Finds a registered nick
- * @param nick The nick to lookup
- * @return the nick, if found
- */
- static NickAlias *Find(const Anope::string &nick);
-};
-
-/* A registered account. Each account must have a NickAlias with the same nick as the
- * account's display.
- * It matters that Base is here before Extensible (it is inherited by Serializable)
- */
-class CoreExport NickCore : public Serializable, public Extensible
-{
- /* Channels which reference this core in some way (this is on their access list, akick list, is founder, successor, etc) */
- Serialize::Checker<std::map<ChannelInfo *, int> > chanaccess;
- public:
- /* Name of the account. Find(display)->nc == this. */
- Anope::string display;
- /* User password in form of hashm:data */
- Anope::string pass;
- Anope::string email;
- /* Locale name of the language of the user. Empty means default language */
- Anope::string language;
- /* Access list, contains user@host masks of users who get certain privileges based
- * on if NI_SECURE is set and what (if any) kill protection is enabled. */
- std::vector<Anope::string> access;
- MemoInfo memos;
- std::map<Anope::string, Anope::string> last_modes;
-
- /* Nicknames registered that are grouped to this account.
- * for n in aliases, n->nc == this.
- */
- Serialize::Checker<std::vector<NickAlias *> > aliases;
-
- /* Set if this user is a services operattor. o->ot must exist. */
- Oper *o;
-
- /* Unsaved data */
-
- /* Number of channels registered by this account */
- uint16_t channelcount;
- /* Last time an email was sent to this user */
- time_t lastmail;
- /* Users online now logged into this account */
- std::list<User *> users;
-
- /** Constructor
- * @param display The display nick
- */
- NickCore(const Anope::string &nickdisplay);
- ~NickCore();
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-
- /** Changes the display for this account
- * @param na The new display, must be grouped to this account.
- */
- void SetDisplay(const NickAlias *na);
-
- /** Checks whether this account is a services oper or not.
- * @return True if this account is a services oper, false otherwise.
- */
- virtual bool IsServicesOper() const;
-
- /** Add an entry to the nick's access list
- *
- * @param entry The nick!ident@host entry to add to the access list
- *
- * Adds a new entry into the access list.
- */
- void AddAccess(const Anope::string &entry);
-
- /** Get an entry from the nick's access list by index
- *
- * @param entry Index in the access list vector to retrieve
- * @return The access list entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
- *
- * Retrieves an entry from the access list corresponding to the given index.
- */
- Anope::string GetAccess(unsigned entry) const;
-
- /** Get the number of entries on the access list for this account.
- */
- unsigned GetAccessCount() const;
-
- /** Find an entry in the nick's access list
- *
- * @param entry The nick!ident@host entry to search for
- * @return True if the entry is found in the access list, false otherwise
- *
- * Search for an entry within the access list.
- */
- bool FindAccess(const Anope::string &entry);
-
- /** Erase an entry from the nick's access list
- *
- * @param entry The nick!ident@host entry to remove
- *
- * Removes the specified access list entry from the access list.
- */
- void EraseAccess(const Anope::string &entry);
-
- /** Clears the entire nick's access list
- *
- * Deletes all the memory allocated in the access list vector and then clears the vector.
- */
- void ClearAccess();
-
- /** Is the given user on this accounts access list?
- *
- * @param u The user
- *
- * @return true if the user is on the access list
- */
- bool IsOnAccess(const User *u) const;
-
- /** Finds an account
- * @param nick The account name to find
- * @return The account, if it exists
- */
- static NickCore* Find(const Anope::string &nick);
-
- void AddChannelReference(ChannelInfo *ci);
- void RemoveChannelReference(ChannelInfo *ci);
- void GetChannelReferences(std::deque<ChannelInfo *> &queue);
-};
-
-/* A request to check if an account/password is valid. These can exist for
- * extended periods due to the time some authentication modules take.
- */
-class CoreExport IdentifyRequest
-{
- /* Owner of this request, used to cleanup requests if a module is unloaded
- * while a reqyest us pending */
- Module *owner;
- Anope::string account;
- Anope::string password;
-
- std::set<Module *> holds;
- bool dispatched;
- bool success;
-
- static std::set<IdentifyRequest *> Requests;
-
- protected:
- IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass);
- virtual ~IdentifyRequest();
-
- public:
- /* One of these is called when the request goes through */
- virtual void OnSuccess() = 0;
- virtual void OnFail() = 0;
-
- const Anope::string &GetAccount() const { return account; }
- const Anope::string &GetPassword() const { return password; }
-
- /* Holds this request. When a request is held it must be Released later
- * for the request to complete. Multiple modules may hold a request at any time,
- * but the request is not complete until every module has released it. If you do not
- * require holding this (eg, your password check is done in this thread and immediately)
- * then you don't need to hold the request before Successing it.
- * @param m The module holding this request
- */
- void Hold(Module *m);
-
- /** Releases a held request
- * @param m The module releaseing the hold
- */
- void Release(Module *m);
-
- /** Called by modules when this IdentifyRequest has successeded successfully.
- * If this request is behind held it must still be Released after calling this.
- * @param m The module confirming authentication
- */
- void Success(Module *m);
-
- /** Used to either finalize this request or marks
- * it as dispatched and begins waiting for the module(s)
- * that have holds to finish.
- */
- void Dispatch();
-
- static void ModuleUnload(Module *m);
-};
-
-#endif // ACCOUNT_H
diff --git a/include/anope.h b/include/anope.h
index 48a4f7674..49e7c7ddc 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef ANOPE_H
-#define ANOPE_H
+#pragma once
#include <signal.h>
@@ -308,33 +315,40 @@ namespace Anope
inline const string operator+(const char *_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
inline const string operator+(const std::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
+ struct hash
+ {
+ size_t operator()(const string &s) const;
+ };
+
+ struct compare
+ {
+ bool operator()(const string &s1, const string &s2) const;
+ };
+
struct hash_ci
{
- inline size_t operator()(const string &s) const
- {
- return TR1NS::hash<std::string>()(s.lower().str());
- }
+ size_t operator()(const string &s) const;
};
- struct hash_cs
+ struct compare_ci
{
- inline size_t operator()(const string &s) const
- {
- return TR1NS::hash<std::string>()(s.str());
- }
+ bool operator()(const string &s1, const string &s2) const;
};
- struct compare
+ struct hash_locale
{
- inline bool operator()(const string &s1, const string &s2) const
- {
- return s1.equals_ci(s2);
- }
+ size_t operator()(const string &s) const;
};
- template<typename T> class map : public std::map<string, T, ci::less> { };
- template<typename T> class multimap : public std::multimap<string, T, ci::less> { };
- template<typename T> class hash_map : public TR1NS::unordered_map<string, T, hash_ci, compare> { };
+ struct compare_locale
+ {
+ bool operator()(const string &s1, const string &s2) const;
+ };
+
+ template<typename T> using map = std::map<string, T, ci::less>;
+ template<typename T> using multimap = std::multimap<string, T, ci::less>;
+ template<typename T> using hash_map = std::unordered_map<string, T, hash_ci, compare_ci>;
+ template<typename T> using locale_hash_map = std::unordered_map<string, T, hash_locale, compare_locale>;
#ifndef REPRODUCIBLE_BUILD
static const char *const compiled = __TIME__ " " __DATE__;
@@ -366,7 +380,7 @@ namespace Anope
*/
extern CoreExport bool ReadOnly, NoFork, NoThird, NoExpire, ProtocolDebug;
- /** The root of the services installation. Usually ~/services
+ /** The root of the services installation. Usually ~/anope
*/
extern CoreExport Anope::string ServicesDir;
@@ -443,13 +457,13 @@ namespace Anope
*/
extern CoreExport void Unhex(const string &src, string &dest);
extern CoreExport void Unhex(const string &src, char *dest, size_t sz);
-
+
/** Base 64 encode a string
* @param src The string to encode
* @param target Where the encoded string is placed
*/
extern CoreExport void B64Encode(const string &src, string &target);
-
+
/** Base 64 decode a string
* @param src The base64 encoded string
* @param target The plain text result
@@ -462,14 +476,6 @@ namespace Anope
*/
extern CoreExport void Encrypt(const Anope::string &src, Anope::string &dest);
- /** Decrypts what is in 'src' to 'dest'.
- * @param src The source string to decrypt
- * @param dest The destination where the decrypted string is placed
- * @return true if decryption was successful. This is usually not the case
- * as most encryption methods we use are one way.
- */
- extern CoreExport bool Decrypt(const Anope::string &src, Anope::string &dest);
-
/** Returns a sequence of data formatted as the format argument specifies.
** After the format parameter, the function expects at least as many
** additional arguments as specified in format.
@@ -504,21 +510,21 @@ namespace Anope
* @param nc The account to use language settings for to translate this string, if applicable
* @return A human readable string, eg "1 minute"
*/
- extern CoreExport Anope::string Duration(time_t seconds, const NickCore *nc = NULL);
+ extern CoreExport Anope::string Duration(time_t seconds, NickServ::Account *nc = NULL);
/** Generates a human readable string of type "expires in ..."
* @param expires time in seconds
* @param nc The account to use language settings for to translate this string, if applicable
* @return A human readable string, eg "expires in 5 days"
*/
- extern CoreExport Anope::string Expires(time_t seconds, const NickCore *nc = NULL);
+ extern CoreExport Anope::string Expires(time_t seconds, NickServ::Account *nc = NULL);
/** Converts a time in seconds (epoch) to a human readable format.
* @param t The time
* @param nc The account to use language settings for to translate this string, if applicable
* @param short_output If true, the output is just a date (eg, "Apr 12 20:18:22 2009 MSD"), else it includes the date and how long ago/from now that date is, (eg "Apr 12 20:18:22 2009 MSD (1313 days, 9 hours, 32 minutes ago)"
*/
- extern CoreExport Anope::string strftime(time_t t, const NickCore *nc = NULL, bool short_output = false);
+ extern CoreExport Anope::string strftime(time_t t, NickServ::Account *nc = NULL, bool short_output = false);
/** Normalize buffer, stripping control characters and colors
* @param A string to be parsed for control and color codes
@@ -633,7 +639,7 @@ class spacesepstream : public sepstream
public:
/** Initialize with space seperator
*/
- spacesepstream(const Anope::string &source) : sepstream(source, ' ') { }
+ spacesepstream(const Anope::string &source, bool allowempty = false) : sepstream(source, ' ', allowempty) { }
};
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
@@ -706,6 +712,22 @@ class ConvertException : public CoreException
virtual ~ConvertException() throw() { }
};
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::ostream &>::type
+operator<<(std::ostream &os, T t)
+{
+ // XXX
+ return os;
+}
+
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::istream &>::type
+operator>>(std::istream &is, T& t)
+{
+ // XXX
+ return is;
+}
+
/** Convert something to a string
*/
template<typename T> inline Anope::string stringify(const T &x)
@@ -778,4 +800,66 @@ template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr)
}
#endif
-#endif // ANOPE_H
+struct kwarg
+{
+ Anope::string name, value;
+
+ template<typename T>
+ kwarg& operator=(const T& rhs)
+ {
+ value = stringify(rhs);
+ return *this;
+ }
+};
+
+inline kwarg operator"" _kw(const char *literal, size_t n)
+{
+ return { literal };
+}
+
+struct FormatInfo
+{
+ Anope::string format;
+ std::vector<kwarg> parameters;
+ unsigned int pos = 0;
+
+ FormatInfo(const Anope::string &fmt, size_t size) : format(fmt), parameters(size) { }
+
+ template<typename T>
+ void Add(T& arg)
+ {
+ parameters[pos] = kwarg{ stringify(pos).c_str() } = stringify(arg);
+ ++pos;
+ }
+
+ template<typename Arg, typename... Args>
+ void Format(Arg &&arg, Args&&... args)
+ {
+ Add(arg);
+ Format(std::forward<Args>(args)...);
+ }
+
+ void Format()
+ {
+ for (kwarg& arg : parameters)
+ format = format.replace_all_cs("{" + arg.name + "}", arg.value);
+ }
+};
+
+template<>
+inline void FormatInfo::Add(kwarg &arg)
+{
+ parameters[pos++] = arg;
+}
+
+namespace Anope
+{
+ template<typename... Args>
+ inline Anope::string Format(const Anope::string &format, Args&&... args)
+ {
+ FormatInfo fi(format, sizeof...(Args));
+ fi.Format(std::forward<Args>(args)...);
+ return fi.format;
+ }
+}
+
diff --git a/include/base.h b/include/base.h
index 677c0cfc8..d82d2a4d2 100644
--- a/include/base.h
+++ b/include/base.h
@@ -1,13 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Adam <Adam@anope.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef BASE_H
-#define BASE_H
+#pragma once
#include "services.h"
@@ -32,13 +42,14 @@ class CoreExport Base
class ReferenceBase
{
- protected:
- bool invalid;
+ static std::set<ReferenceBase *> *references;
public:
- ReferenceBase() : invalid(false) { }
- ReferenceBase(const ReferenceBase &other) : invalid(other.invalid) { }
- virtual ~ReferenceBase() { }
- inline void Invalidate() { this->invalid = true; }
+ static void ResetAll();
+
+ ReferenceBase();
+ virtual ~ReferenceBase();
+ virtual void Invalidate() anope_abstract;
+ virtual void Reset() { }
};
/** Used to hold pointers to objects that may be deleted. A Reference will
@@ -49,8 +60,11 @@ class Reference : public ReferenceBase
{
protected:
T *ref;
+
+ virtual void Check() { }
+
public:
- Reference() : ref(NULL)
+ Reference() : ref(nullptr)
{
}
@@ -60,19 +74,24 @@ class Reference : public ReferenceBase
ref->AddReference(this);
}
- Reference(const Reference<T> &other) : ReferenceBase(other), ref(other.ref)
+ Reference(const Reference<T> &other) : ref(other.ref)
{
- if (operator bool())
+ if (ref)
ref->AddReference(this);
}
virtual ~Reference()
{
- if (operator bool())
- ref->DelReference(this);
+ if (*this)
+ this->ref->DelReference(this);
+ }
+
+ void Invalidate() override
+ {
+ ref = nullptr;
}
- inline Reference<T>& operator=(const Reference<T> &other)
+ Reference<T>& operator=(const Reference<T> &other)
{
if (this != &other)
{
@@ -80,7 +99,6 @@ class Reference : public ReferenceBase
this->ref->DelReference(this);
this->ref = other.ref;
- this->invalid = other.invalid;
if (*this)
this->ref->AddReference(this);
@@ -88,36 +106,31 @@ class Reference : public ReferenceBase
return *this;
}
- /* We explicitly call operator bool here in several places to prevent other
- * operators, such operator T*, from being called instead, which will mess
- * with any class inheriting from this that overloads this operator.
- */
- virtual operator bool()
+ explicit operator bool()
{
- if (!this->invalid)
- return this->ref != NULL;
- return false;
+ Check();
+ return this->ref != nullptr;
}
- inline operator T*()
+ operator T*()
{
- if (operator bool())
+ if (*this)
return this->ref;
- return NULL;
+ return nullptr;
}
- inline T* operator->()
+ T* operator->()
{
- if (operator bool())
+ if (*this)
return this->ref;
- return NULL;
+ return nullptr;
}
- inline T* operator*()
+ T* operator*()
{
- if (operator bool())
+ if (*this)
return this->ref;
- return NULL;
+ return nullptr;
}
/** Note that we can't have an operator< that returns this->ref < other.ref
@@ -132,12 +145,11 @@ class Reference : public ReferenceBase
* actually referred to.
*/
- inline bool operator==(const Reference<T> &other)
+ bool operator==(const Reference<T> &other)
{
- if (!this->invalid)
+ if (*this)
return this->ref == other;
return false;
}
};
-#endif // BASE_H
diff --git a/include/bots.h b/include/bots.h
index 6b429b66d..0fa35e8a1 100644
--- a/include/bots.h
+++ b/include/bots.h
@@ -1,45 +1,43 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef BOTS_H
-#define BOTS_H
+#pragma once
#include "users.h"
#include "anope.h"
#include "serialize.h"
#include "commands.h"
-
-
-typedef Anope::map<BotInfo *> botinfo_map;
-
-extern CoreExport Serialize::Checker<botinfo_map> BotListByNick, BotListByUID;
+#include "config.h"
/* A service bot (NickServ, ChanServ, a BotServ bot, etc). */
-class CoreExport BotInfo : public User, public Serializable
+class CoreExport ServiceBot : public LocalUser
{
- /* Channels this bot is assigned to */
- Serialize::Checker<std::set<ChannelInfo *> > channels;
public:
- time_t created;
- /* Last time this bot said something (via privmsg) */
- time_t lastmsg;
+ /* Underlying botinfo for this bot */
+ Serialize::Reference<BotInfo> bi;
/* Map of actual command names -> service name/permission required */
CommandInfo::map commands;
/* Modes the bot should have as configured in service:modes */
Anope::string botmodes;
- /* Channels the bot should be in as configured in service:channels */
- std::vector<Anope::string> botchannels;
/* Whether or not this bot is introduced to the network */
bool introduced;
- /* Bot can only be assigned by irc ops */
- bool oper_only;
- /* Bot is defined in the configuration file */
- bool conf;
/** Create a new bot.
* @param nick The nickname to assign to the bot.
@@ -48,14 +46,11 @@ class CoreExport BotInfo : public User, public Serializable
* @param real The realname to give the bot.
* @param bmodes The modes to give the bot.
*/
- BotInfo(const Anope::string &nick, const Anope::string &user = "", const Anope::string &host = "", const Anope::string &real = "", const Anope::string &bmodes = "");
+ ServiceBot(const Anope::string &nick, const Anope::string &user = "", const Anope::string &host = "", const Anope::string &real = "", const Anope::string &bmodes = "");
/** Destroy a bot, clearing up appropriately.
*/
- virtual ~BotInfo();
-
- void Serialize(Serialize::Data &data) const;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
+ virtual ~ServiceBot();
void GenerateUID();
@@ -68,19 +63,19 @@ class CoreExport BotInfo : public User, public Serializable
/** Return the channels this bot is assigned to
*/
- const std::set<ChannelInfo *> &GetChannels() const;
+ std::vector<ChanServ::Channel *> GetChannels() const;
/** Assign this bot to a given channel, removing the existing assigned bot if one exists.
* @param u The user assigning the bot, or NULL
* @param ci The channel registration to assign the bot to.
*/
- void Assign(User *u, ChannelInfo *ci);
+ void Assign(User *u, ChanServ::Channel *ci);
/** Remove this bot from a given channel.
* @param u The user requesting the unassign, or NULL.
* @param ci The channel registration to remove the bot from.
*/
- void UnAssign(User *u, ChannelInfo *ci);
+ void UnAssign(User *u, ChanServ::Channel *ci);
/** Get the number of channels this bot is assigned to
*/
@@ -124,12 +119,68 @@ class CoreExport BotInfo : public User, public Serializable
*/
CommandInfo *GetCommand(const Anope::string &cname);
+ CommandInfo *FindCommand(const Anope::string &service);
+
/** Find a bot by nick
* @param nick The nick
* @param nick_only True to only look by nick, and not by UID
* @return The bot, if it exists
*/
- static BotInfo* Find(const Anope::string &nick, bool nick_only = false);
+ static ServiceBot* Find(const Anope::string &nick, bool nick_only = false);
+};
+
+class BotInfo : public Serialize::Object
+{
+ friend class BotInfoType;
+
+ Anope::string nick, user, host, realname;
+ time_t created = 0;
+ bool operonly = false;
+
+ public:
+ static constexpr const char *const NAME = "botinfo";
+
+ ServiceBot *bot;
+ Configuration::Block *conf = nullptr;
+
+ using Serialize::Object::Object;
+
+ void Delete() override;
+
+ void SetNick(const Anope::string &);
+ Anope::string GetNick();
+
+ void SetUser(const Anope::string &);
+ Anope::string GetUser();
+
+ void SetHost(const Anope::string &);
+ Anope::string GetHost();
+
+ void SetRealName(const Anope::string &);
+ Anope::string GetRealName();
+
+ void SetCreated(const time_t &);
+ time_t GetCreated();
+
+ void SetOperOnly(const bool &);
+ bool GetOperOnly();
+};
+
+class BotInfoType : public Serialize::Type<BotInfo>
+{
+ public:
+ Serialize::Field<BotInfo, Anope::string> nick, user, host, realname;
+ Serialize::Field<BotInfo, time_t> created;
+ Serialize::Field<BotInfo, bool> operonly;
+
+ BotInfoType() : Serialize::Type<BotInfo>(nullptr)
+ , nick(this, "nick", &BotInfo::nick)
+ , user(this, "user", &BotInfo::user)
+ , host(this, "host", &BotInfo::host)
+ , realname(this, "realname", &BotInfo::realname)
+ , created(this, "created", &BotInfo::created)
+ , operonly(this, "operonly", &BotInfo::operonly)
+ {
+ }
};
-#endif // BOTS_H
diff --git a/include/channels.h b/include/channels.h
index 547db9f20..664f06a0a 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -1,20 +1,30 @@
-/* Channel support
+/*
+ * Anope IRC Services
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef CHANNELS_H
-#define CHANNELS_H
+#pragma once
#include "anope.h"
#include "extensible.h"
#include "modes.h"
#include "serialize.h"
-typedef Anope::hash_map<Channel *> channel_map;
+using channel_map = Anope::locale_hash_map<Channel *>;
extern CoreExport channel_map ChannelList;
@@ -44,7 +54,7 @@ class CoreExport Channel : public Base, public Extensible
/* Channel name */
Anope::string name;
/* Set if this channel is registered. ci->c == this. Contains information relevant to the registered channel */
- Serialize::Reference<ChannelInfo> ci;
+ Serialize::Reference<ChanServ::Channel> ci;
/* When the channel was created */
time_t creation_time;
/* If the channel has just been created in a netjoin */
@@ -149,7 +159,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param The param
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void SetModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
+ void SetModeInternal(const MessageSource &source, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
/** Remove a mode internally on a channel, this is not sent out to the IRCd
* @param setter The Setter
@@ -157,7 +167,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param The param
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void RemoveModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
+ void RemoveModeInternal(const MessageSource &source, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
/** Set a mode on a channel
* @param bi The client setting the modes
@@ -165,7 +175,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param Optional param arg for the mode
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
+ void SetMode(User *bi, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
/**
* Set a mode on a channel
@@ -174,7 +184,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param Optional param arg for the mode
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void SetMode(BotInfo *bi, const Anope::string &name, const Anope::string &param = "", bool enforce_mlock = true);
+ void SetMode(User *bi, const Anope::string &name, const Anope::string &param = "", bool enforce_mlock = true);
/** Remove a mode from a channel
* @param bi The client setting the modes
@@ -182,7 +192,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param Optional param arg for the mode
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
+ void RemoveMode(User *bi, ChannelMode *cm, const Anope::string &param = "", bool enforce_mlock = true);
/**
* Remove a mode from a channel
@@ -191,7 +201,7 @@ class CoreExport Channel : public Base, public Extensible
* @param param Optional param arg for the mode
* @param enforce_mlock true if mlocks should be enforced, false to override mlock
*/
- void RemoveMode(BotInfo *bi, const Anope::string &name, const Anope::string &param = "", bool enforce_mlock = true);
+ void RemoveMode(User *bi, const Anope::string &name, const Anope::string &param = "", bool enforce_mlock = true);
/** Get a modes parameter for the channel
* @param name The mode
@@ -205,7 +215,7 @@ class CoreExport Channel : public Base, public Extensible
* @param enforce_mlock Should mlock be enforced on this mode change
* @param cmodes The modes to set
*/
- void SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...);
+ void SetModes(User *bi, bool enforce_mlock, const char *cmodes, ...);
/** Set a string of modes internally on a channel
* @param source The setter
@@ -225,8 +235,9 @@ class CoreExport Channel : public Base, public Extensible
* @param source The sender of the kick
* @param nick The nick being kicked
* @param reason The reason for the kick
+ * @return true if the kick was scucessful, false if a module blocked the kick or was otherwise unsuccessful
*/
- void KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason);
+ bool KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason);
/** Kick a user from the channel
* @param bi The sender, can be NULL for the service bot for this channel
@@ -234,7 +245,7 @@ class CoreExport Channel : public Base, public Extensible
* @param reason The reason for the kick
* @return true if the kick was scucessful, false if a module blocked the kick
*/
- bool Kick(BotInfo *bi, User *u, const char *reason = NULL, ...);
+ bool Kick(User *bi, User *u, const char *reason = NULL, ...);
/** Get all modes set on this channel, excluding status modes.
* @return a map of modes and their optional parameters.
@@ -307,4 +318,3 @@ class CoreExport Channel : public Base, public Extensible
static void DeleteChannels();
};
-#endif // CHANNELS_H
diff --git a/include/commands.h b/include/commands.h
index dee85c56f..8cdb0d544 100644
--- a/include/commands.h
+++ b/include/commands.h
@@ -1,27 +1,36 @@
-/* Declarations for command data.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef COMMAND_H
-#define COMMAND_H
+#pragma once
#include "service.h"
#include "anope.h"
#include "channels.h"
+#include "language.h"
+#include "modules/nickserv.h"// XXX clang
struct CommandGroup
{
Anope::string name, description;
};
-/* Used in BotInfo::commands */
+/* Used in ServiceBot::commands */
struct CommandInfo
{
typedef Anope::map<CommandInfo> map;
@@ -30,6 +39,8 @@ struct CommandInfo
/* Service name of the command */
Anope::string name;
+ /* User visible name */
+ Anope::string cname;
/* Permission required to execute the command */
Anope::string permission;
/* Group this command is in */
@@ -46,7 +57,7 @@ struct CommandInfo
struct CoreExport CommandReply
{
virtual ~CommandReply() { }
- virtual void SendMessage(BotInfo *source, const Anope::string &msg) = 0;
+ virtual void SendMessage(const MessageSource &, const Anope::string &msg) anope_abstract;
};
/* The source for a command */
@@ -58,27 +69,33 @@ class CoreExport CommandSource
Reference<User> u;
public:
/* The account executing the command */
- Reference<NickCore> nc;
+ Reference<NickServ::Account> nc;
/* Where the reply should go */
CommandReply *reply;
/* Channel the command was executed on (fantasy) */
Reference<Channel> c;
/* The service this command is on */
- Reference<BotInfo> service;
+ Reference<ServiceBot> service;
/* The actual name of the command being executed */
Anope::string command;
/* The permission of the command being executed */
Anope::string permission;
- CommandSource(const Anope::string &n, User *user, NickCore *core, CommandReply *reply, BotInfo *bi);
+ CommandSource(const Anope::string &n, User *user, NickServ::Account *core, CommandReply *reply, ServiceBot *bi);
const Anope::string &GetNick() const;
User *GetUser();
- NickCore *GetAccount();
- AccessGroup AccessFor(ChannelInfo *ci);
- bool IsFounder(ChannelInfo *ci);
+ NickServ::Account *GetAccount();
+ ChanServ::AccessGroup AccessFor(ChanServ::Channel *ci);
+ bool IsFounder(ChanServ::Channel *ci);
+
+ template<typename... Args>
+ void Reply(const char *message, Args&&... args)
+ {
+ const char *translated_message = Language::Translate(this->nc, message);
+ Reply(Anope::Format(translated_message, std::forward<Args>(args)...));
+ }
- void Reply(const char *message, ...);
void Reply(const Anope::string &message);
bool HasCommand(const Anope::string &cmd);
@@ -107,6 +124,8 @@ class CoreExport Command : public Service
/* Module which owns us */
Module *module;
+ static constexpr const char *NAME = "Command";
+
protected:
/** Create a new command.
* @param owner The owner of the command
@@ -125,12 +144,12 @@ class CoreExport Command : public Service
void ClearSyntax();
void SetSyntax(const Anope::string &s);
- void SendSyntax(CommandSource &);
void AllowUnregistered(bool b);
void RequireUser(bool b);
public:
+ void SendSyntax(CommandSource &);
bool AllowUnregistered() const;
bool RequireUser() const;
@@ -144,7 +163,7 @@ class CoreExport Command : public Service
* @param source The source
* @param params Command parameters
*/
- virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
+ virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_abstract;
/** Called when HELP is requsted for the client this command is on.
* @param source The source
@@ -179,7 +198,6 @@ class CoreExport Command : public Service
* @param name If found, is set to the comand name, eg REGISTER
* @return true if the given command service exists
*/
- static bool FindCommandFromService(const Anope::string &command_service, BotInfo* &bi, Anope::string &name);
+ static bool FindCommandFromService(const Anope::string &command_service, ServiceBot* &bi, Anope::string &name);
};
-#endif // COMMANDS_H
diff --git a/include/config.h b/include/config.h
index e59bd6a85..dccadbe79 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1,22 +1,26 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef CONFIG_H
-#define CONFIG_H
+#pragma once
-#include "account.h"
-#include "regchannel.h"
#include "users.h"
#include "opertype.h"
-#include <stack>
namespace Configuration
{
@@ -38,7 +42,8 @@ namespace Configuration
Block(const Anope::string &);
const Anope::string &GetName() const;
int CountBlock(const Anope::string &name);
- Block* GetBlock(const Anope::string &name, int num = 0);
+ Block* GetBlock(const Anope::string &name);
+ Block* GetBlock(const Anope::string &name, int num);
template<typename T> inline T Get(const Anope::string &tag)
{
@@ -49,7 +54,7 @@ namespace Configuration
*/
template<typename T> T Get(const Anope::string &tag, const Anope::string &def) const
{
- const Anope::string &value = this->Get<const Anope::string>(tag, def);
+ const Anope::string &value = this->Get<Anope::string>(tag, def);
if (!value.empty())
try
{
@@ -59,13 +64,20 @@ namespace Configuration
return T();
}
- bool Set(const Anope::string &tag, const Anope::string &value);
+ template<typename T> void Set(const Anope::string &tag, const T &value)
+ {
+ Set(tag, stringify(value));
+ }
+
const item_map* GetItems() const;
};
- template<> CoreExport const Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const;
+ template<> CoreExport Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const;
template<> CoreExport time_t Block::Get(const Anope::string &tag, const Anope::string &def) const;
template<> CoreExport bool Block::Get(const Anope::string &tag, const Anope::string &def) const;
+ template<> CoreExport unsigned int Block::Get(const Anope::string &tag, const Anope::string &def) const;
+
+ template<> void Block::Set(const Anope::string &tag, const Anope::string &value);
/** Represents a configuration file
*/
@@ -87,6 +99,8 @@ namespace Configuration
};
struct Uplink;
+ struct Usermode;
+ struct Channelmode;
struct CoreExport Conf : Block
{
@@ -102,6 +116,8 @@ namespace Configuration
time_t TimeoutCheck;
/* options:usestrictprivmsg */
bool UseStrictPrivmsg;
+ /* flag for options:regexengine */
+ std::regex::flag_type regex_flags;
/* networkinfo:nickchars */
Anope::string NickChars;
@@ -115,14 +131,20 @@ namespace Configuration
std::vector<Anope::string> Ulines;
/* List of available opertypes */
std::vector<OperType *> MyOperTypes;
- /* List of pairs of opers and their opertype from the config */
- std::vector<Oper *> Opers;
+ /* names of opers configured in the configuration */
+ std::vector<Anope::string> Opers;
/* Map of fantasy commands */
CommandInfo::map Fantasy;
/* Command groups */
std::vector<CommandGroup> CommandGroups;
/* List of modules to autoload */
std::vector<Anope::string> ModulesAutoLoad;
+ /* After how many characters do we wrap lines? */
+ unsigned int LineWrap;
+ std::vector<Usermode> Usermodes;
+ std::vector<Channelmode> Channelmodes;
+ unsigned char CaseMapUpper[256] = { 0 }, CaseMapLower[256] = { 0 };
+ std::locale *locale = nullptr;
/* module configuration blocks */
std::map<Anope::string, Block *> modules;
@@ -137,7 +159,7 @@ namespace Configuration
Block *GetModule(Module *);
Block *GetModule(const Anope::string &name);
- BotInfo *GetClient(const Anope::string &name);
+ ServiceBot *GetClient(const Anope::string &name);
Block *GetCommand(CommandSource &);
};
@@ -153,14 +175,26 @@ namespace Configuration
inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && ipv6 == other.ipv6; }
inline bool operator!=(const Uplink &other) const { return !(*this == other); }
};
+
+ struct Usermode
+ {
+ Anope::string name;
+ char character;
+ bool param;
+ bool oper_only, setable;
+ };
+
+ struct Channelmode
+ {
+ Anope::string name, param_regex;
+ char character;
+ char status; /* status char, if any +/@ */
+ int level; /* relative level */
+ bool oper_only, list, param, param_unset, setable;
+
+ };
}
-/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
- * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
- * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not
- * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user
- * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time.
- */
class ConfigException : public CoreException
{
public:
@@ -170,14 +204,10 @@ class ConfigException : public CoreException
/** This constructor can be used to specify an error message before throwing.
*/
ConfigException(const Anope::string &message) : CoreException(message, "Config Parser") { }
- /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
- * Actually no, it does nothing. Never mind.
- * @throws Nothing!
- */
- virtual ~ConfigException() throw() { }
+
+ virtual ~ConfigException() throw() = default;
};
extern Configuration::File ServicesConf;
extern CoreExport Configuration::Conf *Config;
-#endif // CONFIG_H
diff --git a/include/defs.h b/include/defs.h
index 5cc0cb7ac..b25183062 100644
--- a/include/defs.h
+++ b/include/defs.h
@@ -1,53 +1,79 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2004-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-class AccessGroup;
+
class AutoKick;
class BotInfo;
-class CallBack;
-class ChanAccess;
class Channel;
-class ChannelInfo;
+class ChannelMode;
class ChannelStatus;
+namespace ChanServ
+{
+ class AccessGroup;
+ class ChanAccess;
+ class Channel;
+}
struct ChanUserContainer;
class ClientSocket;
class Command;
class CommandSource;
namespace Configuration { struct Conf; }
class ConnectionSocket;
-namespace DNS { struct Query; }
class Entry;
-class IdentifyRequest;
+class ExtensibleBase;
class InfoFormatter;
class IRCDProto;
class ListenSocket;
class Log;
-class Memo;
+class LogInfo;
+namespace NickServ
+{
+ class Account;
+ class Nick;
+ class IdentifyRequest;
+}
+namespace MemoServ
+{
+ class Memo;
+ class MemoInfo;
+}
class MessageSource;
class Module;
-class NickAlias;
-class NickCore;
class OperType;
class ReferenceBase;
class Regex;
-class Serializable;
+class ServiceBot;
+namespace Serialize
+{
+ using ID = uint64_t;
+ struct Edge;
+ class FieldBase;
+ class TypeBase;
+ class Object;
+}
class Server;
class Socket;
class Thread;
class User;
class XLine;
class XLineManager;
-struct BadWord;
-struct Exception;
-struct MemoInfo;
-struct ModeLock;
-struct Oper;
+class Oper;
namespace SASL { struct Message; }
+class UserMode;
+
diff --git a/include/event.h b/include/event.h
new file mode 100644
index 000000000..b71eef738
--- /dev/null
+++ b/include/event.h
@@ -0,0 +1,1232 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Adam <Adam@anope.org>
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "service.h"
+#include "base.h"
+
+/** Possible return types from events.
+ */
+enum EventReturn
+{
+ EVENT_STOP,
+ EVENT_CONTINUE,
+ EVENT_ALLOW
+};
+
+class Events : public Service
+{
+ public:
+ Events(Module *o, const Anope::string &ename) : Service(o, ename) { }
+};
+
+/* uninstantiated */
+template<typename EventHandler, typename Func, typename Return, typename... Args>
+struct Caller;
+
+/* specialization for void */
+template<typename EventHandler, typename Func, typename... Args>
+struct Caller<EventHandler, Func, void, Args...>
+{
+ void operator()(const std::vector<EventHandler *> &handlers, Func func, Args&&... args)
+ {
+ for (EventHandler *eh : handlers)
+ (eh->*func)(std::forward<Args>(args)...);
+ }
+};
+
+/* specialization for EventReturn */
+template<typename EventHandler, typename Func, typename... Args>
+struct Caller<EventHandler, Func, EventReturn, Args...>
+{
+ EventReturn operator()(const std::vector<EventHandler *> &handlers, Func func, Args&&... args)
+ {
+ EventReturn ret = EVENT_CONTINUE;
+
+ for (EventHandler *eh : handlers)
+ {
+ ret = (eh->*func)(std::forward<Args>(args)...);
+ if (ret != EVENT_CONTINUE)
+ return ret;
+ }
+
+ return ret;
+ }
+};
+
+template<typename EventHandler>
+class EventHook;
+
+template<typename EventHandler>
+class EventDispatcher
+{
+ static_assert(std::is_base_of<Events, EventHandler>::value, "");
+
+ ServiceReferenceList<EventHandler> handlers;
+
+ public:
+ EventDispatcher(const Anope::string &name) : handlers(name) { }
+
+ template<typename Func, typename... Args>
+ auto Dispatch(Func func, Args&&... args) -> decltype(((static_cast<EventHandler*>(nullptr))->*func)(args...))
+ {
+ const std::vector<EventHandler *> h = this->handlers.GetServices();
+ return Caller<EventHandler, Func, decltype(((static_cast<EventHandler*>(nullptr))->*func)(args...)), Args...>()(h, func, std::forward<Args>(args)...);
+ }
+};
+
+template<typename EventHandler>
+class EventHook : public EventHandler
+{
+ static_assert(std::is_base_of<Events, EventHandler>::value, "");
+
+ public:
+ enum class Priority
+ {
+ FIRST,
+ LAST
+ }
+ priority;
+
+ EventHook(Module *creator) : EventHook(creator, Priority::LAST) { }
+
+ EventHook(Module *creator, Priority p)
+ : EventHandler(creator, EventHandler::NAME)
+ , priority(p)
+ {
+#warning "priority doesnt work"
+ }
+};
+
+class EventManager
+{
+ Anope::hash_map<EventDispatcher<Events> *> cache;
+
+ template<typename T>
+ EventDispatcher<T> *GetDispatcher(const Anope::string &name)
+ {
+ auto it = cache.find(name);
+ if (it != cache.end())
+ return reinterpret_cast<EventDispatcher<T> *>(it->second);
+
+ auto dispatcher = new EventDispatcher<T>(name);
+ cache[name] = reinterpret_cast<EventDispatcher<Events> *>(dispatcher);
+ return dispatcher;
+ }
+
+ static EventManager *eventManager;
+
+ public:
+ template<
+ typename Type,
+ typename Function,
+ typename... Args
+ >
+ auto Dispatch(Function Type::*func, Args&&... args) -> decltype(((static_cast<Type*>(nullptr))->*func)(args...))
+ {
+ static_assert(std::is_base_of<Events, Type>::value, "");
+
+ EventDispatcher<Type> *dispatcher = GetDispatcher<Type>(Type::NAME);
+ return dispatcher->Dispatch(func, std::forward<Args>(args)...);
+ }
+
+ static void Init();
+ static EventManager *Get();
+};
+
+namespace Event
+{
+ struct CoreExport PreUserKicked : Events
+ {
+ static constexpr const char *NAME = "preuserkicked";
+
+ using Events::Events;
+
+ /** Called before a user has been kicked from a channel.
+ * @param source The kicker
+ * @param cu The user, channel, and status of the user being kicked
+ * @param kickmsg The reason for the kick.
+ * @return EVENT_STOP to stop the kick, which can only be done if source is 'Me' or from me
+ */
+ virtual EventReturn OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_abstract;
+ };
+
+ struct CoreExport UserKicked : Events
+ {
+ static constexpr const char *NAME = "userkicked";
+
+ using Events::Events;
+
+ /** Called when a user has been kicked from a channel.
+ * @param source The kicker
+ * @param target The user being kicked
+ * @param channel The channel the user was kicked from, which may no longer exist
+ * @param status The status the kicked user had on the channel before they were kicked
+ * @param kickmsg The reason for the kick.
+ */
+ virtual void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_abstract;
+ };
+
+ struct CoreExport PreBotAssign : Events
+ {
+ static constexpr const char *NAME = "prebotassign";
+
+ using Events::Events;
+
+ /** Called before a bot is assigned to a channel.
+ * @param sender The user assigning the bot
+ * @param ci The channel the bot is to be assigned to.
+ * @param bi The bot being assigned.
+ * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the assign.
+ */
+ virtual EventReturn OnPreBotAssign(User *sender, ChanServ::Channel *ci, ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport BotAssign : Events
+ {
+ static constexpr const char *NAME = "botassign";
+
+ using Events::Events;
+
+ /** Called when a bot is assigned ot a channel
+ */
+ virtual void OnBotAssign(User *sender, ChanServ::Channel *ci, ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport BotUnAssign : Events
+ {
+ static constexpr const char *NAME = "botunassign";
+
+ using Events::Events;
+
+ /** Called before a bot is unassigned from a channel.
+ * @param sender The user unassigning the bot
+ * @param ci The channel the bot is being removed from
+ * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the unassign.
+ */
+ virtual EventReturn OnBotUnAssign(User *sender, ChanServ::Channel *ci) anope_abstract;
+ };
+
+ struct CoreExport UserConnect : Events
+ {
+ static constexpr const char *NAME = "userconnect";
+
+ using Events::Events;
+
+ /** Called when a new user connects to the network.
+ * @param u The connecting user.
+ * @param exempt set to true/is true if the user should be excepted from bans etc
+ */
+ virtual void OnUserConnect(User *u, bool &exempt) anope_abstract;
+ };
+
+ struct CoreExport NewServer : Events
+ {
+ static constexpr const char *NAME = "newserver";
+
+ using Events::Events;
+
+ /** Called when a new server connects to the network.
+ * @param s The server that has connected to the network
+ */
+ virtual void OnNewServer(Server *s) anope_abstract;
+ };
+
+ struct CoreExport UserNickChange : Events
+ {
+ static constexpr const char *NAME = "usernickchange";
+
+ using Events::Events;
+
+ /** Called after a user changed the nick
+ * @param u The user.
+ * @param oldnick The old nick of the user
+ */
+ virtual void OnUserNickChange(User *u, const Anope::string &oldnick) anope_abstract;
+ };
+
+ struct CoreExport PreCommand : Events
+ {
+ static constexpr const char *NAME = "precommand";
+
+ using Events::Events;
+
+ /** Called before a command is due to be executed.
+ * @param source The source of the command
+ * @param command The command the user is executing
+ * @param params The parameters the user is sending
+ * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
+ */
+ virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_abstract;
+ };
+
+ struct CoreExport PostCommand : Events
+ {
+ static constexpr const char *NAME = "postcommand";
+
+ using Events::Events;
+
+ /** Called after a command has been executed.
+ * @param source The source of the command
+ * @param command The command the user executed
+ * @param params The parameters the user sent
+ */
+ virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) anope_abstract;
+ };
+
+ struct CoreExport SaveDatabase : Events
+ {
+ static constexpr const char *NAME = "savedatabase";
+
+ using Events::Events;
+
+ /** Called when the databases are saved
+ */
+ virtual void OnSaveDatabase() anope_abstract;
+ };
+
+ struct CoreExport LoadDatabase : Events
+ {
+ static constexpr const char *NAME = "loaddatabase";
+
+ using Events::Events;
+
+ /** Called when the databases are loaded
+ * @return EVENT_CONTINUE to let other modules continue loading, EVENT_STOP to stop
+ */
+ virtual EventReturn OnLoadDatabase() anope_abstract;
+ };
+
+ struct CoreExport Encrypt : Events
+ {
+ static constexpr const char *NAME = "encrypt";
+
+ using Events::Events;
+
+ /** Called when anope needs to check passwords against encryption
+ * see src/encrypt.c for detailed informations
+ */
+ virtual EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_abstract;
+ };
+
+ struct CoreExport CreateBot : Events
+ {
+ static constexpr const char *NAME = "createbot";
+
+ using Events::Events;
+
+ /** Called when a bot is created or destroyed
+ */
+ virtual void OnCreateBot(ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport DelBot : Events
+ {
+ static constexpr const char *NAME = "delbot";
+
+ using Events::Events;
+
+ virtual void OnDelBot(ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport PrePartChannel : Events
+ {
+ static constexpr const char *NAME = "prepartchannel";
+
+ using Events::Events;
+
+ /** Called before a user parts a channel
+ * @param u The user
+ * @param c The channel
+ */
+ virtual void OnPrePartChannel(User *u, Channel *c) anope_abstract;
+ };
+
+ struct CoreExport PartChannel : Events
+ {
+ static constexpr const char *NAME = "partchannel";
+
+ using Events::Events;
+
+ /** Called when a user parts a channel
+ * @param u The user
+ * @param c The channel, may be NULL if the channel no longer exists
+ * @param channel The channel name
+ * @param msg The part reason
+ */
+ virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) anope_abstract;
+ };
+
+ struct CoreExport LeaveChannel : Events
+ {
+ static constexpr const char *NAME = "leavechannel";
+
+ using Events::Events;
+
+ /** 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) anope_abstract;
+ };
+
+ struct CoreExport JoinChannel : Events
+ {
+ static constexpr const char *NAME = "joinchannel";
+
+ using Events::Events;
+
+ /** Called after a user joins a channel
+ * If this event triggers the user is allowed to be in the channel, and will
+ * not be kicked for restricted/akick/forbidden, etc. If you want to kick the user,
+ * use the CheckKick event instead.
+ * @param u The user
+ * @param channel The channel
+ */
+ virtual void OnJoinChannel(User *u, Channel *c) anope_abstract;
+ };
+
+ struct CoreExport TopicUpdated : Events
+ {
+ static constexpr const char *NAME = "topicupdated";
+
+ using Events::Events;
+
+ /** Called when a new topic is set
+ * @param source
+ * @param c The channel
+ * @param setter The user who set the new topic
+ * @param topic The new topic
+ */
+ virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_abstract;
+ };
+
+ struct CoreExport PreServerConnect : Events
+ {
+ static constexpr const char *NAME = "preserverconnect";
+
+ using Events::Events;
+
+ /** Called before Anope connecs to its uplink
+ */
+ virtual void OnPreServerConnect() anope_abstract;
+ };
+
+ struct CoreExport ServerConnect : Events
+ {
+ static constexpr const char *NAME = "serverconnect";
+
+ using Events::Events;
+
+ /** Called when Anope connects to its uplink
+ */
+ virtual void OnServerConnect() anope_abstract;
+ };
+
+ struct CoreExport PreUplinkSync : Events
+ {
+ static constexpr const char *NAME = "preuplinksync";
+
+ using Events::Events;
+
+ /** Called when we are almost done synching with the uplink, just before we send the EOB
+ */
+ virtual void OnPreUplinkSync(Server *serv) anope_abstract;
+ };
+
+ struct CoreExport ServerDisconnect : Events
+ {
+ static constexpr const char *NAME = "serverdisconnect";
+
+ using Events::Events;
+
+ /** Called when Anope disconnects from its uplink, before it tries to reconnect
+ */
+ virtual void OnServerDisconnect() anope_abstract;
+ };
+
+ struct CoreExport Restart : Events
+ {
+ static constexpr const char *NAME = "restart";
+
+ using Events::Events;
+
+ /** Called when services restart
+ */
+ virtual void OnRestart() anope_abstract;
+ };
+
+ struct CoreExport Shutdown : Events
+ {
+ static constexpr const char *NAME = "shutdown";
+
+ using Events::Events;
+
+ /** Called when services shutdown
+ */
+ virtual void OnShutdown() anope_abstract;
+ };
+
+ struct CoreExport AddXLine : Events
+ {
+ static constexpr const char *NAME = "addxline";
+
+ using Events::Events;
+
+ /** Called before a XLine is added
+ * @param source The source of 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(CommandSource &source, const XLine *x, XLineManager *xlm) anope_abstract;
+ };
+
+ struct CoreExport DelXLine : Events
+ {
+ static constexpr const char *NAME = "delxline";
+
+ using Events::Events;
+
+ /** Called before a XLine is deleted
+ * @param source The source of the XLine
+ * @param x The XLine
+ * @param xlm The xline manager it was deleted from
+ */
+ virtual void OnDelXLine(CommandSource &source, const XLine *x, XLineManager *xlm) anope_abstract;
+ };
+
+ struct CoreExport IsServicesOperEvent : Events
+ {
+ static constexpr const char *NAME = "isservicesoper";
+
+ using Events::Events;
+
+ /** Called when a user is checked for whether they are a services oper
+ * @param u The user
+ * @return EVENT_ALLOW to allow, anything else to deny
+ */
+ virtual EventReturn IsServicesOper(User *u) anope_abstract;
+ };
+
+ struct CoreExport ServerQuit : Events
+ {
+ static constexpr const char *NAME = "serverquit";
+
+ using Events::Events;
+
+ /** Called when a server quits
+ * @param server The server
+ */
+ virtual void OnServerQuit(Server *server) anope_abstract;
+ };
+
+ struct CoreExport UserQuit : Events
+ {
+ static constexpr const char *NAME = "userquit";
+
+ using Events::Events;
+
+ /** Called when a user quits, or is killed
+ * @param u The user
+ * @param msg The quit message
+ */
+ virtual void OnUserQuit(User *u, const Anope::string &msg) anope_abstract;
+ };
+
+ struct CoreExport PreUserLogoff : Events
+ {
+ static constexpr const char *NAME = "preuserlogoff";
+
+ using Events::Events;
+
+ /** Called when a user is quit, before and after being internally removed from
+ * This is different from OnUserQuit, which takes place at the time of the quit.
+ * This happens shortly after when all message processing is finished.
+ * all lists (channels, user list, etc)
+ * @param u The user
+ */
+ virtual void OnPreUserLogoff(User *u) anope_abstract;
+ };
+
+ struct CoreExport PostUserLogoff : Events
+ {
+ static constexpr const char *NAME = "postuserlogoff";
+
+ using Events::Events;
+
+ virtual void OnPostUserLogoff(User *u) anope_abstract;
+ };
+
+ struct CoreExport AccessDel : Events
+ {
+ static constexpr const char *NAME = "accessdel";
+
+ using Events::Events;
+
+ /** Called after an access entry is deleted from a channel
+ * @param ci The channel
+ * @param source The source of the command
+ * @param access The access entry that was removed
+ */
+ virtual void OnAccessDel(ChanServ::Channel *ci, CommandSource &source, ChanServ::ChanAccess *access) anope_abstract;
+ };
+
+ struct CoreExport AccessAdd : Events
+ {
+ static constexpr const char *NAME = "accessadd";
+
+ using Events::Events;
+
+ /** Called when access is added
+ * @param ci The channel
+ * @param source The source of the command
+ * @param access The access changed
+ */
+ virtual void OnAccessAdd(ChanServ::Channel *ci, CommandSource &source, ChanServ::ChanAccess *access) anope_abstract;
+ };
+
+ struct CoreExport AccessClear : Events
+ {
+ static constexpr const char *NAME = "accessclear";
+
+ using Events::Events;
+
+ /** Called when the access list is cleared
+ * @param ci The channel
+ * @param u The user who cleared the access
+ */
+ virtual void OnAccessClear(ChanServ::Channel *ci, CommandSource &source) anope_abstract;
+ };
+
+ struct CoreExport ChanRegistered : Events
+ {
+ static constexpr const char *NAME = "chanregistered";
+
+ using Events::Events;
+
+ /** Called when a channel is registered
+ * @param ci The channel
+ */
+ virtual void OnChanRegistered(ChanServ::Channel *ci) anope_abstract;
+ };
+
+ struct CoreExport DelChan : Events
+ {
+ static constexpr const char *NAME = "delchan";
+
+ using Events::Events;
+
+ /** Called when a channel is being deleted, for any reason
+ * @param ci The channel
+ */
+ virtual void OnDelChan(ChanServ::Channel *ci) anope_abstract;
+ };
+
+ struct CoreExport ChannelCreate : Events
+ {
+ static constexpr const char *NAME = "channelcreate";
+
+ using Events::Events;
+
+ /** Called when a new channel is created
+ * Note that this channel may not be introduced to the uplink at this point.
+ * @param c The channel
+ */
+ virtual void OnChannelCreate(Channel *c) anope_abstract;
+ };
+
+ struct CoreExport ChannelDelete : Events
+ {
+ static constexpr const char *NAME = "channeldelete";
+
+ using Events::Events;
+
+ /** Called when a channel is deleted
+ * @param c The channel
+ */
+ virtual void OnChannelDelete(Channel *c) anope_abstract;
+ };
+
+ struct CoreExport CheckKick : Events
+ {
+ static constexpr const char *NAME = "checkkick";
+
+ using Events::Events;
+
+ /** Called after a user join a channel when we decide whether to kick them or not
+ * @param u The user
+ * @param c The channel
+ * @param kick Set to true to kick
+ * @param mask The mask to ban, if any
+ * @param reason The reason for the kick
+ * @return EVENT_STOP to prevent the user from joining by kicking/banning the user
+ */
+ virtual EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_abstract;
+ };
+
+ struct CoreExport CheckPriv : Events
+ {
+ static constexpr const char *NAME = "checkpriv";
+
+ using Events::Events;
+
+ /** Checks if access has the channel privilege 'priv'.
+ * @param access THe access struct
+ * @param priv The privilege being checked for
+ * @return EVENT_ALLOW for yes, EVENT_STOP to stop all processing
+ */
+ virtual EventReturn OnCheckPriv(const ChanServ::ChanAccess *access, const Anope::string &priv) anope_abstract;
+ };
+
+ struct CoreExport GroupCheckPriv : Events
+ {
+ static constexpr const char *NAME = "groupcheckpriv";
+
+ using Events::Events;
+
+ /** Check whether an access group has a privilege
+ * @param group The group
+ * @param priv The privilege
+ * @return MOD_ALLOW to allow, MOD_STOP to stop
+ */
+ virtual EventReturn OnGroupCheckPriv(const ChanServ::AccessGroup *group, const Anope::string &priv) anope_abstract;
+ };
+
+ struct CoreExport NickIdentify : Events
+ {
+ static constexpr const char *NAME = "nickidentify";
+
+ using Events::Events;
+
+ /** Called when a user identifies to a nick
+ * @param u The user
+ */
+ virtual void OnNickIdentify(User *u) anope_abstract;
+ };
+
+ struct CoreExport UserLogin : Events
+ {
+ static constexpr const char *NAME = "userlogin";
+
+ using Events::Events;
+
+ /** Called when a user is logged into an account
+ * @param u The user
+ */
+ virtual void OnUserLogin(User *u) anope_abstract;
+ };
+
+ struct CoreExport NickLogout : Events
+ {
+ static constexpr const char *NAME = "nicklogout";
+
+ using Events::Events;
+
+ /** Called when a nick logs out
+ * @param u The nick
+ */
+ virtual void OnNickLogout(User *u) anope_abstract;
+ };
+
+ struct CoreExport DelNick : Events
+ {
+ static constexpr const char *NAME = "delnick";
+
+ using Events::Events;
+
+ /** Called on delnick()
+ * @param na pointer to the nickalias
+ */
+ virtual void OnDelNick(NickServ::Nick *na) anope_abstract;
+ };
+
+ struct CoreExport DelCore : Events
+ {
+ static constexpr const char *NAME = "delcore";
+
+ using Events::Events;
+
+ /** Called on delcore()
+ * @param nc pointer to the NickServ::Account
+ */
+ virtual void OnDelCore(NickServ::Account *nc) anope_abstract;
+ };
+
+ struct CoreExport ChangeCoreDisplay : Events
+ {
+ static constexpr const char *NAME = "changecoredisplay";
+
+ using Events::Events;
+
+ /** Called on change_core_display()
+ * @param nc pointer to the NickServ::Account
+ * @param newdisplay the new display
+ */
+ virtual void OnChangeCoreDisplay(NickServ::Account *nc, const Anope::string &newdisplay) anope_abstract;
+ };
+
+ struct CoreExport NickClearAccess : Events
+ {
+ static constexpr const char *NAME = "nickclearaccess";
+
+ using Events::Events;
+
+ /** called from NickServ::Account::ClearAccess()
+ * @param nc pointer to the NickServ::Account
+ */
+ virtual void OnNickClearAccess(NickServ::Account *nc) anope_abstract;
+ };
+
+ struct CoreExport NickAddAccess : Events
+ {
+ static constexpr const char *NAME = "nickaddaccess";
+
+ using Events::Events;
+
+ /** Called when a user adds an entry to their access list
+ * @param nc The nick
+ * @param entry The entry
+ */
+ virtual void OnNickAddAccess(NickServ::Account *nc, const Anope::string &entry) anope_abstract;
+ };
+
+ struct CoreExport NickEraseAccess : Events
+ {
+ static constexpr const char *NAME = "nickeraseaccess";
+
+ using Events::Events;
+
+ /** Called from NickServ::Account::EraseAccess()
+ * @param nc pointer to the NickServ::Account
+ * @param entry The access mask
+ */
+ virtual void OnNickEraseAccess(NickServ::Account *nc, const Anope::string &entry) anope_abstract;
+ };
+
+ struct CoreExport CheckAuthentication : Events
+ {
+ static constexpr const char *NAME = "checkauthentication";
+
+ using Events::Events;
+
+ /** Check whether a username and password is correct
+ * @param u The user trying to identify, if applicable.
+ * @param req The login request
+ */
+ virtual void OnCheckAuthentication(User *u, NickServ::IdentifyRequest *req) anope_abstract;
+ };
+
+ struct CoreExport Fingerprint : Events
+ {
+ static constexpr const char *NAME = "fingerprint";
+
+ using Events::Events;
+
+ /** Called when we get informed about a users SSL fingerprint
+ * when we call this, the fingerprint should already be stored in the user struct
+ * @param u pointer to the user
+ */
+ virtual void OnFingerprint(User *u) anope_abstract;
+ };
+
+ struct CoreExport UserAway : Events
+ {
+ static constexpr const char *NAME = "useraway";
+
+ using Events::Events;
+
+ /** Called when a user becomes (un)away
+ * @param message The message, is .empty() if unaway
+ */
+ virtual void OnUserAway(User *u, const Anope::string &message) anope_abstract;
+ };
+
+ struct CoreExport Invite : Events
+ {
+ static constexpr const char *NAME = "invite";
+
+ using Events::Events;
+
+ /** Called when a user invites one of our users to a channel
+ * @param source The user doing the inviting
+ * @param c The channel the user is inviting to
+ * @param targ The user being invited
+ */
+ virtual void OnInvite(User *source, Channel *c, User *targ) anope_abstract;
+ };
+
+ struct CoreExport SetVhost : Events
+ {
+ static constexpr const char *NAME = "setvhost";
+
+ using Events::Events;
+
+ /** Called when a vhost is set
+ * @param na The nickalias of the vhost
+ */
+ virtual void OnSetVhost(NickServ::Nick *na) anope_abstract;
+ };
+
+ struct CoreExport SetDisplayedHost : Events
+ {
+ static constexpr const char *NAME = "setdisplayedhost";
+
+ using Events::Events;
+
+ /** Called when a users host changes
+ * @param u The user
+ */
+ virtual void OnSetDisplayedHost(User *) anope_abstract;
+ };
+
+ struct CoreExport ChannelModeSet : Events
+ {
+ static constexpr const char *NAME = "channelmodeset";
+
+ using Events::Events;
+
+ /** Called when a mode is set on a channel
+ * @param c The channel
+ * @param setter The user or server that is setting the mode
+ * @param mode The mode
+ * @param param The mode param, if there is one
+ * @return EVENT_STOP to make mlock/secureops etc checks not happen
+ */
+ virtual EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_abstract;
+ };
+
+ struct CoreExport ChannelModeUnset : Events
+ {
+ static constexpr const char *NAME = "channelmodeunset";
+
+ using Events::Events;
+
+ /** Called when a mode is unset on a channel
+ * @param c The channel
+ * @param setter The user or server that is unsetting the mode
+ * @param mode The mode
+ * @param param The mode param, if there is one
+ * @return EVENT_STOP to make mlock/secureops etc checks not happen
+ */
+ virtual EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_abstract;
+ };
+
+ struct CoreExport UserModeSet : Events
+ {
+ static constexpr const char *NAME = "usermodeset";
+
+ using Events::Events;
+
+ /** Called when a mode is set on a user
+ * @param setter who/what is setting the mode
+ * @param u The user
+ * @param mname The mode name
+ */
+ virtual void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_abstract;
+ };
+
+ struct CoreExport UserModeUnset : Events
+ {
+ static constexpr const char *NAME = "usermodeunset";
+
+ using Events::Events;
+
+ /** Called when a mode is unset from a user
+ * @param setter who/what is setting the mode
+ * @param u The user
+ * @param mname The mode name
+ */
+ virtual void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_abstract;
+ };
+
+ struct CoreExport ChannelModeAdd : Events
+ {
+ static constexpr const char *NAME = "channelmodeadd";
+
+ using Events::Events;
+
+ /** Called when a channel mode is introducted into Anope
+ * @param cm The mode
+ */
+ virtual void OnChannelModeAdd(ChannelMode *cm) anope_abstract;
+ };
+
+ struct CoreExport UserModeAdd : Events
+ {
+ static constexpr const char *NAME = "usermodeadd";
+
+ using Events::Events;
+
+ /** Called when a user mode is introducted into Anope
+ * @param um The mode
+ */
+ virtual void OnUserModeAdd(UserMode *um) anope_abstract;
+ };
+
+ struct CoreExport ModuleLoad : Events
+ {
+ static constexpr const char *NAME = "moduleload";
+
+ using Events::Events;
+
+ /** Called after a module is loaded
+ * @param u The user loading the module, can be NULL
+ * @param m The module
+ */
+ virtual void OnModuleLoad(User *u, Module *m) anope_abstract;
+ };
+
+ struct CoreExport ModuleUnload : Events
+ {
+ static constexpr const char *NAME = "moduleunload";
+
+ using Events::Events;
+
+ /** Called before a module is unloaded
+ * @param u The user, can be NULL
+ * @param m The module
+ */
+ virtual void OnModuleUnload(User *u, Module *m) anope_abstract;
+ };
+
+ struct CoreExport ServerSync : Events
+ {
+ static constexpr const char *NAME = "serversync";
+
+ using Events::Events;
+
+ /** Called when a server is synced
+ * @param s The server, can be our uplink server
+ */
+ virtual void OnServerSync(Server *s) anope_abstract;
+ };
+
+ struct CoreExport UplinkSync : Events
+ {
+ static constexpr const char *NAME = "uplinksync";
+
+ using Events::Events;
+
+ /** Called when we sync with our uplink
+ * @param s Our uplink
+ */
+ virtual void OnUplinkSync(Server *s) anope_abstract;
+ };
+
+ struct CoreExport BotPrivmsg : Events
+ {
+ static constexpr const char *NAME = "botprivmsg";
+
+ using Events::Events;
+
+ /** Called when we receive a PRIVMSG for one of our clients
+ * @param u The user sending the PRIVMSG
+ * @param bi The target of the PRIVMSG
+ * @param message The message
+ * @return EVENT_STOP to halt processing
+ */
+ virtual EventReturn OnBotPrivmsg(User *u, ServiceBot *bi, Anope::string &message) anope_abstract;
+ };
+
+ struct CoreExport BotNotice : Events
+ {
+ static constexpr const char *NAME = "botnotice";
+
+ using Events::Events;
+
+ /** Called when we receive a NOTICE for one of our clients
+ * @param u The user sending the NOTICE
+ * @param bi The target of the NOTICE
+ * @param message The message
+ */
+ virtual void OnBotNotice(User *u, ServiceBot *bi, Anope::string &message) anope_abstract;
+ };
+
+ struct CoreExport Privmsg : Events
+ {
+ static constexpr const char *NAME = "privmsg";
+
+ using Events::Events;
+
+ /** Called when we receive a PRIVMSG for a registered channel we are in
+ * @param u The source of the message
+ * @param c The channel
+ * @param msg The message
+ */
+ virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_abstract;
+ };
+
+ struct CoreExport Log : Events
+ {
+ static constexpr const char *NAME = "log";
+
+ using Events::Events;
+
+ /** Called when a message is logged
+ * @param l The log message
+ */
+ virtual void OnLog(::Log *l) anope_abstract;
+ };
+
+ struct CoreExport LogMessage : Events
+ {
+ static constexpr const char *NAME = "logmessage";
+
+ using Events::Events;
+
+ /** Called when a log message is actually logged to a given log info
+ * The message has already passed validation checks by the LogInfo
+ * @param li The loginfo whee the message is being logged
+ * @param l The log message
+ * @param msg The final formatted message, derived from 'l'
+ */
+ virtual void OnLogMessage(LogInfo *li, const ::Log *l, const Anope::string &msg) anope_abstract;
+ };
+
+ struct CoreExport CheckModes : Events
+ {
+ static constexpr const char *NAME = "checkmodes";
+
+ using Events::Events;
+
+ /** Called when a channels modes are being checked to see if they are allowed,
+ * mostly to ensure mlock/+r are set.
+ * @param c The channel
+ */
+ virtual void OnCheckModes(Reference<Channel> &c) anope_abstract;
+ };
+
+ struct CoreExport ChannelSync : Events
+ {
+ static constexpr const char *NAME = "channelsync";
+
+ using Events::Events;
+
+ /** Called when a channel is synced.
+ * Channels are synced after a sjoin is finished processing
+ * for a newly created channel to set the correct modes, topic,
+ * set.
+ */
+ virtual void OnChannelSync(Channel *c) anope_abstract;
+ };
+
+ struct CoreExport SetCorrectModes : Events
+ {
+ static constexpr const char *NAME = "setcorrectmodes";
+
+ using Events::Events;
+
+ /** Called to set the correct modes on the user on the given channel
+ * @param user The user
+ * @param chan The channel
+ * @param access The user's access on the channel
+ * @param give_modes If giving modes is desired
+ * @param take_modes If taking modes is desired
+ */
+ virtual void OnSetCorrectModes(User *user, Channel *chan, ChanServ::AccessGroup &access, bool &give_modes, bool &take_modes) anope_abstract;
+ };
+
+ struct CoreExport Message : Events
+ {
+ static constexpr const char *NAME = "message";
+
+ using Events::Events;
+
+ /** Called whenever a message is received from the uplink
+ * @param source The source of the message
+ * @param command The command being executed
+ * @param params Parameters
+ * @return EVENT_STOP to prevent the protocol module from processing this message
+ */
+ virtual EventReturn OnMessage(MessageSource &source, Anope::string &command, std::vector<Anope::string> &param) anope_abstract;
+ };
+
+ struct CoreExport CanSet : Events
+ {
+ static constexpr const char *NAME = "canset";
+
+ using Events::Events;
+
+ /** Called to determine if a chnanel mode can be set by a user
+ * @param u The user
+ * @param cm The mode
+ */
+ virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_abstract;
+ };
+
+ struct CoreExport CheckDelete : Events
+ {
+ static constexpr const char *NAME = "checkdelete";
+
+ using Events::Events;
+
+ virtual EventReturn OnCheckDelete(Channel *) anope_abstract;
+ };
+
+ struct CoreExport ExpireTick : Events
+ {
+ static constexpr const char *NAME = "expiretick";
+
+ using Events::Events;
+
+ /** Called every options:expiretimeout seconds. Should be used to expire nicks,
+ * channels, etc.
+ */
+ virtual void OnExpireTick() anope_abstract;
+ };
+
+ struct CoreExport SerializeEvents : Events
+ {
+ static constexpr const char *NAME = "serialize";
+
+ using Events::Events;
+
+ virtual EventReturn OnSerializeList(Serialize::TypeBase *type, std::vector<Serialize::ID> &ids) anope_abstract;
+
+ virtual EventReturn OnSerializeFind(Serialize::TypeBase *type, Serialize::FieldBase *field, const Anope::string &value, Serialize::ID &id) anope_abstract;
+
+ virtual EventReturn OnSerializeGet(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &value) anope_abstract;
+
+ virtual EventReturn OnSerializeGetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &type, Serialize::ID &id) anope_abstract;
+
+ virtual EventReturn OnSerializeGetRefs(Serialize::Object *object, Serialize::TypeBase *type, std::vector<Serialize::Edge> &) anope_abstract;
+
+ virtual EventReturn OnSerializeDeref(Serialize::ID value, Serialize::TypeBase *type) anope_abstract;
+
+ virtual EventReturn OnSerializableGetId(Serialize::ID &id) anope_abstract;
+
+ virtual void OnSerializableDelete(Serialize::Object *) anope_abstract;
+
+ virtual EventReturn OnSerializeSet(Serialize::Object *object, Serialize::FieldBase *field, const Anope::string &value) anope_abstract;
+
+ virtual EventReturn OnSerializeSetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Serialize::Object *value) anope_abstract;
+
+ virtual EventReturn OnSerializeUnset(Serialize::Object *object, Serialize::FieldBase *field) anope_abstract;
+
+ virtual EventReturn OnSerializeUnsetSerializable(Serialize::Object *object, Serialize::FieldBase *field) anope_abstract;
+
+ virtual EventReturn OnSerializeHasField(Serialize::Object *object, Serialize::FieldBase *field) anope_abstract;
+
+ virtual void OnSerializableCreate(Serialize::Object *) anope_abstract;
+ };
+}
diff --git a/include/extensible.h b/include/extensible.h
index aec29a8f6..2e1079631 100644
--- a/include/extensible.h
+++ b/include/extensible.h
@@ -1,16 +1,25 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef EXTENSIBLE_H
-#define EXTENSIBLE_H
+#pragma once
#include "anope.h"
-#include "serialize.h"
#include "service.h"
#include "logger.h"
@@ -22,47 +31,37 @@ class CoreExport ExtensibleBase : public Service
std::map<Extensible *, void *> items;
ExtensibleBase(Module *m, const Anope::string &n);
- ~ExtensibleBase();
+ ExtensibleBase(Module *m, const Anope::string &t, const Anope::string &n);
public:
- virtual void Unset(Extensible *obj) = 0;
-
- /* called when an object we are keep track of is serializing */
- virtual void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &) const { }
- virtual void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &) { }
+ virtual void Unset(Extensible *obj) anope_abstract;
+
+ static constexpr const char *NAME = "Extensible";
};
class CoreExport Extensible
{
public:
- std::set<ExtensibleBase *> extension_items;
+ std::vector<ExtensibleBase *> extension_items;
virtual ~Extensible();
- void UnsetExtensibles();
-
- template<typename T> T* GetExt(const Anope::string &name) const;
- bool HasExt(const Anope::string &name) const;
+ template<typename T> T* GetExt(const Anope::string &name);
+ bool HasExtOK(const Anope::string &name);
template<typename T> T* Extend(const Anope::string &name, const T &what);
- template<typename T> T* Extend(const Anope::string &name);
- template<typename T> T* Require(const Anope::string &name);
- template<typename T> void Shrink(const Anope::string &name);
- static void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &data);
- static void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &data);
+ template<typename T> void Shrink(const Anope::string &name);
};
template<typename T>
-class BaseExtensibleItem : public ExtensibleBase
+class ExtensibleItem : public ExtensibleBase
{
- protected:
- virtual T *Create(Extensible *) = 0;
-
public:
- BaseExtensibleItem(Module *m, const Anope::string &n) : ExtensibleBase(m, n) { }
+ ExtensibleItem(Module *m, const Anope::string &n) : ExtensibleBase(m, n) { }
+ ExtensibleItem(Module *m, const Anope::string &t, const Anope::string &n) : ExtensibleBase(m, t, n) { }
- ~BaseExtensibleItem()
+ ~ExtensibleItem()
{
while (!items.empty())
{
@@ -70,48 +69,49 @@ class BaseExtensibleItem : public ExtensibleBase
Extensible *obj = it->first;
T *value = static_cast<T *>(it->second);
- obj->extension_items.erase(this);
+ auto it2 = std::find(obj->extension_items.begin(), obj->extension_items.end(), this);
+ if (it2 != obj->extension_items.end())
+ obj->extension_items.erase(it2);
items.erase(it);
+
delete value;
}
}
T* Set(Extensible *obj, const T &value)
{
- T* t = Set(obj);
- if (t)
- *t = value;
- return t;
- }
-
- T* Set(Extensible *obj)
- {
- T* t = Create(obj);
+ T* t = new T(value);
Unset(obj);
+
items[obj] = t;
- obj->extension_items.insert(this);
+ obj->extension_items.push_back(this);
+
return t;
}
- void Unset(Extensible *obj) anope_override
+ void Unset(Extensible *obj) override
{
T *value = Get(obj);
+
items.erase(obj);
- obj->extension_items.erase(this);
+ auto it = std::find(obj->extension_items.begin(), obj->extension_items.end(), this);
+ if (it != obj->extension_items.end())
+ obj->extension_items.erase(it);
+
delete value;
}
- T* Get(const Extensible *obj) const
+ T* Get(Extensible *obj)
{
- std::map<Extensible *, void *>::const_iterator it = items.find(const_cast<Extensible *>(obj));
+ std::map<Extensible *, void *>::const_iterator it = items.find(obj);
if (it != items.end())
return static_cast<T *>(it->second);
- return NULL;
+ return nullptr;
}
- bool HasExt(const Extensible *obj) const
+ bool HasExt(Extensible *obj)
{
- return items.find(const_cast<Extensible *>(obj)) != items.end();
+ return items.find(obj) != items.end();
}
T* Require(Extensible *obj)
@@ -120,98 +120,18 @@ class BaseExtensibleItem : public ExtensibleBase
if (t)
return t;
- return Set(obj);
- }
-};
-
-template<typename T>
-class ExtensibleItem : public BaseExtensibleItem<T>
-{
- protected:
- T* Create(Extensible *obj) anope_override
- {
- return new T(obj);
- }
- public:
- ExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { }
-};
-
-template<typename T>
-class PrimitiveExtensibleItem : public BaseExtensibleItem<T>
-{
- protected:
- T* Create(Extensible *obj) anope_override
- {
- return new T();
- }
- public:
- PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<T>(m, n) { }
-};
-
-template<>
-class PrimitiveExtensibleItem<bool> : public BaseExtensibleItem<bool>
-{
- protected:
- bool* Create(Extensible *) anope_override
- {
- return NULL;
+ return Set(obj, T());
}
- public:
- PrimitiveExtensibleItem(Module *m, const Anope::string &n) : BaseExtensibleItem<bool>(m, n) { }
};
template<typename T>
-class SerializableExtensibleItem : public PrimitiveExtensibleItem<T>
+struct ExtensibleRef : ServiceReference<ExtensibleItem<T>>
{
- public:
- SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<T>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- T* t = this->Get(e);
- data[this->name] << *t;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- T t;
- if (data[this->name] >> t)
- this->Set(e, t);
- else
- this->Unset(e);
- }
-};
-
-template<>
-class SerializableExtensibleItem<bool> : public PrimitiveExtensibleItem<bool>
-{
- public:
- SerializableExtensibleItem(Module *m, const Anope::string &n) : PrimitiveExtensibleItem<bool>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- data[this->name] << true;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- bool b = false;
- data[this->name] >> b;
- if (b)
- this->Set(e);
- else
- this->Unset(e);
- }
+ ExtensibleRef(const Anope::string &n) : ServiceReference<ExtensibleItem<T>>(n) { }
};
template<typename T>
-struct ExtensibleRef : ServiceReference<BaseExtensibleItem<T> >
-{
- ExtensibleRef(const Anope::string &n) : ServiceReference<BaseExtensibleItem<T> >("Extensible", n) { }
-};
-
-template<typename T>
-T* Extensible::GetExt(const Anope::string &name) const
+T* Extensible::GetExt(const Anope::string &name)
{
ExtensibleRef<T> ref(name);
if (ref)
@@ -224,33 +144,18 @@ T* Extensible::GetExt(const Anope::string &name) const
template<typename T>
T* Extensible::Extend(const Anope::string &name, const T &what)
{
- T* t = Extend<T>(name);
- if (t)
- *t = what;
- return t;
-}
-
-template<typename T>
-T* Extensible::Extend(const Anope::string &name)
-{
ExtensibleRef<T> ref(name);
if (ref)
- return ref->Set(this);
+ {
+ ref->Set(this, what);
+ return ref->Get(this);
+ }
Log(LOG_DEBUG) << "Extend for nonexistent type " << name << " on " << static_cast<void *>(this);
return NULL;
}
template<typename T>
-T* Extensible::Require(const Anope::string &name)
-{
- if (HasExt(name))
- return GetExt<T>(name);
- else
- return Extend<T>(name);
-}
-
-template<typename T>
void Extensible::Shrink(const Anope::string &name)
{
ExtensibleRef<T> ref(name);
@@ -260,4 +165,3 @@ void Extensible::Shrink(const Anope::string &name)
Log(LOG_DEBUG) << "Shrink for nonexistent type " << name << " on " << static_cast<void *>(this);
}
-#endif // EXTENSIBLE_H
diff --git a/include/hashcomp.h b/include/hashcomp.h
index 4f319c21d..d246bfd2b 100644
--- a/include/hashcomp.h
+++ b/include/hashcomp.h
@@ -1,24 +1,28 @@
/*
+ * Anope IRC Services
*
- * (C) 2002-2011 InspIRCd Development Team
- * (C) 2009-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2002-2011 InspIRCd Development Team
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef HASHCOMP_H
-#define HASHCOMP_H
+#pragma once
#include <string>
#include <locale>
-
-#if defined _LIBCPP_VERSION || defined _WIN32
#include <unordered_map>
-#define TR1NS std
-#else
-#include <tr1/unordered_map>
-#define TR1NS std::tr1
-#endif
#include "services.h"
@@ -26,56 +30,8 @@ namespace Anope
{
class string;
- /* Casemap in use by Anope. ci::string's comparation functions use this (and thus Anope::string) */
- extern std::locale casemap;
-
- extern void CaseMapRebuild();
extern unsigned char tolower(unsigned char);
extern unsigned char toupper(unsigned char);
-
- /* ASCII case insensitive ctype. */
- template<typename char_type>
- class ascii_ctype : public std::ctype<char_type>
- {
- public:
- char_type do_toupper(char_type c) const anope_override
- {
- if (c >= 'a' && c <= 'z')
- return c - 32;
- else
- return c;
- }
-
- char_type do_tolower(char_type c) const anope_override
- {
- if (c >= 'A' && c <= 'Z')
- return c + 32;
- else
- return c;
- }
- };
-
- /* rfc1459 case insensitive ctype, { = [, } = ], and | = \ */
- template<typename char_type>
- class rfc1459_ctype : public ascii_ctype<char_type>
- {
- public:
- char_type do_toupper(char_type c) const anope_override
- {
- if (c == '{' || c == '}' || c == '|')
- return c - 32;
- else
- return ascii_ctype<char_type>::do_toupper(c);
- }
-
- char_type do_tolower(char_type c) const anope_override
- {
- if (c == '[' || c == ']' || c == '\\')
- return c + 32;
- else
- return ascii_ctype<char_type>::do_tolower(c);
- }
- };
}
/** The ci namespace contains a number of helper classes relevant to case insensitive strings.
@@ -196,4 +152,17 @@ inline bool operator!=(const std::string &leftval, const ci::string &rightval)
return !(leftval.c_str() == rightval);
}
-#endif // HASHCOMP_H
+namespace Anope {
+namespace locale {
+
+#ifdef Boost_FOUND
+
+extern std::locale generate(const std::string &);
+extern int compare(const std::string &, const std::string &);
+extern long hash(const std::string &);
+
+#endif
+
+}
+}
+
diff --git a/include/language.h b/include/language.h
index a214ef214..2cfdfe40d 100644
--- a/include/language.h
+++ b/include/language.h
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "anope.h"
@@ -11,7 +22,7 @@
namespace Language
{
- /* Languages we support as configured in services.conf. They are
+ /* Languages we support as configured in anope.conf. They are
* added to this list if we detect a language exists in the correct
* location for each language.
*/
@@ -23,7 +34,7 @@ namespace Language
* and we detect a language file exists for at least one of the supported
* languages for the module, then we add the module's domain (its name)
* here.
- *
+ *
* When strings are translated they are checked against all domains.
*/
extern std::vector<Anope::string> Domains;
@@ -38,6 +49,7 @@ namespace Language
* @return The translated string if found, else the original string.
*/
extern CoreExport const char *Translate(const char *string);
+ extern CoreExport const char *Translate(const Anope::string &string);
/** Translates a string to the language of the given user.
* @param u The user to transate the string for
@@ -45,13 +57,15 @@ namespace Language
* @return The translated string if found, else the original string.
*/
extern CoreExport const char *Translate(User *u, const char *string);
+ extern CoreExport const char *Translate(User *u, const Anope::string &string);
/** Translates a string to the language of the given account.
* @param nc The account to translate the string for
* @param string A string to translate
* @return The translated string if count, else the original string
*/
- extern CoreExport const char *Translate(const NickCore *nc, const char *string);
+ extern CoreExport const char *Translate(NickServ::Account *nc, const char *string);
+ extern CoreExport const char *Translate(NickServ::Account *nc, const Anope::string &string);
/** Translatesa string to the given language.
* @param lang The language to translate to
@@ -62,66 +76,3 @@ namespace Language
} // namespace Language
-/* Commonly used language strings */
-#define MORE_INFO _("\002%s%s HELP %s\002 for more information.")
-#define BAD_USERHOST_MASK _("Mask must be in the form \037user\037@\037host\037.")
-#define BAD_EXPIRY_TIME _("Invalid expiry time.")
-#define USERHOST_MASK_TOO_WIDE _("%s coverage is too wide; Please use a more specific mask.")
-#define READ_ONLY_MODE _("Services are in read-only mode!")
-#define PASSWORD_INCORRECT _("Password incorrect.")
-#define ACCESS_DENIED _("Access denied.")
-#define MORE_OBSCURE_PASSWORD _("Please try again with a more obscure password. Passwords should be at least\n" \
- "five characters long, should not be something easily guessed\n" \
- "(e.g. your real name or your nick), and cannot contain the space or tab characters.")
-#define PASSWORD_TOO_LONG _("Your password is too long. It must not exceed %u characters.")
-#define NICK_NOT_REGISTERED _("Your nick isn't registered.")
-#define NICK_X_NOT_REGISTERED _("Nick \002%s\002 isn't registered.")
-#define NICK_X_NOT_IN_USE _("Nick \002%s\002 isn't currently in use.")
-#define NICK_X_NOT_ON_CHAN _("\002%s\002 is not currently on channel %s.")
-#define NICK_X_SUSPENDED _("Nick %s is currently suspended.")
-#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.")
-#define MAIL_X_INVALID _("\002%s\002 is not a valid e-mail address.")
-#define UNKNOWN _("<unknown>")
-#define NO_EXPIRE _("does not expire")
-#define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.")
-#define NICK_IS_REGISTERED _("This nick is owned by someone else. Please choose another.\n" \
- "(If this is your nick, type \002%s%s IDENTIFY \037password\037\002.)")
-#define NICK_IS_SECURE _("This nickname is registered and protected. If it is your\n" \
- "nick, type \002%s%s IDENTIFY \037password\037\002. Otherwise,\n" \
- "please choose a different nick.")
-#define FORCENICKCHANGE_NOW _("This nickname has been registered; you may not use it.")
-#define NICK_CANNOT_BE_REGISTERED _("Nickname \002%s\002 may not be registered.")
-#define NICK_ALREADY_REGISTERED _("Nickname \002%s\002 is already registered!")
-#define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.")
-#define NICK_CONFIRM_INVALID _("Invalid passcode has been entered, please check the e-mail again, and retry.")
-#define CHAN_NOT_ALLOWED_TO_JOIN _("You are not permitted to be on this channel.")
-#define CHAN_X_INVALID _("Channel %s is not a valid channel.")
-#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_SETTING_CHANGED _("%s for %s set to %s.")
-#define CHAN_SETTING_UNSET _("%s for %s unset.")
-#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
-#define CHAN_INFO_HEADER _("Information for channel \002%s\002:")
-#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except has been removed.")
-#define MEMO_NEW_X_MEMO_ARRIVED _("There is a new memo on channel %s.\n" \
- "Type \002%s%s READ %s %d\002 to read it.")
-#define MEMO_NEW_MEMO_ARRIVED _("You have a new memo from %s.\n" \
- "Type \002%s%s READ %d\002 to read it.")
-#define MEMO_HAVE_NO_MEMOS _("You have no memos.")
-#define MEMO_X_HAS_NO_MEMOS _("%s has no memos.")
-#define MEMO_SEND_DISABLED _("Sorry, memo sending is temporarily disabled.")
-#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.")
-#define BOT_NOT_ON_CHANNEL _("Bot is not on channel \002%s\002.")
-#define HOST_SET_ERROR _("A vHost must be in the format of a valid hostname.")
-#define HOST_SET_IDENT_ERROR _("A vHost ident must be in the format of a valid ident.")
-#define HOST_SET_TOOLONG _("Error! The vHost is too long, please use a hostname shorter than %d characters.")
-#define HOST_SET_IDENTTOOLONG _("Error! The vHost ident is too long, please use an ident shorter than %d characters.")
-#define HOST_NOT_ASSIGNED _("Please contact an Operator to get a vHost assigned to this nick.")
-#define HOST_NO_VIDENT _("Your IRCd does not support vIdent's, if this is incorrect, please report this as a possible bug")
diff --git a/include/lists.h b/include/lists.h
index 594f2c5ad..f5014933d 100644
--- a/include/lists.h
+++ b/include/lists.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef LISTS_H
-#define LISTS_H
+#pragma once
#include "services.h"
#include "anope.h"
@@ -24,39 +31,16 @@
*/
class CoreExport NumberList
{
- private:
- bool is_valid;
-
- std::set<unsigned> numbers;
+ std::function<void(void)> endf;
- bool desc;
public:
/** Processes a numbered list
* @param list The list
- * @param descending True to make HandleNumber get called with numbers in descending order
+ * @param descending True to call the number handler callback with the numbers in descending order
*/
- NumberList(const Anope::string &list, bool descending);
+ NumberList(const Anope::string &list, bool descending, std::function<void(unsigned int)> nf, std::function<void(void)> ef);
- /** Destructor, does nothing
- */
- virtual ~NumberList();
-
- /** Should be called after the constructors are done running. This calls the callbacks.
- */
- void Process();
-
- /** Called with a number from the list
- * @param number The number
- */
- virtual void HandleNumber(unsigned number);
-
- /** Called when there is an error with the numbered list
- * Return false to immediately stop processing the list and return
- * This is all done before we start calling HandleNumber, so no numbers will have been processed yet
- * @param list The list
- * @return false to stop processing
- */
- virtual bool InvalidRange(const Anope::string &list);
+ ~NumberList();
};
/** This class handles formatting LIST/VIEW replies.
@@ -66,11 +50,11 @@ class CoreExport ListFormatter
public:
typedef std::map<Anope::string, Anope::string> ListEntry;
private:
- NickCore *nc;
+ NickServ::Account *nc;
std::vector<Anope::string> columns;
std::vector<ListEntry> entries;
public:
- ListFormatter(NickCore *nc);
+ ListFormatter(NickServ::Account *nc);
ListFormatter &AddColumn(const Anope::string &name);
void AddEntry(const ListEntry &entry);
bool IsEmpty() const;
@@ -81,14 +65,13 @@ class CoreExport ListFormatter
*/
class CoreExport InfoFormatter
{
- NickCore *nc;
+ NickServ::Account *nc;
std::vector<std::pair<Anope::string, Anope::string> > replies;
unsigned longest;
public:
- InfoFormatter(NickCore *nc);
+ InfoFormatter(NickServ::Account *nc);
void Process(std::vector<Anope::string> &);
Anope::string &operator[](const Anope::string &key);
void AddOption(const Anope::string &opt);
};
-#endif // LISTS_H
diff --git a/include/logger.h b/include/logger.h
index 349ca5a55..f3b00068b 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef LOGGER_H
-#define LOGGER_H
+#pragma once
#include "anope.h"
#include "defs.h"
@@ -53,11 +60,11 @@ class CoreExport Log
{
public:
/* Bot that should log this message */
- BotInfo *bi;
+ ServiceBot *bi;
/* For commands, the user executing the command, but might not always exist */
User *u;
/* For commands, the account executing the command, but will not always exist */
- NickCore *nc;
+ NickServ::Account *nc;
/* For commands, the command being executed */
Command *c;
/* For commands, the command source */
@@ -65,7 +72,7 @@ class CoreExport Log
/* Used for LOG_CHANNEL */
Channel *chan;
/* For commands, the channel the command was executed on, will not always exist */
- const ChannelInfo *ci;
+ ChanServ::Channel *ci;
/* For LOG_SERVER */
Server *s;
/* For LOG_MODULE */
@@ -75,23 +82,23 @@ class CoreExport Log
std::stringstream buf;
- Log(LogType type = LOG_NORMAL, const Anope::string &category = "", BotInfo *bi = NULL);
+ Log(LogType type = LOG_NORMAL, const Anope::string &category = "", ServiceBot *bi = NULL);
/* LOG_COMMAND/OVERRIDE/ADMIN */
- Log(LogType type, CommandSource &source, Command *c, ChannelInfo *ci = NULL);
+ Log(LogType type, CommandSource &source, Command *c, ChanServ::Channel *ci = NULL);
/* LOG_CHANNEL */
Log(User *u, Channel *c, const Anope::string &category = "");
/* LOG_USER */
- Log(User *u, const Anope::string &category = "", BotInfo *bi = NULL);
+ Log(User *u, const Anope::string &category = "", ServiceBot *bi = NULL);
/* LOG_SERVER */
- Log(Server *s, const Anope::string &category = "", BotInfo *bi = NULL);
+ Log(Server *s, const Anope::string &category = "", ServiceBot *bi = NULL);
- Log(BotInfo *b, const Anope::string &category = "");
+ Log(ServiceBot *b, const Anope::string &category = "");
- Log(Module *m, const Anope::string &category = "", BotInfo *bi = NULL);
+ Log(Module *m, const Anope::string &category = "", ServiceBot *bi = NULL);
~Log();
@@ -113,7 +120,7 @@ class CoreExport Log
class CoreExport LogInfo
{
public:
- BotInfo *bot;
+ ServiceBot *bot;
std::vector<Anope::string> targets;
std::vector<LogFile *> logfiles;
int last_day;
@@ -141,4 +148,3 @@ class CoreExport LogInfo
void ProcessMessage(const Log *l);
};
-#endif // LOGGER_H
diff --git a/include/mail.h b/include/mail.h
index 4b3aaa9bd..911c2011d 100644
--- a/include/mail.h
+++ b/include/mail.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef MAIL_H
-#define MAIL_H
+#pragma once
#include "anope.h"
#include "threadengine.h"
@@ -18,8 +25,8 @@
namespace Mail
{
- extern CoreExport bool Send(User *from, NickCore *to, BotInfo *service, const Anope::string &subject, const Anope::string &message);
- extern CoreExport bool Send(NickCore *to, const Anope::string &subject, const Anope::string &message);
+ extern CoreExport bool Send(User *from, NickServ::Account *to, ServiceBot *service, const Anope::string &subject, const Anope::string &message);
+ extern CoreExport bool Send(NickServ::Account *to, const Anope::string &subject, const Anope::string &message);
extern CoreExport bool Validate(const Anope::string &email);
/* A email message being sent */
@@ -48,9 +55,8 @@ namespace Mail
~Message();
/* Called from within the thread to actually send the mail */
- void Run() anope_override;
+ void Run() override;
};
} // namespace Mail
-#endif // MAIL_H
diff --git a/include/memo.h b/include/memo.h
deleted file mode 100644
index 5d92b6566..000000000
--- a/include/memo.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- * (C) 2003-2016 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.
- */
-
-#ifndef MEMO_H
-#define MEMO_H
-
-#include "anope.h"
-#include "serialize.h"
-
-class CoreExport Memo : public Serializable
-{
- public:
- MemoInfo *mi;
- bool unread;
- bool receipt;
- Memo();
- ~Memo();
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-
- Anope::string owner;
- /* When it was sent */
- time_t time;
- Anope::string sender;
- Anope::string text;
-};
-
-/* Memo info structures. Since both nicknames and channels can have memos,
- * we encapsulate memo data in a MemoInfo to make it easier to handle.
- */
-struct CoreExport MemoInfo
-{
- int16_t memomax;
- Serialize::Checker<std::vector<Memo *> > memos;
- std::vector<Anope::string> ignores;
-
- MemoInfo();
- Memo *GetMemo(unsigned index) const;
- unsigned GetIndex(Memo *m) const;
- void Del(unsigned index);
- bool HasIgnore(User *u);
-
- static MemoInfo *GetMemoInfo(const Anope::string &targ, bool &is_chan);
-};
-
-#endif // MEMO_H
diff --git a/include/messages.h b/include/messages.h
index dde8a506e..9c0b7f862 100644
--- a/include/messages.h
+++ b/include/messages.h
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2004-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "protocol.h"
@@ -22,39 +30,39 @@ namespace Message
struct CoreExport Away : IRCDMessage
{
Away(Module *creator, const Anope::string &mname = "AWAY") : IRCDMessage(creator, mname, 0) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Capab : IRCDMessage
{
Capab(Module *creator, const Anope::string &mname = "CAPAB") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Error : IRCDMessage
{
Error(Module *creator, const Anope::string &mname = "ERROR") : IRCDMessage(creator, mname, 1) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
struct CoreExport Invite : IRCDMessage
{
Invite(Module *creator, const Anope::string &mname = "INVITE") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Join : IRCDMessage
{
Join(Module *creator, const Anope::string &mname = "JOIN") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
-
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+
typedef std::pair<ChannelStatus, User *> SJoinUser;
-
+
/** Handle a SJOIN.
* @param source The source of the SJOIN
* @param chan The channel the users are joining to
@@ -64,110 +72,110 @@ namespace Message
*/
static void SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users);
};
-
+
struct CoreExport Kick : IRCDMessage
{
Kick(Module *creator, const Anope::string &mname = "KICK") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Kill : IRCDMessage
{
Kill(Module *creator, const Anope::string &mname = "KILL") : IRCDMessage(creator, mname, 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
struct CoreExport Mode : IRCDMessage
{
Mode(Module *creator, const Anope::string &mname = "MODE") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport MOTD : IRCDMessage
{
MOTD(Module *creator, const Anope::string &mname = "MOTD") : IRCDMessage(creator, mname, 1) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Notice : IRCDMessage
{
Notice(Module *creator, const Anope::string &mname = "NOTICE") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
struct CoreExport Part : IRCDMessage
{
Part(Module *creator, const Anope::string &mname = "PART") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Ping : IRCDMessage
{
Ping(Module *creator, const Anope::string &mname = "PING") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Privmsg : IRCDMessage
{
Privmsg(Module *creator, const Anope::string &mname = "PRIVMSG") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Quit : IRCDMessage
{
Quit(Module *creator, const Anope::string &mname = "QUIT") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport SQuit : IRCDMessage
{
SQuit(Module *creator, const Anope::string &mname = "SQUIT") : IRCDMessage(creator, mname, 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Stats : IRCDMessage
{
Stats(Module *creator, const Anope::string &mname = "STATS") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Time : IRCDMessage
{
Time(Module *creator, const Anope::string &mname = "TIME") : IRCDMessage(creator, mname, 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Topic : IRCDMessage
{
Topic(Module *creator, const Anope::string &mname = "TOPIC") : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Version : IRCDMessage
{
Version(Module *creator, const Anope::string &mname = "VERSION") : IRCDMessage(creator, mname, 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
-
+
struct CoreExport Whois : IRCDMessage
{
Whois(Module *creator, const Anope::string &mname = "WHOIS") : IRCDMessage(creator, mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override;
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
};
} // namespace Message
diff --git a/include/modes.h b/include/modes.h
index 03f6f8a58..706b0b716 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -1,13 +1,24 @@
-/* Mode support
+/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Adam <Adam@anope.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Adam <Adam@anope.org>
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef MODES_H
-#define MODES_H
+#pragma once
#include "anope.h"
#include "base.h"
@@ -48,6 +59,9 @@ class CoreExport Mode : public Base
/* Type of mode this is, eg MODE_LIST */
ModeType type;
+ bool setable = true;
+ bool oper_only = false;
+
/** constructor
* @param mname The mode name
* @param mclass The type of mode this is
@@ -57,6 +71,9 @@ class CoreExport Mode : public Base
Mode(const Anope::string &mname, ModeClass mclass, char mc, ModeType type);
virtual ~Mode();
+ void SetSetable(bool b) { setable = b; }
+ void SetOperOnly(bool b) { oper_only = b; }
+
/** Can a user set this mode, used for mlock
* @param u The user
*/
@@ -105,7 +122,7 @@ class CoreExport ChannelMode : public Mode
*/
ChannelMode(const Anope::string &name, char mc);
- bool CanSet(User *u) const anope_override;
+ bool CanSet(User *u) const override;
virtual void Check() { }
@@ -146,18 +163,6 @@ class CoreExport ChannelModeList : public ChannelMode
* @return true on match
*/
virtual bool Matches(User *u, const Entry *e) { return false; }
-
- /** Called when a mask is added to a channel
- * @param chan The channel
- * @param mask The mask
- */
- virtual void OnAdd(Channel *chan, const Anope::string &mask) { }
-
- /** Called when a mask is removed from a channel
- * @param chan The channel
- * @param mask The mask
- */
- virtual void OnDel(Channel *chan, const Anope::string &mask) { }
};
/** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this
@@ -175,11 +180,13 @@ class CoreExport ChannelModeParam : public ChannelMode
/* Should we send an arg when unsetting this mode? */
bool minus_no_arg;
+ std::regex param_validation;
+
/** Is the param valid
* @param value The param
* @return true for yes, false for no
*/
- virtual bool IsValid(Anope::string &value) const { return true; }
+ virtual bool IsValid(Anope::string &value) const;
};
/** This is a mode that is a channel status, eg +v/h/o/a/q.
@@ -197,7 +204,7 @@ class CoreExport ChannelModeStatus : public ChannelMode
/** constructor
* @param name The mode name
* @param mc The mode char
- * @param msymbol The symbol for the mode, eg @ %
+ * @param msymbol The symbol for the mode, eg @ %
* @param mlevel A level for the mode, which is usually determined by the PREFIX capab
*/
ChannelModeStatus(const Anope::string &name, char mc, char msymbol, short mlevel);
@@ -217,11 +224,11 @@ class CoreExport ChannelModeVirtual : public T
~ChannelModeVirtual();
- void Check() anope_override;
+ void Check() override;
- ChannelMode *Wrap(Anope::string &param) anope_override;
+ ChannelMode *Wrap(Anope::string &param) override;
- ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) = 0;
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) override anope_abstract;
};
/* The status a user has on a channel (+v, +h, +o) etc */
@@ -240,53 +247,6 @@ class CoreExport ChannelStatus
Anope::string BuildModePrefixList() const;
};
-class CoreExport UserModeOperOnly : public UserMode
-{
- public:
- UserModeOperOnly(const Anope::string &mname, char um) : UserMode(mname, um) { }
-
- bool CanSet(User *u) const anope_override;
-};
-
-class CoreExport UserModeNoone : public UserMode
-{
- public:
- UserModeNoone(const Anope::string &mname, char um) : UserMode(mname, um) { }
-
- bool CanSet(User *u) const anope_override;
-};
-
-/** Channel mode +k (key)
- */
-class CoreExport ChannelModeKey : public ChannelModeParam
-{
- public:
- ChannelModeKey(char mc) : ChannelModeParam("KEY", mc) { }
-
- bool IsValid(Anope::string &value) const anope_override;
-};
-
-/** This class is used for oper only channel modes
- */
-class CoreExport ChannelModeOperOnly : public ChannelMode
-{
- public:
- ChannelModeOperOnly(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { }
-
- /* Opers only */
- bool CanSet(User *u) const anope_override;
-};
-
-/** This class is used for channel modes only servers may set
- */
-class CoreExport ChannelModeNoone : public ChannelMode
-{
- public:
- ChannelModeNoone(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { }
-
- bool CanSet(User *u) const anope_override;
-};
-
/** This is the mode manager
* It contains functions for adding modes to Anope so Anope can track them
* and do things such as MLOCK.
@@ -296,11 +256,6 @@ class CoreExport ChannelModeNoone : public ChannelMode
class CoreExport ModeManager
{
public:
-
- /* Number of generic channel and user modes we are tracking */
- static unsigned GenericChannelModes;
- static unsigned GenericUserModes;
-
/** Add a user mode to Anope
* @param um A UserMode or UserMode derived class
* @return true on success, false on error
@@ -365,7 +320,7 @@ class CoreExport ModeManager
* @param set true for setting, false for removing
* @param param The param, if there is one
*/
- static void StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool set, const Anope::string &param = "");
+ static void StackerAdd(User *bi, Channel *c, ChannelMode *cm, bool set, const Anope::string &param = "");
/** Add a mode to the stacker to be set on a user
* @param bi The client to set the modes from
@@ -374,7 +329,7 @@ class CoreExport ModeManager
* @param set true for setting, false for removing
* @param param The param, if there is one
*/
- static void StackerAdd(BotInfo *bi, User *u, UserMode *um, bool set, const Anope::string &param = "");
+ static void StackerAdd(User *bi, User *u, UserMode *um, bool set, const Anope::string &param = "");
/** Process all of the modes in the stacker and send them to the IRCd to be set on channels/users
*/
@@ -385,6 +340,8 @@ class CoreExport ModeManager
static void StackerDel(User *u);
static void StackerDel(Channel *c);
static void StackerDel(Mode *m);
+
+ static void Apply(Configuration::Conf *old);
};
/** Represents a mask set on a channel (b/e/I)
@@ -395,7 +352,7 @@ class CoreExport Entry
Anope::string mask;
public:
unsigned short cidr_len;
- int family;
+ int family = 0;
Anope::string nick, user, host, real;
/** Constructor
@@ -418,5 +375,3 @@ class CoreExport Entry
*/
bool Matches(User *u, bool full = false) const;
};
-
-#endif // MODES_H
diff --git a/include/module.h b/include/module.h
index c8abe21f4..e761dd822 100644
--- a/include/module.h
+++ b/include/module.h
@@ -1,39 +1,42 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef MODULE_H
-#define MODULE_H
+#pragma once
-#include "access.h"
-#include "account.h"
#include "anope.h"
#include "base.h"
#include "bots.h"
#include "channels.h"
#include "commands.h"
#include "config.h"
+#include "event.h"
#include "extensible.h"
#include "hashcomp.h"
#include "language.h"
#include "lists.h"
#include "logger.h"
#include "mail.h"
-#include "memo.h"
#include "messages.h"
#include "modes.h"
#include "modules.h"
#include "opertype.h"
#include "protocol.h"
-#include "regexpr.h"
-#include "regchannel.h"
#include "serialize.h"
#include "servers.h"
#include "service.h"
@@ -46,9 +49,8 @@
#include "users.h"
#include "xline.h"
-#include "modules/pseudoclients/chanserv.h"
-#include "modules/pseudoclients/global.h"
-#include "modules/pseudoclients/memoserv.h"
-#include "modules/pseudoclients/nickserv.h"
-
-#endif // MODULE_H
+#include "modules/chanserv.h"
+#include "modules/nickserv.h"
+#include "modules/botserv.h"
+#include "modules/memoserv.h"
+#include "accessgroup.h"
diff --git a/include/modules.h b/include/modules.h
index 52fc4c676..ff9303c4f 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -1,19 +1,25 @@
-/* Modular support
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#include "serialize.h"
-
-#ifndef MODULES_H
-#define MODULES_H
+#pragma once
+#include "serialize.h"
#include "base.h"
#include "modes.h"
#include "timers.h"
@@ -21,133 +27,81 @@
#include "extensible.h"
#include "version.h"
+class ModuleDef;
+struct ModuleVersionC;
+
+enum
+{
+ ANOPE_MODAPI_VER = 1
+};
+
+struct AnopeModule
+{
+ unsigned int api_version;
+ ModuleDef* (*init)();
+ void (*fini)(ModuleDef *);
+ ModuleVersionC (*version)();
+};
+
+class ModuleDef
+{
+ std::vector<Anope::string> dependencies;
+
+ public:
+ virtual ~ModuleDef() = default;
+ virtual Module *Create(const Anope::string &modname, const Anope::string &creator) anope_abstract;
+ virtual void Destroy(Module *) anope_abstract;
+ virtual void BuildModuleInfo() anope_abstract;
+
+ void Depends(const Anope::string &modname);
+ const std::vector<Anope::string> &GetDependencies();
+};
+
+template<class ModuleClass> void ModuleInfo(ModuleDef *moddef) { }
+
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
- * It defines the class factory and external AnopeInit and AnopeFini functions.
*/
-#ifdef _WIN32
-# define MODULE_INIT(x) \
- extern "C" DllExport Module *AnopeInit(const Anope::string &, const Anope::string &); \
- extern "C" Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \
+#define MODULE_INIT(ModuleClass) \
+ class ModuleClass ## ModuleDef : public ModuleDef \
{ \
- return new x(modname, creator); \
- } \
- BOOLEAN WINAPI DllMain(HINSTANCE, DWORD, LPVOID) \
+ Module *Create(const Anope::string &modname, const Anope::string &creator) override \
+ { \
+ return new ModuleClass(modname, creator); \
+ } \
+ void Destroy(Module *module) override \
+ { \
+ delete module; \
+ } \
+ void BuildModuleInfo() override \
+ { \
+ ModuleInfo<ModuleClass>(this); \
+ } \
+ }; \
+ static ModuleDef *CreateModuleDef() \
{ \
- return TRUE; \
+ return new ModuleClass ## ModuleDef(); \
} \
- extern "C" DllExport void AnopeFini(x *); \
- extern "C" void AnopeFini(x *m) \
+ static void DeleteModuleDef(ModuleDef *def) \
{ \
- delete m; \
+ delete def; \
} \
- extern "C" DllExport ModuleVersionC AnopeVersion() \
+ static ModuleVersionC AnopeModuleVersion() \
{ \
ModuleVersionC ver; \
ver.version_major = VERSION_MAJOR; \
ver.version_minor = VERSION_MINOR; \
ver.version_patch = VERSION_PATCH; \
return ver; \
- }
-#else
-# define MODULE_INIT(x) \
- extern "C" DllExport Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \
- { \
- return new x(modname, creator); \
- } \
- extern "C" DllExport void AnopeFini(x *m) \
- { \
- delete m; \
} \
- extern "C" DllExport ModuleVersionC AnopeVersion() \
+ extern "C" DllExport struct AnopeModule AnopeMod; \
+ struct AnopeModule AnopeMod = \
{ \
- ModuleVersionC ver; \
- ver.version_major = VERSION_MAJOR; \
- ver.version_minor = VERSION_MINOR; \
- ver.version_patch = VERSION_PATCH; \
- return ver; \
- }
-#endif
-
-/**
- * This #define allows us to call a method in all
- * loaded modules in a readable simple way, e.g.:
- *
- * FOREACH_MOD(OnUserConnect, (user, exempt));
- */
-#define FOREACH_MOD(ename, args) \
-if (true) \
-{ \
- std::vector<Module *> &_modules = ModuleManager::EventHandlers[I_ ## ename]; \
- for (std::vector<Module *>::iterator _i = _modules.begin(); _i != _modules.end();) \
- { \
- try \
- { \
- (*_i)->ename args; \
- } \
- catch (const ModuleException &modexcept) \
- { \
- Log() << "Exception caught: " << modexcept.GetReason(); \
- } \
- catch (const NotImplementedException &) \
- { \
- _i = _modules.erase(_i); \
- continue; \
- } \
- ++_i; \
- } \
-} \
-else \
- static_cast<void>(0)
-
-/**
- * This define is similar to the one above but returns a result.
- * The first module to return a result other than EVENT_CONTINUE is the value to be accepted,
- * and any modules after are ignored. This is used like:
- *
- * EventReturn MOD_RESULT;
- * FOREACH_RESULT(OnUserConnect, MOD_RESULT, (user, exempt));
- */
-#define FOREACH_RESULT(ename, ret, args) \
-if (true) \
-{ \
- ret = EVENT_CONTINUE; \
- std::vector<Module *> &_modules = ModuleManager::EventHandlers[I_ ## ename]; \
- for (std::vector<Module *>::iterator _i = _modules.begin(); _i != _modules.end();) \
- { \
- try \
- { \
- EventReturn res = (*_i)->ename args; \
- if (res != EVENT_CONTINUE) \
- { \
- ret = res; \
- break; \
- } \
- } \
- catch (const ModuleException &modexcept) \
- { \
- Log() << "Exception caught: " << modexcept.GetReason(); \
- } \
- catch (const NotImplementedException &) \
- { \
- _i = _modules.erase(_i); \
- continue; \
- } \
- ++_i; \
- } \
-} \
-else \
- static_cast<void>(0)
-
-
-/** Possible return types from events.
- */
-enum EventReturn
-{
- EVENT_STOP,
- EVENT_CONTINUE,
- EVENT_ALLOW
-};
+ ANOPE_MODAPI_VER, \
+ CreateModuleDef, \
+ DeleteModuleDef, \
+ AnopeModuleVersion \
+ };
enum ModuleReturn
{
@@ -162,9 +116,6 @@ enum ModuleReturn
MOD_ERR_VERSION
};
-/** Priority types which can be returned from Module::Prioritize()
- */
-enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
/* Module types, in the order in which they are unloaded. The order these are in is IMPORTANT */
enum
{
@@ -223,8 +174,6 @@ class ModuleVersion
int GetPatch() const;
};
-class NotImplementedException : public CoreException { };
-
/** Every module in Anope is actually a class.
*/
class CoreExport Module : public Extensible
@@ -248,6 +197,9 @@ class CoreExport Module : public Extensible
*/
void *handle;
+ ModuleDef *def = nullptr;
+ AnopeModule *module = nullptr;
+
/** Time this module was created
*/
time_t created;
@@ -295,832 +247,13 @@ class CoreExport Module : public Extensible
*/
void SetAuthor(const Anope::string &author);
- virtual void Prioritize();
-
- /* Everything below here are events. Modules must ModuleManager::Attach to these events
- * before they will be called.
- */
-
- /** Called before a user has been kicked from a channel.
- * @param source The kicker
- * @param cu The user, channel, and status of the user being kicked
- * @param kickmsg The reason for the kick.
- */
- virtual void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) { throw NotImplementedException(); }
-
- /** Called when a user has been kicked from a channel.
- * @param source The kicker
- * @param target The user being kicked
- * @param channel The channel the user was kicked from, which may no longer exist
- * @param status The status the kicked user had on the channel before they were kicked
- * @param kickmsg The reason for the kick.
- */
- virtual void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) { throw NotImplementedException(); }
-
- /** Called when Services' configuration is being (re)loaded.
- * @param conf The config that is being built now and will replace the global Config object
- * @throws A ConfigException to abort the config (re)loading process.
- */
- virtual void OnReload(Configuration::Conf *conf) { throw NotImplementedException(); }
-
- /** Called before a bot is assigned to a channel.
- * @param sender The user assigning the bot
- * @param ci The channel the bot is to be assigned to.
- * @param bi The bot being assigned.
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the assign.
- */
- virtual EventReturn OnPreBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called when a bot is assigned ot a channel
- */
- virtual void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called before a bot is unassigned from a channel.
- * @param sender The user unassigning the bot
- * @param ci The channel the bot is being removed from
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the unassign.
- */
- virtual EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a new user connects to the network.
- * @param u The connecting user.
- * @param exempt set to true/is true if the user should be excepted from bans etc
- */
- virtual void OnUserConnect(User *u, bool &exempt) { throw NotImplementedException(); }
-
- /** Called when a new server connects to the network.
- * @param s The server that has connected to the network
- */
- virtual void OnNewServer(Server *s) { throw NotImplementedException(); }
-
- /** Called after a user changed the nick
- * @param u The user.
- * @param oldnick The old nick of the user
- */
- virtual void OnUserNickChange(User *u, const Anope::string &oldnick) { throw NotImplementedException(); }
-
- /** Called when someone uses the generic/help command
- * @param source Command source
- * @param params Params
- * @return EVENT_STOP to stop processing
- */
- virtual EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
-
- /** 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) { throw NotImplementedException(); }
-
- /** Called before a command is due to be executed.
- * @param source The source of the command
- * @param command The command the user is executing
- * @param params The parameters the user is sending
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
- */
- virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) { throw NotImplementedException(); }
-
- /** Called after a command has been executed.
- * @param source The source of the command
- * @param command The command the user executed
- * @param params The parameters the user sent
- */
- virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
-
- /** Called when the databases are saved
- */
- virtual void OnSaveDatabase() { throw NotImplementedException(); }
-
- /** Called when the databases are loaded
- * @return EVENT_CONTINUE to let other modules continue loading, EVENT_STOP to stop
- */
- virtual EventReturn OnLoadDatabase() { throw NotImplementedException(); }
-
- /** Called when anope needs to check passwords against encryption
- * see src/encrypt.c for detailed informations
- */
- virtual EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) { throw NotImplementedException(); }
- virtual EventReturn OnDecrypt(const Anope::string &hashm, const Anope::string &src, Anope::string &dest) { throw NotImplementedException(); }
-
- /** Called on fantasy command
- * @param source The source of the command
- * @param c The command
- * @param ci The channel it's being used in
- * @param params The params
- * @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
- */
- virtual EventReturn OnBotFantasy(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
-
- /** Called on fantasy command without access
- * @param source The source of the command
- * @param c The command
- * @param ci The channel it's being used in
- * @param params The params
- * @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
- */
- virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
-
- /** Called when a bot places a ban
- * @param u User being banned
- * @param ci Channel the ban is placed on
- * @param mask The mask being banned
- */
- virtual void OnBotBan(User *u, ChannelInfo *ci, const Anope::string &mask) { throw NotImplementedException(); }
-
- /** Called before a badword is added to the badword list
- * @param ci The channel
- * @param bw The badword
- */
- virtual void OnBadWordAdd(ChannelInfo *ci, const BadWord *bw) { throw NotImplementedException(); }
-
- /** Called before a badword is deleted from a channel
- * @param ci The channel
- * @param bw The badword
- */
- virtual void OnBadWordDel(ChannelInfo *ci, const BadWord *bw) { throw NotImplementedException(); }
-
- /** Called when a bot is created or destroyed
- */
- virtual void OnCreateBot(BotInfo *bi) { throw NotImplementedException(); }
- virtual void OnDelBot(BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called before a bot kicks a user
- * @param bi The bot sending the kick
- * @param c The channel the user is being kicked on
- * @param u The user being kicked
- * @param reason The reason
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
- */
- virtual EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason) { throw NotImplementedException(); }
-
- /** Called before a user parts a channel
- * @param u The user
- * @param c The channel
- */
- virtual void OnPrePartChannel(User *u, Channel *c) {}
-
- /** Called when a user parts a channel
- * @param u The user
- * @param c The channel, may be NULL if the channel no longer exists
- * @param channel The channel name
- * @param msg The part reason
- */
- virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) { throw NotImplementedException(); }
-
- /** Called when a user leaves a channel.
- * From either parting, being kicked, or quitting/killed!
- * @param u The user
- * @param c The channel
- */
- virtual void OnLeaveChannel(User *u, Channel *c) { throw NotImplementedException(); }
-
- /** Called after a user joins a channel
- * If this event triggers the user is allowed to be in the channel, and will
- * not be kicked for restricted/akick/forbidden, etc. If you want to kick the user,
- * use the CheckKick event instead.
- * @param u The user
- * @param channel The channel
- */
- virtual void OnJoinChannel(User *u, Channel *c) { throw NotImplementedException(); }
-
- /** Called when a new topic is set
- * @param source The user changing the topic, if any
- * @param c The channel
- * @param setter The user who set the new topic, if there is no source
- * @param topic The new topic
- */
- virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) { throw NotImplementedException(); }
-
- /** Called before a channel expires
- * @param ci The channel
- * @param expire Set to true to allow the chan to expire
- */
- virtual void OnPreChanExpire(ChannelInfo *ci, bool &expire) { throw NotImplementedException(); }
-
- /** Called before a channel expires
- * @param ci The channel
- */
- virtual void OnChanExpire(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called before Anope connecs to its uplink
- */
- virtual void OnPreServerConnect() { throw NotImplementedException(); }
-
- /** Called when Anope connects to its uplink
- */
- virtual void OnServerConnect() { throw NotImplementedException(); }
-
- /** Called when we are almost done synching with the uplink, just before we send the EOB
- */
- virtual void OnPreUplinkSync(Server *serv) { throw NotImplementedException(); }
-
- /** Called when Anope disconnects from its uplink, before it tries to reconnect
- */
- virtual void OnServerDisconnect() { throw NotImplementedException(); }
-
- /** Called when services restart
- */
- virtual void OnRestart() { throw NotImplementedException(); }
-
- /** Called when services shutdown
- */
- virtual void OnShutdown() { throw NotImplementedException(); }
-
- /** Called before a nick expires
- * @param na The nick
- * @param expire Set to true to allow the nick to expire
- */
- virtual void OnPreNickExpire(NickAlias *na, bool &expire) { throw NotImplementedException(); }
-
- /** Called when a nick drops
- * @param na The nick
- */
- virtual void OnNickExpire(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when defcon level changes
- * @param level The level
- */
- virtual void OnDefconLevel(int level) { throw NotImplementedException(); }
-
- /** 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
- */
- virtual EventReturn OnExceptionAdd(Exception *ex) { throw NotImplementedException(); }
-
- /** Called before an exception is deleted
- * @param source The source deleting it
- * @param ex The exceotion
- */
- virtual void OnExceptionDel(CommandSource &source, Exception *ex) { throw NotImplementedException(); }
-
- /** Called before a XLine is added
- * @param source The source of 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(CommandSource &source, const XLine *x, XLineManager *xlm) { throw NotImplementedException(); }
-
- /** Called before a XLine is deleted
- * @param source The source of the XLine
- * @param x The XLine
- * @param xlm The xline manager it was deleted from
- */
- virtual void OnDelXLine(CommandSource &source, const XLine *x, XLineManager *xlm) { throw NotImplementedException(); }
-
- /** Called when a user is checked for whether they are a services oper
- * @param u The user
- * @return EVENT_ALLOW to allow, anything else to deny
- */
- virtual EventReturn IsServicesOper(User *u) { throw NotImplementedException(); }
-
- /** Called when a server quits
- * @param server The server
- */
- virtual void OnServerQuit(Server *server) { throw NotImplementedException(); }
-
- /** Called when a user quits, or is killed
- * @param u The user
- * @param msg The quit message
- */
- virtual void OnUserQuit(User *u, const Anope::string &msg) { throw NotImplementedException(); }
-
- /** Called when a user is quit, before and after being internally removed from
- * This is different from OnUserQuit, which takes place at the time of the quit.
- * This happens shortly after when all message processing is finished.
- * all lists (channels, user list, etc)
- * @param u The user
- */
- virtual void OnPreUserLogoff(User *u) { throw NotImplementedException(); }
- virtual void OnPostUserLogoff(User *u) { throw NotImplementedException(); }
-
- /** Called when a new bot is made
- * @param bi The bot
- */
- virtual void OnBotCreate(BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called when a bot is changed
- * @param bi The bot
- */
- virtual void OnBotChange(BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called when a bot is deleted
- * @param bi The bot
- */
- virtual void OnBotDelete(BotInfo *bi) { throw NotImplementedException(); }
-
- /** Called after an access entry is deleted from a channel
- * @param ci The channel
- * @param source The source of the command
- * @param access The access entry that was removed
- */
- virtual void OnAccessDel(ChannelInfo *ci, CommandSource &source, ChanAccess *access) { throw NotImplementedException(); }
-
- /** Called when access is added
- * @param ci The channel
- * @param source The source of the command
- * @param access The access changed
- */
- virtual void OnAccessAdd(ChannelInfo *ci, CommandSource &source, ChanAccess *access) { throw NotImplementedException(); }
-
- /** Called when the access list is cleared
- * @param ci The channel
- * @param u The user who cleared the access
- */
- virtual void OnAccessClear(ChannelInfo *ci, CommandSource &source) { throw NotImplementedException(); }
-
- /** Called when a level for a channel is changed
- * @param source The source of the command
- * @param ci The channel the level was changed on
- * @param priv The privilege changed
- * @param what The new level
- */
- virtual void OnLevelChange(CommandSource &source, ChannelInfo *ci, const Anope::string &priv, int16_t what) { throw NotImplementedException(); }
-
- /** Called right before a channel is dropped
- * @param source The user dropping the channel
- * @param ci The channel
- */
- virtual EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a channel is registered
- * @param ci The channel
- */
- virtual void OnChanRegistered(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a channel is suspended
- * @param ci The channel
- */
- virtual void OnChanSuspend(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a channel is unsuspended
- * @param ci The channel
- */
- virtual void OnChanUnsuspend(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a channel is being created, for any reason
- * @param ci The channel
- */
- virtual void OnCreateChan(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a channel is being deleted, for any reason
- * @param ci The channel
- */
- virtual void OnDelChan(ChannelInfo *ci) { throw NotImplementedException(); }
-
- /** Called when a new channel is created
- * Note that this channel may not be introduced to the uplink at this point.
- * @param c The channel
- */
- virtual void OnChannelCreate(Channel *c) { throw NotImplementedException(); }
-
- /** Called when a channel is deleted
- * @param c The channel
- */
- virtual void OnChannelDelete(Channel *c) { throw NotImplementedException(); }
-
- /** Called after adding an akick to a channel
- * @param source The source of the command
- * @param ci The channel
- * @param ak The akick
- */
- virtual void OnAkickAdd(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) { throw NotImplementedException(); }
-
- /** Called before removing an akick from a channel
- * @param source The source of the command
- * @param ci The channel
- * @param ak The akick
- */
- virtual void OnAkickDel(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) { throw NotImplementedException(); }
-
- /** Called after a user join a channel when we decide whether to kick them or not
- * @param u The user
- * @param c The channel
- * @param kick Set to true to kick
- * @param mask The mask to ban, if any
- * @param reason The reason for the kick
- * @return EVENT_STOP to prevent the user from joining by kicking/banning the user
- */
- virtual EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) { throw NotImplementedException(); }
-
- /** 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
- * @param info Data to show the user requesting information
- * @param show_hidden true if we should show the user everything
- */
- virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) { throw NotImplementedException(); }
-
- /** Checks if access has the channel privilege 'priv'.
- * @param access THe access struct
- * @param priv The privilege being checked for
- * @return EVENT_ALLOW for yes, EVENT_STOP to stop all processing
- */
- virtual EventReturn OnCheckPriv(const ChanAccess *access, const Anope::string &priv) { throw NotImplementedException(); }
-
- /** Check whether an access group has a privilege
- * @param group The group
- * @param priv The privilege
- * @return MOD_ALLOW to allow, MOD_STOP to stop
- */
- virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) { throw NotImplementedException(); }
-
- /** Called when a nick is dropped
- * @param source The source of the command
- * @param na The nick
- */
- virtual void OnNickDrop(CommandSource &source, NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when a user groups their nick
- * @param u The user grouping
- * @param target The target they're grouping to
- */
- virtual void OnNickGroup(User *u, NickAlias *target) { throw NotImplementedException(); }
-
- /** Called when a user identifies to a nick
- * @param u The user
- */
- virtual void OnNickIdentify(User *u) { throw NotImplementedException(); }
-
- /** Called when a user is logged into an account
- * @param u The user
- */
- virtual void OnUserLogin(User *u) { throw NotImplementedException(); }
-
- /** Called when a nick logs out
- * @param u The nick
- */
- virtual void OnNickLogout(User *u) { throw NotImplementedException(); }
-
- /** Called when a nick is registered
- * @param user The user registering the nick, of any
- * @param The nick
- * @param pass The password of the newly registered nick
- */
- virtual void OnNickRegister(User *user, NickAlias *na, const Anope::string &pass) { throw NotImplementedException(); }
-
- /** Called when a nick is confirmed. This will never be called if registration confirmation is not enabled.
- * @param user The user confirming the nick
- * @param The account being confirmed
- */
- virtual void OnNickConfirm(User *user, NickCore *) { throw NotImplementedException(); }
-
- /** Called when a nick is suspended
- * @param na The nick alias
- */
- virtual void OnNickSuspend(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when a nick is unsuspneded
- * @param na The nick alias
- */
- virtual void OnNickUnsuspended(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called on delnick()
- * @ param na pointer to the nickalias
- */
- virtual void OnDelNick(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when a nickcore is created
- * @param nc The nickcore
- */
- virtual void OnNickCoreCreate(NickCore *nc) { throw NotImplementedException(); }
-
- /** Called on delcore()
- * @param nc pointer to the NickCore
- */
- virtual void OnDelCore(NickCore *nc) { throw NotImplementedException(); }
-
- /** Called on change_core_display()
- * @param nc pointer to the NickCore
- * @param newdisplay the new display
- */
- virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) { throw NotImplementedException(); }
-
- /** called from NickCore::ClearAccess()
- * @param nc pointer to the NickCore
- */
- virtual void OnNickClearAccess(NickCore *nc) { throw NotImplementedException(); }
-
- /** Called when a user adds an entry to their access list
- * @param nc The nick
- * @param entry The entry
- */
- virtual void OnNickAddAccess(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
-
- /** Called from NickCore::EraseAccess()
- * @param nc pointer to the NickCore
- * @param entry The access mask
- */
- virtual void OnNickEraseAccess(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
-
- /** called from NickCore::ClearCert()
- * @param nc pointer to the NickCore
- */
- virtual void OnNickClearCert(NickCore *nc) { throw NotImplementedException(); }
-
- /** Called when a user adds an entry to their cert list
- * @param nc The nick
- * @param entry The entry
- */
- virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
-
- /** Called from NickCore::EraseCert()
- * @param nc pointer to the NickCore
- * @param entry The fingerprint
- */
- virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
-
- /** Called when a user requests info for a nick
- * @param source The user requesting info
- * @param na The nick the user is requesting info from
- * @param info Data to show the user requesting information
- * @param show_hidden true if we should show the user everything
- */
- virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) { throw NotImplementedException(); }
-
- /** Called when a user uses botserv/info on a bot or channel.
- */
- virtual void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) { throw NotImplementedException(); }
-
- /** Check whether a username and password is correct
- * @param u The user trying to identify, if applicable.
- * @param req The login request
- */
- virtual void OnCheckAuthentication(User *u, IdentifyRequest *req) { throw NotImplementedException(); }
-
- /** Called when a user does /ns update
- * @param u The user
- */
- virtual void OnNickUpdate(User *u) { throw NotImplementedException(); }
-
- /** Called when we get informed about a users SSL fingerprint
- * when we call this, the fingerprint should already be stored in the user struct
- * @param u pointer to the user
- */
- virtual void OnFingerprint(User *u) { throw NotImplementedException(); }
-
- /** Called when a user becomes (un)away
- * @param message The message, is .empty() if unaway
- */
- virtual void OnUserAway(User *u, const Anope::string &message) { throw NotImplementedException(); }
-
- /** Called when a user invites one of our users to a channel
- * @param source The user doing the inviting
- * @param c The channel the user is inviting to
- * @param targ The user being invited
- */
- virtual void OnInvite(User *source, Channel *c, User *targ) { throw NotImplementedException(); }
-
- /** Called when a vhost is deleted
- * @param na The nickalias of the vhost
- */
- virtual void OnDeleteVhost(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when a vhost is set
- * @param na The nickalias of the vhost
- */
- virtual void OnSetVhost(NickAlias *na) { throw NotImplementedException(); }
-
- /** Called when a users host changes
- * @param u The user
- */
- virtual void OnSetDisplayedHost(User *) { throw NotImplementedException(); }
-
- /** Called when a memo is sent
- * @param source The source of the memo
- * @param target The target of the memo
- * @param mi Memo info for target
- * @param m The memo
- */
- virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) { throw NotImplementedException(); }
-
- /** Called when a memo is deleted
- * @param target The target the memo is being deleted from (nick or channel)
- * @param mi The memo info
- * @param m The memo
- */
- virtual void OnMemoDel(const Anope::string &target, MemoInfo *mi, const Memo *m) { throw NotImplementedException(); }
-
- /** Called when a mode is set on a channel
- * @param c The channel
- * @param setter The user or server that is setting the mode
- * @param mode The mode
- * @param param The mode param, if there is one
- * @return EVENT_STOP to make mlock/secureops etc checks not happen
- */
- virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) { throw NotImplementedException(); }
-
- /** Called when a mode is unset on a channel
- * @param c The channel
- * @param setter The user or server that is unsetting the mode
- * @param mode The mode
- * @param param The mode param, if there is one
- * @return EVENT_STOP to make mlock/secureops etc checks not happen
- */
- virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) { throw NotImplementedException(); }
-
- /** Called when a mode is set on a user
- * @param setter who/what is setting the mode
- * @param u The user
- * @param mname The mode name
- */
- virtual void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) { throw NotImplementedException(); }
-
- /** Called when a mode is unset from a user
- * @param setter who/what is setting the mode
- * @param u The user
- * @param mname The mode name
- */
- virtual void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) { throw NotImplementedException(); }
-
- /** Called when a channel mode is introducted into Anope
- * @param cm The mode
- */
- virtual void OnChannelModeAdd(ChannelMode *cm) { throw NotImplementedException(); }
-
- /** Called when a user mode is introducted into Anope
- * @param um The mode
- */
- virtual void OnUserModeAdd(UserMode *um) { throw NotImplementedException(); }
-
- /** Called when a mode is about to be mlocked
- * @param ci The channel the mode is being locked on
- * @param lock The mode lock
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
- */
- virtual EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) { throw NotImplementedException(); }
-
- /** Called when a mode is about to be unlocked
- * @param ci The channel the mode is being unlocked from
- * @param lock The mode lock
- * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
- */
- virtual EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) { throw NotImplementedException(); }
-
- /** Called after a module is loaded
- * @param u The user loading the module, can be NULL
- * @param m The module
- */
- virtual void OnModuleLoad(User *u, Module *m) { throw NotImplementedException(); }
-
- /** Called before a module is unloaded
- * @param u The user, can be NULL
- * @param m The module
- */
- virtual void OnModuleUnload(User *u, Module *m) { throw NotImplementedException(); }
-
- /** Called when a server is synced
- * @param s The server, can be our uplink server
- */
- virtual void OnServerSync(Server *s) { throw NotImplementedException(); }
-
- /** Called when we sync with our uplink
- * @param s Our uplink
- */
- virtual void OnUplinkSync(Server *s) { throw NotImplementedException(); }
-
- /** Called when we receive a PRIVMSG for one of our clients
- * @param u The user sending the PRIVMSG
- * @param bi The target of the PRIVMSG
- * @param message The message
- * @return EVENT_STOP to halt processing
- */
- virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) { throw NotImplementedException(); }
-
- /** Called when we receive a NOTICE for one of our clients
- * @param u The user sending the NOTICE
- * @param bi The target of the NOTICE
- * @param message The message
- */
- virtual void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) { throw NotImplementedException(); }
-
- /** Called when we receive a PRIVMSG for a registered channel we are in
- * @param u The source of the message
- * @param c The channel
- * @param msg The message
- */
- virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg) { throw NotImplementedException(); }
-
- /** Called when a message is logged
- * @param l The log message
- */
- virtual void OnLog(Log *l) { throw NotImplementedException(); }
-
- /** Called when a log message is actually logged to a given log info
- * The message has already passed validation checks by the LogInfo
- * @param li The loginfo whee the message is being logged
- * @param l The log message
- * @param msg The final formatted message, derived from 'l'
- */
- virtual void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) { throw NotImplementedException(); }
-
- /** Called when a DNS request (question) is received.
- * @param req The dns request
- * @param reply The reply that will be sent
- */
- virtual void OnDnsRequest(DNS::Query &req, DNS::Query *reply) { throw NotImplementedException(); }
-
- /** Called when a channels modes are being checked to see if they are allowed,
- * mostly to ensure mlock/+r are set.
- * @param c The channel
- */
- virtual void OnCheckModes(Reference<Channel> &c) { throw NotImplementedException(); }
-
- /** Called when a channel is synced.
- * Channels are synced after a sjoin is finished processing
- * for a newly created channel to set the correct modes, topic,
- * set.
- */
- virtual void OnChannelSync(Channel *c) { throw NotImplementedException(); }
-
- /** Called to set the correct modes on the user on the given channel
- * @param user The user
- * @param chan The channel
- * @param access The user's access on the channel
- * @param give_modes If giving modes is desired
- * @param take_modes If taking modes is desired
- */
- virtual void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) { throw NotImplementedException(); }
-
- virtual void OnSerializeCheck(Serialize::Type *) { throw NotImplementedException(); }
- virtual void OnSerializableConstruct(Serializable *) { throw NotImplementedException(); }
- virtual void OnSerializableDestruct(Serializable *) { throw NotImplementedException(); }
- virtual void OnSerializableUpdate(Serializable *) { throw NotImplementedException(); }
- virtual void OnSerializeTypeCreate(Serialize::Type *) { throw NotImplementedException(); }
-
- /** Called when a chanserv/set command is used
- * @param source The source of the command
- * @param cmd The command
- * @param ci The channel the command was used on
- * @param setting The setting passed to the command. Probably ON/OFF.
- * @return EVENT_ALLOW to bypass access checks, EVENT_STOP to halt immediately.
- */
- virtual EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChannelInfo *ci, const Anope::string &setting) { throw NotImplementedException(); }
-
- /** Called when a nickserv/set command is used.
- * @param source The source of the command
- * @param cmd The command
- * @param nc The nickcore being modifed
- * @param setting The setting passed to the command. Probably ON/OFF.
- * @return EVENT_STOP to halt immediately
- */
- virtual EventReturn OnSetNickOption(CommandSource &source, Command *cmd, NickCore *nc, const Anope::string &setting) { throw NotImplementedException(); }
-
- /** Called whenever a message is received from the uplink
- * @param source The source of the message
- * @param command The command being executed
- * @param params Parameters
- * @return EVENT_STOP to prevent the protocol module from processing this message
- */
- virtual EventReturn OnMessage(MessageSource &source, Anope::string &command, std::vector<Anope::string> &param) { throw NotImplementedException(); }
-
- /** Called to determine if a chnanel mode can be set by a user
- * @param u The user
- * @param cm The mode
- */
- virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) { throw NotImplementedException(); }
-
- virtual EventReturn OnCheckDelete(Channel *) { throw NotImplementedException(); }
-
- /** Called every options:expiretimeout seconds. Should be used to expire nicks,
- * channels, etc.
- */
- virtual void OnExpireTick() { throw NotImplementedException(); }
-
- /** Called when a nick is validated. That is, to determine if a user is permissted
- * to be on the given nick.
- * @param u The user
- * @param na The nick they are on
- * @return EVENT_STOP to force the user off of the nick
+ /** Get the version of Anope this module was
+ * compiled against
+ * @return The version
*/
- virtual EventReturn OnNickValidate(User *u, NickAlias *na) { throw NotImplementedException(); }
-};
+ ModuleVersion GetVersion() const;
-enum Implementation
-{
- I_OnPreUserKicked, I_OnUserKicked, I_OnReload, I_OnPreBotAssign, I_OnBotAssign, I_OnBotUnAssign, I_OnUserConnect,
- I_OnNewServer, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, I_OnPreCommand, I_OnPostCommand, I_OnSaveDatabase,
- I_OnLoadDatabase, I_OnEncrypt, I_OnDecrypt, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd,
- I_OnBadWordDel, I_OnCreateBot, I_OnDelBot, I_OnBotKick, I_OnPrePartChannel, I_OnPartChannel, I_OnLeaveChannel,
- I_OnJoinChannel, I_OnTopicUpdated, I_OnPreChanExpire, I_OnChanExpire, I_OnPreServerConnect, I_OnServerConnect,
- I_OnPreUplinkSync, I_OnServerDisconnect, I_OnRestart, I_OnShutdown, I_OnPreNickExpire, I_OnNickExpire, I_OnDefconLevel,
- I_OnExceptionAdd, I_OnExceptionDel, I_OnAddXLine, I_OnDelXLine, I_IsServicesOper, I_OnServerQuit, I_OnUserQuit,
- I_OnPreUserLogoff, I_OnPostUserLogoff, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnAccessDel, I_OnAccessAdd,
- I_OnAccessClear, I_OnLevelChange, I_OnChanDrop, I_OnChanRegistered, I_OnChanSuspend, I_OnChanUnsuspend,
- I_OnCreateChan, I_OnDelChan, I_OnChannelCreate, I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick,
- I_OnChanInfo, I_OnCheckPriv, I_OnGroupCheckPriv, I_OnNickDrop, I_OnNickGroup, I_OnNickIdentify,
- I_OnUserLogin, I_OnNickLogout, I_OnNickRegister, I_OnNickConfirm, I_OnNickSuspend, I_OnNickUnsuspended, I_OnDelNick, I_OnNickCoreCreate,
- I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess, I_OnNickClearCert,
- I_OnNickAddCert, I_OnNickEraseCert, I_OnNickInfo, I_OnBotInfo, I_OnCheckAuthentication, I_OnNickUpdate,
- I_OnFingerprint, I_OnUserAway, I_OnInvite, I_OnDeleteVhost, I_OnSetVhost, I_OnSetDisplayedHost, I_OnMemoSend, I_OnMemoDel,
- I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
- I_OnMLock, I_OnUnMLock, I_OnModuleLoad, I_OnModuleUnload, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnBotNotice,
- I_OnPrivmsg, I_OnLog, I_OnLogMessage, I_OnDnsRequest, I_OnCheckModes, I_OnChannelSync, I_OnSetCorrectModes,
- I_OnSerializeCheck, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate,
- I_OnSerializeTypeCreate, I_OnSetChannelOption, I_OnSetNickOption, I_OnMessage, I_OnCanSet, I_OnCheckDelete,
- I_OnExpireTick, I_OnNickValidate,
- I_SIZE
+ virtual void OnReload(Configuration::Conf *conf) { }
};
/** Used to manage modules.
@@ -1128,10 +261,6 @@ enum Implementation
class CoreExport ModuleManager
{
public:
- /** Event handler hooks.
- */
- static std::vector<Module *> EventHandlers[I_SIZE];
-
/** List of all modules loaded in Anope
*/
static std::list<Module *> Modules;
@@ -1176,36 +305,6 @@ class CoreExport ModuleManager
*/
static void RequireVersion(int major, int minor, int patch);
- /** Change the priority of one event in a module.
- * Each module event has a list of modules which are attached to that event type. If you wish to be called before or after other specific modules, you may use this
- * method (usually within void Module::Prioritize()) to set your events priority. You may use this call in other methods too, however, this is not supported behaviour
- * for a module.
- * @param mod The module to change the priority of
- * @param i The event to change the priority of
- * @param s The state you wish to use for this event. Use one of
- * PRIO_FIRST to set the event to be first called, PRIO_LAST to set it to be the last called, or PRIO_BEFORE and PRIO_AFTER
- * to set it to be before or after one or more other modules.
- * @param modules If PRIO_BEFORE or PRIO_AFTER is set in parameter 's', then this contains a list of one or more modules your module must be
- * placed before or after. Your module will be placed before the highest priority module in this list for PRIO_BEFORE, or after the lowest
- * priority module in this list for PRIO_AFTER.
- * @param sz The number of modules being passed for PRIO_BEFORE and PRIO_AFTER. Defaults to 1, as most of the time you will only want to prioritize your module
- * to be before or after one other module.
- */
- static bool SetPriority(Module *mod, Implementation i, Priority s, Module **modules = NULL, size_t sz = 1);
-
- /** Change the priority of all events in a module.
- * @param mod The module to set the priority of
- * @param s The priority of all events in the module.
- * Note that with this method, it is not possible to effectively use PRIO_BEFORE or PRIO_AFTER, you should use the more fine tuned
- * SetPriority method for this, where you may specify other modules to be prioritized against.
- */
- static bool SetPriority(Module *mod, Priority s);
-
- /** Detach all events from a module (used on unload)
- * @param mod Module to detach from
- */
- static void DetachAll(Module *mod);
-
/** Unloading all modules except the protocol module.
*/
static void UnloadAll();
@@ -1216,11 +315,5 @@ class CoreExport ModuleManager
* @return MOD_ERR_OK on success, anything else on fail
*/
static ModuleReturn DeleteModule(Module *m);
-
- /** Get the version of Anope the module was compiled against
- * @return The version
- */
- static ModuleVersion GetVersion(void *handle);
};
-#endif // MODULES_H
diff --git a/include/modules/botserv.h b/include/modules/botserv.h
new file mode 100644
index 000000000..89342cef2
--- /dev/null
+++ b/include/modules/botserv.h
@@ -0,0 +1,32 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace BotServ
+{
+ class BotServService : public Service
+ {
+ public:
+ BotServService(Module *m) : Service(m, "BotServService", "BotServ")
+ {
+ }
+
+ };
+}
diff --git a/include/modules/botserv/badwords.h b/include/modules/botserv/badwords.h
new file mode 100644
index 000000000..09f8040ae
--- /dev/null
+++ b/include/modules/botserv/badwords.h
@@ -0,0 +1,112 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/** Flags for badwords
+ */
+enum BadWordType
+{
+ /* Always kicks if the word is said */
+ BW_ANY,
+ /* User must say the entire word */
+ BW_SINGLE,
+ /* The word has to start with the badword */
+ BW_START,
+ /* The word has to end with the badword */
+ BW_END
+};
+
+/* Structure used to contain bad words. */
+class BadWord : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+ public:
+ static constexpr const char *NAME = "badword";
+
+ virtual ~BadWord() = default;
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetWord() anope_abstract;
+ virtual void SetWord(const Anope::string &) anope_abstract;
+
+ virtual BadWordType GetType() anope_abstract;
+ virtual void SetType(const BadWordType &) anope_abstract;
+};
+
+class BadWords : public Service
+{
+ public:
+ static constexpr const char *NAME = "badwords";
+
+ BadWords(Module *me) : Service(me, NAME) { }
+
+ /** Add a badword to the badword list
+ * @param word The badword
+ * @param type The type (SINGLE START END)
+ * @return The badword
+ */
+ virtual BadWord* AddBadWord(ChanServ::Channel *, const Anope::string &word, BadWordType type) anope_abstract;
+
+ virtual std::vector<BadWord *> GetBadWords(ChanServ::Channel *ci) anope_abstract;
+
+ /** Get a badword structure by index
+ * @param index The index
+ * @return The badword
+ */
+ virtual BadWord* GetBadWord(ChanServ::Channel *, unsigned index) anope_abstract;
+
+ /** Get how many badwords are on this channel
+ * @return The number of badwords in the vector
+ */
+ virtual unsigned GetBadWordCount(ChanServ::Channel *) anope_abstract;
+
+ /** Remove a badword
+ * @param index The index of the badword
+ */
+ virtual void EraseBadWord(ChanServ::Channel *, unsigned index) anope_abstract;
+
+ /** Clear all badwords from the channel
+ */
+ virtual void ClearBadWords(ChanServ::Channel *) anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport BadWordEvents : Events
+ {
+ static constexpr const char *NAME = "badwords";
+
+ using Events::Events;
+
+ /** Called before a badword is added to the badword list
+ * @param ci The channel
+ * @param bw The badword
+ */
+ virtual void OnBadWordAdd(ChanServ::Channel *ci, const BadWord *bw) anope_abstract;
+
+ /** Called before a badword is deleted from a channel
+ * @param ci The channel
+ * @param bw The badword
+ */
+ virtual void OnBadWordDel(ChanServ::Channel *ci, const BadWord *bw) anope_abstract;
+ };
+}
+
diff --git a/include/modules/botserv/bot.h b/include/modules/botserv/bot.h
new file mode 100644
index 000000000..21cda65bf
--- /dev/null
+++ b/include/modules/botserv/bot.h
@@ -0,0 +1,58 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport BotCreate : Events
+ {
+ static constexpr const char *NAME = "botcreate";
+
+ using Events::Events;
+
+ /** Called when a new bot is made
+ * @param bi The bot
+ */
+ virtual void OnBotCreate(ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport BotChange : Events
+ {
+ static constexpr const char *NAME = "botchange";
+
+ using Events::Events;
+
+ /** Called when a bot is changed
+ * @param bi The bot
+ */
+ virtual void OnBotChange(ServiceBot *bi) anope_abstract;
+ };
+
+ struct CoreExport BotDelete : Events
+ {
+ static constexpr const char *NAME = "botdelete";
+
+ using Events::Events;
+
+ /** Called when a bot is deleted
+ * @param bi The bot
+ */
+ virtual void OnBotDelete(ServiceBot *bi) anope_abstract;
+ };
+}
+
diff --git a/include/modules/botserv/info.h b/include/modules/botserv/info.h
new file mode 100644
index 000000000..643c45363
--- /dev/null
+++ b/include/modules/botserv/info.h
@@ -0,0 +1,33 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport ServiceBotEvent : Events
+ {
+ static constexpr const char *NAME = "servicebotevent";
+
+ using Events::Events;
+
+ /** Called when a user uses botserv/info on a bot or channel.
+ */
+ virtual void OnServiceBot(CommandSource &source, ServiceBot *bi, ChanServ::Channel *ci, InfoFormatter &info) anope_abstract;
+ };
+}
+
diff --git a/include/modules/botserv/kick.h b/include/modules/botserv/kick.h
new file mode 100644
index 000000000..99ae14b5e
--- /dev/null
+++ b/include/modules/botserv/kick.h
@@ -0,0 +1,141 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+class KickerData : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "kickerdata";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual bool GetAmsgs() anope_abstract;
+ virtual void SetAmsgs(const bool &) anope_abstract;
+
+ virtual bool GetBadwords() anope_abstract;
+ virtual void SetBadwords(const bool &) anope_abstract;
+
+ virtual bool GetBolds() anope_abstract;
+ virtual void SetBolds(const bool &) anope_abstract;
+
+ virtual bool GetCaps() anope_abstract;
+ virtual void SetCaps(const bool &) anope_abstract;
+
+ virtual bool GetColors() anope_abstract;
+ virtual void SetColors(const bool &) anope_abstract;
+
+ virtual bool GetFlood() anope_abstract;
+ virtual void SetFlood(const bool &) anope_abstract;
+
+ virtual bool GetItalics() anope_abstract;
+ virtual void SetItalics(const bool &) anope_abstract;
+
+ virtual bool GetRepeat() anope_abstract;
+ virtual void SetRepeat(const bool &) anope_abstract;
+
+ virtual bool GetReverses() anope_abstract;
+ virtual void SetReverses(const bool &) anope_abstract;
+
+ virtual bool GetUnderlines() anope_abstract;
+ virtual void SetUnderlines(const bool &) anope_abstract;
+
+ virtual int16_t GetTTBBolds() anope_abstract;
+ virtual void SetTTBBolds(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBColors() anope_abstract;
+ virtual void SetTTBColors(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBReverses() anope_abstract;
+ virtual void SetTTBReverses(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBUnderlines() anope_abstract;
+ virtual void SetTTBUnderlines(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBBadwords() anope_abstract;
+ virtual void SetTTBBadwords(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBCaps() anope_abstract;
+ virtual void SetTTBCaps(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBFlood() anope_abstract;
+ virtual void SetTTBFlood(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBRepeat() anope_abstract;
+ virtual void SetTTBRepeat(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBItalics() anope_abstract;
+ virtual void SetTTBItalics(const int16_t &) anope_abstract;
+
+ virtual int16_t GetTTBAmsgs() anope_abstract;
+ virtual void SetTTBAmsgs(const int16_t &) anope_abstract;
+
+ virtual int16_t GetCapsMin() anope_abstract;
+ virtual void SetCapsMin(const int16_t &) anope_abstract;
+
+ virtual int16_t GetCapsPercent() anope_abstract;
+ virtual void SetCapsPercent(const int16_t &) anope_abstract;
+
+ virtual int16_t GetFloodLines() anope_abstract;
+ virtual void SetFloodLines(const int16_t &) anope_abstract;
+
+ virtual int16_t GetFloodSecs() anope_abstract;
+ virtual void SetFloodSecs(const int16_t &) anope_abstract;
+
+ virtual int16_t GetRepeatTimes() anope_abstract;
+ virtual void SetRepeatTimes(const int16_t &) anope_abstract;
+
+ virtual bool GetDontKickOps() anope_abstract;
+ virtual void SetDontKickOps(const bool &) anope_abstract;
+
+ virtual bool GetDontKickVoices() anope_abstract;
+ virtual void SetDontKickVoices(const bool &) anope_abstract;
+};
+
+inline KickerData *GetKickerData(ChanServ::Channel *ci)
+{
+ KickerData *kd = ci->GetRef<KickerData *>();
+ if (!kd)
+ {
+ kd = Serialize::New<KickerData *>();
+ if (kd != nullptr)
+ {
+ kd->SetChannel(ci);
+ }
+ }
+ return kd;
+}
+
+namespace Event
+{
+ struct CoreExport BotBan : Events
+ {
+ static constexpr const char *NAME = "botban";
+
+ using Events::Events;
+
+ /** Called when a bot places a ban
+ * @param u User being banned
+ * @param ci Channel the ban is placed on
+ * @param mask The mask being banned
+ */
+ virtual void OnBotBan(User *u, ChanServ::Channel *ci, const Anope::string &mask) anope_abstract;
+ };
+}
diff --git a/include/modules/bs_badwords.h b/include/modules/bs_badwords.h
deleted file mode 100644
index 80c5f17b6..000000000
--- a/include/modules/bs_badwords.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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.
- */
-
-/** Flags for badwords
- */
-enum BadWordType
-{
- /* Always kicks if the word is said */
- BW_ANY,
- /* User must way the entire word */
- BW_SINGLE,
- /* The word has to start with the badword */
- BW_START,
- /* The word has to end with the badword */
- BW_END
-};
-
-/* Structure used to contain bad words. */
-struct BadWord
-{
- Anope::string chan;
- Anope::string word;
- BadWordType type;
-
- virtual ~BadWord() { }
- protected:
- BadWord() { }
-};
-
-struct BadWords
-{
- virtual ~BadWords() { }
-
- /** Add a badword to the badword list
- * @param word The badword
- * @param type The type (SINGLE START END)
- * @return The badword
- */
- virtual BadWord* AddBadWord(const Anope::string &word, BadWordType type) = 0;
-
- /** Get a badword structure by index
- * @param index The index
- * @return The badword
- */
- virtual BadWord* GetBadWord(unsigned index) const = 0;
-
- /** Get how many badwords are on this channel
- * @return The number of badwords in the vector
- */
- virtual unsigned GetBadWordCount() const = 0;
-
- /** Remove a badword
- * @param index The index of the badword
- */
- virtual void EraseBadWord(unsigned index) = 0;
-
- /** Clear all badwords from the channel
- */
- virtual void ClearBadWords() = 0;
-
- virtual void Check() = 0;
-};
diff --git a/include/modules/bs_kick.h b/include/modules/bs_kick.h
deleted file mode 100644
index 8fba141f1..000000000
--- a/include/modules/bs_kick.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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.
- */
-
-/* Indices for TTB (Times To Ban) */
-enum
-{
- TTB_BOLDS,
- TTB_COLORS,
- TTB_REVERSES,
- TTB_UNDERLINES,
- TTB_BADWORDS,
- TTB_CAPS,
- TTB_FLOOD,
- TTB_REPEAT,
- TTB_ITALICS,
- TTB_AMSGS,
- TTB_SIZE
-};
-
-struct KickerData
-{
- bool amsgs, badwords, bolds, caps, colors, flood, italics, repeat, reverses, underlines;
- int16_t ttb[TTB_SIZE]; /* Times to ban for each kicker */
- int16_t capsmin, capspercent; /* For CAPS kicker */
- int16_t floodlines, floodsecs; /* For FLOOD kicker */
- int16_t repeattimes; /* For REPEAT kicker */
-
- bool dontkickops, dontkickvoices;
-
- protected:
- KickerData() { }
-
- public:
- virtual ~KickerData() { }
- virtual void Check(ChannelInfo *ci) = 0;
-};
diff --git a/include/modules/chanserv.h b/include/modules/chanserv.h
new file mode 100644
index 000000000..8c5687cc2
--- /dev/null
+++ b/include/modules/chanserv.h
@@ -0,0 +1,479 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "event.h"
+#include "channels.h"
+#include "modules/nickserv.h"
+#include "modules/memoserv.h"
+#include "bots.h"
+
+namespace ChanServ
+{
+ static struct
+ {
+ Anope::string name;
+ Anope::string desc;
+ } descriptions[] = {
+ {"ACCESS_CHANGE", _("Allowed to modify the access list")},
+ {"ACCESS_LIST", _("Allowed to view the access list")},
+ {"AKICK", _("Allowed to use the AKICK command")},
+ {"ASSIGN", _("Allowed to assign/unassign a bot")},
+ {"AUTOHALFOP", _("Automatic halfop upon join")},
+ {"AUTOOP", _("Automatic channel operator status upon join")},
+ {"AUTOOWNER", _("Automatic owner upon join")},
+ {"AUTOPROTECT", _("Automatic protect upon join")},
+ {"AUTOVOICE", _("Automatic voice on join")},
+ {"BADWORDS", _("Allowed to modify channel badwords list")},
+ {"BAN", _("Allowed to ban users")},
+ {"FANTASIA", _("Allowed to use fantasy commands")},
+ {"FOUNDER", _("Allowed to issue commands restricted to channel founders")},
+ {"GETKEY", _("Allowed to use GETKEY command")},
+ {"GREET", _("Greet message displayed on join")},
+ {"HALFOP", _("Allowed to (de)halfop users")},
+ {"HALFOPME", _("Allowed to (de)halfop him/herself")},
+ {"INFO", _("Allowed to get full INFO output")},
+ {"INVITE", _("Allowed to use the INVITE command")},
+ {"KICK", _("Allowed to use the KICK command")},
+ {"MEMO", _("Allowed to read channel memos")},
+ {"MODE", _("Allowed to use the MODE command")},
+ {"NOKICK", _("Prevents users being kicked by Services")},
+ {"OP", _("Allowed to (de)op users")},
+ {"OPME", _("Allowed to (de)op him/herself")},
+ {"OWNER", _("Allowed to (de)owner users")},
+ {"OWNERME", _("Allowed to (de)owner him/herself")},
+ {"PROTECT", _("Allowed to (de)protect users")},
+ {"PROTECTME", _("Allowed to (de)protect him/herself")},
+ {"SAY", _("Allowed to use SAY and ACT commands")},
+ {"SET", _("Allowed to set channel settings")},
+ {"SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used")},
+ {"TOPIC", _("Allowed to change channel topics")},
+ {"UNBAN", _("Allowed to unban users")},
+ {"VOICE", _("Allowed to (de)voice users")},
+ {"VOICEME", _("Allowed to (de)voice him/herself")}
+ };
+
+ /* A privilege, probably configured using a privilege{} block. Most
+ * commands require specific privileges to be executed.
+ */
+ struct CoreExport Privilege
+ {
+ Anope::string name;
+ Anope::string desc;
+ /* Rank relative to other privileges */
+ int rank;
+ int level;
+
+ Privilege(const Anope::string &n, const Anope::string &d, int r, int l) : name(n), desc(d), rank(r), level(l)
+ {
+ if (this->desc.empty())
+ for (unsigned j = 0; j < sizeof(descriptions) / sizeof(*descriptions); ++j)
+ if (descriptions[j].name.equals_ci(name))
+ this->desc = descriptions[j].desc;
+ }
+
+ bool operator==(const Privilege &other) const
+ {
+ return this->name.equals_ci(other.name);
+ }
+ };
+
+ class Channel;
+ using registered_channel_map = Anope::locale_hash_map<Channel *>;
+
+ class Level : public Serialize::Object
+ {
+ public:
+ static constexpr const char *const NAME = "level";
+
+ using Serialize::Object::Object;
+
+ virtual Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(Channel *) anope_abstract;
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual int GetLevel() anope_abstract;
+ virtual void SetLevel(const int &) anope_abstract;
+ };
+
+ class Mode : public Serialize::Object
+ {
+ public:
+ static constexpr const char *const NAME = "mlockmode";
+
+ using Serialize::Object::Object;
+
+ virtual Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(Channel *) anope_abstract;
+
+ virtual Anope::string GetMode() anope_abstract;
+ virtual void SetMode(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetParam() anope_abstract;
+ virtual void SetParam(const Anope::string &) anope_abstract;
+ };
+
+ class ChanServService : public Service
+ {
+ public:
+ static constexpr const char *NAME = "chanserv";
+
+ ChanServService(Module *m) : Service(m, NAME)
+ {
+ }
+
+ virtual Channel *Find(const Anope::string &name) anope_abstract;
+ virtual registered_channel_map& GetChannels() anope_abstract;
+
+ /* Have ChanServ hold the channel, that is, join and set +nsti and wait
+ * for a few minutes so no one can join or rejoin.
+ */
+ virtual void Hold(::Channel *c) anope_abstract;
+
+ virtual void AddPrivilege(Privilege p) anope_abstract;
+ virtual void RemovePrivilege(Privilege &p) anope_abstract;
+ virtual Privilege *FindPrivilege(const Anope::string &name) anope_abstract;
+ virtual std::vector<Privilege> &GetPrivileges() anope_abstract;
+ virtual void ClearPrivileges() anope_abstract;
+ };
+
+ extern ChanServService *service;
+
+ inline Channel *Find(const Anope::string name)
+ {
+ return service ? service->Find(name) : nullptr;
+ }
+
+ namespace Event
+ {
+ struct CoreExport PreChanExpire : Events
+ {
+ static constexpr const char *NAME = "prechanexpire";
+
+ using Events::Events;
+
+ /** Called before a channel expires
+ * @param ci The channel
+ * @param expire Set to true to allow the chan to expire
+ */
+ virtual void OnPreChanExpire(Channel *ci, bool &expire) anope_abstract;
+ };
+
+ struct CoreExport ChanExpire : Events
+ {
+ static constexpr const char *NAME = "chanexpire";
+
+ using Events::Events;
+
+ /** Called before a channel expires
+ * @param ci The channel
+ */
+ virtual void OnChanExpire(Channel *ci) anope_abstract;
+ };
+ }
+
+ /* It matters that Base is here before Extensible (it is inherited by Serializable)
+ */
+ class CoreExport Channel : public Serialize::Object
+ {
+ public:
+ ::Channel *c = nullptr; /* Pointer to channel, if the channel exists */
+
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "channel";
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetDesc() anope_abstract;
+ virtual void SetDesc(const Anope::string &) anope_abstract;
+
+ virtual time_t GetTimeRegistered() anope_abstract;
+ virtual void SetTimeRegistered(const time_t &) anope_abstract;
+
+ virtual time_t GetLastUsed() anope_abstract;
+ virtual void SetLastUsed(const time_t &) anope_abstract;
+
+ virtual Anope::string GetLastTopic() anope_abstract;
+ virtual void SetLastTopic(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLastTopicSetter() anope_abstract;
+ virtual void SetLastTopicSetter(const Anope::string &) anope_abstract;
+
+ virtual time_t GetLastTopicTime() anope_abstract;
+ virtual void SetLastTopicTime(const time_t &) anope_abstract;
+
+ virtual int16_t GetBanType() anope_abstract;
+ virtual void SetBanType(const int16_t &) anope_abstract;
+
+ virtual time_t GetBanExpire() anope_abstract;
+ virtual void SetBanExpire(const time_t &) anope_abstract;
+
+ virtual BotInfo *GetBI() anope_abstract;
+ virtual void SetBI(BotInfo *) anope_abstract;
+
+ virtual ServiceBot *GetBot() anope_abstract;
+ virtual void SetBot(ServiceBot *) anope_abstract;
+
+ /** Is the user the real founder?
+ * @param user The user
+ * @return true or false
+ */
+ virtual bool IsFounder(const User *user) anope_abstract;
+
+ /** Change the founder of the channel
+ * @params nc The new founder
+ */
+ virtual void SetFounder(NickServ::Account *nc) anope_abstract;
+
+ /** Get the founder of the channel
+ * @return The founder
+ */
+ virtual NickServ::Account *GetFounder() anope_abstract;
+
+ virtual void SetSuccessor(NickServ::Account *nc) anope_abstract;
+ virtual NickServ::Account *GetSuccessor() anope_abstract;
+
+ /** Find which bot should send mode/topic/etc changes for this channel
+ * @return The bot
+ */
+ ServiceBot *WhoSends()
+ {
+ if (this)
+ if (ServiceBot *bi = GetBot())
+ return bi;
+
+ ServiceBot *ChanServ = Config->GetClient("ChanServ");
+ if (ChanServ)
+ return ChanServ;
+
+#warning "if(this)"
+ //XXX
+// if (!BotListByNick->empty())
+// return BotListByNick->begin()->second;
+
+ return NULL;
+ }
+
+ /** Get an entry from the channel access list by index
+ *
+ * @param index The index in the access list vector
+ * @return A ChanAccess struct corresponding to the index given, or NULL if outside the bounds
+ *
+ * Retrieves an entry from the access list that matches the given index.
+ */
+ virtual ChanAccess *GetAccess(unsigned index) /*const*/ anope_abstract;
+
+ /** Retrieve the access for a user or group in the form of a vector of access entries
+ * (as multiple entries can affect a single user).
+ */
+ virtual AccessGroup AccessFor(const User *u, bool updateLastUsed = true) anope_abstract;
+ virtual AccessGroup AccessFor(NickServ::Account *nc, bool updateLastUsed = true) anope_abstract;
+
+ /** Get the size of the accss vector for this channel
+ * @return The access vector size
+ */
+ virtual unsigned GetAccessCount() /*const*/ anope_abstract;
+
+ /** Clear the entire channel access list
+ *
+ * Clears the entire access list by deleting every item and then clearing the vector.
+ */
+ virtual void ClearAccess() anope_abstract;
+
+ /** Add an akick entry to the channel by NickServ::Account
+ * @param user The user who added the akick
+ * @param akicknc The nickcore being akicked
+ * @param reason The reason for the akick
+ * @param t The time the akick was added, defaults to now
+ * @param lu The time the akick was last used, defaults to never
+ */
+ virtual AutoKick* AddAkick(const Anope::string &user, NickServ::Account *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) anope_abstract;
+
+ /** Add an akick entry to the channel by reason
+ * @param user The user who added the akick
+ * @param mask The mask of the akick
+ * @param reason The reason for the akick
+ * @param t The time the akick was added, defaults to now
+ * @param lu The time the akick was last used, defaults to never
+ */
+ virtual AutoKick* AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) anope_abstract;
+
+ /** Get an entry from the channel akick list
+ * @param index The index in the akick vector
+ * @return The akick structure, or NULL if not found
+ */
+ virtual AutoKick* GetAkick(unsigned index) anope_abstract;
+
+ /** Get the size of the akick vector for this channel
+ * @return The akick vector size
+ */
+ virtual unsigned GetAkickCount() anope_abstract;
+
+ /** Clear the whole akick list
+ */
+ virtual void ClearAkick() anope_abstract;
+
+ /** Get the level for a privilege
+ * @param priv The privilege name
+ * @return the level
+ * @throws CoreException if priv is not a valid privilege
+ */
+ virtual int16_t GetLevel(const Anope::string &priv) anope_abstract;
+
+ /** Set the level for a privilege
+ * @param priv The privilege priv
+ * @param level The new level
+ */
+ virtual void SetLevel(const Anope::string &priv, int16_t level) anope_abstract;
+
+ /** Remove a privilege from the channel
+ * @param priv The privilege
+ */
+ virtual void RemoveLevel(const Anope::string &priv) anope_abstract;
+
+ /** Clear all privileges from the channel
+ */
+ virtual void ClearLevels() anope_abstract;
+
+ /** Gets a ban mask for the given user based on the bantype
+ * of the channel.
+ * @param u The user
+ * @return A ban mask that affects the user
+ */
+ virtual Anope::string GetIdealBan(User *u) anope_abstract;
+
+ virtual MemoServ::MemoInfo *GetMemos() anope_abstract;
+ };
+
+ enum
+ {
+ ACCESS_INVALID = -10000,
+ ACCESS_FOUNDER = 10001
+ };
+
+ /* Represents one entry of an access list on a channel. */
+ class CoreExport ChanAccess : public Serialize::Object
+ {
+ public:
+ static constexpr const char *const NAME = "access";
+
+ Channel *channel = nullptr;
+ Serialize::Object *object = nullptr;
+ Anope::string creator, mask;
+ time_t last_seen = 0, created = 0;
+
+ using Serialize::Object::Object;
+
+ virtual Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(Channel *ci) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &c) anope_abstract;
+
+ virtual time_t GetLastSeen() anope_abstract;
+ virtual void SetLastSeen(const time_t &t) anope_abstract;
+
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &t) anope_abstract;
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+
+ virtual Serialize::Object *GetObj() anope_abstract;
+ virtual void SetObj(Serialize::Object *) anope_abstract;
+
+ virtual Anope::string Mask() anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
+
+ /** Check if this access entry matches the given user or account
+ * @param u The user
+ * @param acc The account
+ */
+ virtual bool Matches(const User *u, NickServ::Account *acc) anope_abstract;
+
+ /** Check if this access entry has the given privilege.
+ * @param name The privilege name
+ */
+ virtual bool HasPriv(const Anope::string &name) anope_abstract;
+
+ /** Serialize the access given by this access entry into a human
+ * readable form. chanserv/access will return a number, chanserv/xop
+ * will be AOP, SOP, etc.
+ */
+ virtual Anope::string AccessSerialize() anope_abstract;
+
+ /** Unserialize this access entry from the given data. This data
+ * will be fetched from AccessSerialize.
+ */
+ virtual void AccessUnserialize(const Anope::string &data) anope_abstract;
+
+ /* Comparison operators to other Access entries */
+ virtual bool operator>(ChanAccess &other)
+ {
+ const std::vector<Privilege> &privs = service->GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ {
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
+
+ if (!this_p && !other_p)
+ continue;
+
+ return this_p && !other_p;
+ }
+
+ return false;
+ }
+
+ virtual bool operator<(ChanAccess &other)
+ {
+ const std::vector<Privilege> &privs = service->GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ {
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
+
+ if (!this_p && !other_p)
+ continue;
+
+ return !this_p && other_p;
+ }
+
+ return false;
+ }
+
+ bool operator>=(ChanAccess &other)
+ {
+ return !(*this < other);
+ }
+
+ bool operator<=(ChanAccess &other)
+ {
+ return !(*this > other);
+ }
+ };
+}
+
diff --git a/include/modules/chanserv/access.h b/include/modules/chanserv/access.h
new file mode 100644
index 000000000..f826d0c66
--- /dev/null
+++ b/include/modules/chanserv/access.h
@@ -0,0 +1,72 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "main/chanaccess.h"
+
+namespace Event
+{
+ struct CoreExport LevelChange : Events
+ {
+ static constexpr const char *NAME = "levelchange";
+
+ using Events::Events;
+
+ /** Called when a level for a channel is changed
+ * @param source The source of the command
+ * @param ci The channel the level was changed on
+ * @param priv The privilege changed
+ * @param what The new level
+ */
+ virtual void OnLevelChange(CommandSource &source, ChanServ::Channel *ci, const Anope::string &priv, int16_t what) anope_abstract;
+ };
+}
+
+class AccessChanAccess : public ChanAccessImpl
+{
+ public:
+ static constexpr const char *NAME = "accesschanaccess";
+
+ using ChanAccessImpl::ChanAccessImpl;
+
+ virtual int GetLevel() anope_abstract;
+ virtual void SetLevel(const int &) anope_abstract;
+};
+
+class XOPChanAccess : public ChanAccessImpl
+{
+ public:
+ static constexpr const char *NAME = "xopchanaccess";
+
+ using ChanAccessImpl::ChanAccessImpl;
+
+ virtual const Anope::string &GetType() anope_abstract;
+ virtual void SetType(const Anope::string &) anope_abstract;
+};
+
+class FlagsChanAccess : public ChanAccessImpl
+{
+ public:
+ static constexpr const char *NAME = "flagschanaccess";
+
+ using ChanAccessImpl::ChanAccessImpl;
+
+ virtual const Anope::string &GetFlags() anope_abstract;
+ virtual void SetFlags(const Anope::string &) anope_abstract;
+};
+
diff --git a/include/modules/chanserv/akick.h b/include/modules/chanserv/akick.h
new file mode 100644
index 000000000..fdebcc198
--- /dev/null
+++ b/include/modules/chanserv/akick.h
@@ -0,0 +1,77 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/nickserv.h"
+
+ /* AutoKick data. */
+class CoreExport AutoKick : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+ public:
+ static constexpr const char *const NAME = "akick";
+
+ virtual ~AutoKick() = default;
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual time_t GetAddTime() anope_abstract;
+ virtual void SetAddTime(const time_t &) anope_abstract;
+
+ virtual time_t GetLastUsed() anope_abstract;
+ virtual void SetLastUsed(const time_t &) anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport Akick : Events
+ {
+ static constexpr const char *NAME = "akick";
+
+ using Events::Events;
+
+ /** Called after adding an akick to a channel
+ * @param source The source of the command
+ * @param ci The channel
+ * @param ak The akick
+ */
+ virtual void OnAkickAdd(CommandSource &source, ChanServ::Channel *ci, const AutoKick *ak) anope_abstract;
+
+ /** Called before removing an akick from a channel
+ * @param source The source of the command
+ * @param ci The channel
+ * @param ak The akick
+ */
+ virtual void OnAkickDel(CommandSource &source, ChanServ::Channel *ci, const AutoKick *ak) anope_abstract;
+ };
+}
+
diff --git a/include/modules/chanserv/drop.h b/include/modules/chanserv/drop.h
new file mode 100644
index 000000000..4ab5dd097
--- /dev/null
+++ b/include/modules/chanserv/drop.h
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport ChanDrop : Events
+ {
+ static constexpr const char *NAME = "chandrop";
+
+ using Events::Events;
+
+ /** Called right before a channel is dropped
+ * @param source The user dropping the channel
+ * @param ci The channel
+ */
+ virtual EventReturn OnChanDrop(CommandSource &source, ChanServ::Channel *ci) anope_abstract;
+ };
+}
+
diff --git a/include/modules/chanserv/entrymsg.h b/include/modules/chanserv/entrymsg.h
new file mode 100644
index 000000000..738be25d5
--- /dev/null
+++ b/include/modules/chanserv/entrymsg.h
@@ -0,0 +1,41 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class EntryMsg : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "entrymsg";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetMessage() anope_abstract;
+ virtual void SetMessage(const Anope::string &) anope_abstract;
+
+ virtual time_t GetWhen() anope_abstract;
+ virtual void SetWhen(const time_t &) anope_abstract;
+};
+
+
diff --git a/include/modules/chanserv/info.h b/include/modules/chanserv/info.h
new file mode 100644
index 000000000..08ab7a387
--- /dev/null
+++ b/include/modules/chanserv/info.h
@@ -0,0 +1,37 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport ChanInfo : Events
+ {
+ static constexpr const char *NAME = "chaninfo";
+
+ using Events::Events;
+
+ /** 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
+ * @param info Data to show the user requesting information
+ * @param show_hidden true if we should show the user everything
+ */
+ virtual void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_hidden) anope_abstract;
+ };
+}
+
diff --git a/include/modules/chanserv/log.h b/include/modules/chanserv/log.h
new file mode 100644
index 000000000..26f1cac37
--- /dev/null
+++ b/include/modules/chanserv/log.h
@@ -0,0 +1,51 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class LogSetting : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "logsetting";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetServiceName() anope_abstract;
+ virtual void SetServiceName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCommandService() anope_abstract;
+ virtual void SetCommandService(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCommandName() anope_abstract;
+ virtual void SetCommandName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetMethod() anope_abstract;
+ virtual void SetMethod(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetExtra() anope_abstract;
+ virtual void SetExtra(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &) anope_abstract;
+};
diff --git a/include/modules/chanserv/main/chanaccess.h b/include/modules/chanserv/main/chanaccess.h
new file mode 100644
index 000000000..a126da685
--- /dev/null
+++ b/include/modules/chanserv/main/chanaccess.h
@@ -0,0 +1,50 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+class ChanAccessImpl : public ChanServ::ChanAccess
+{
+ public:
+ ChanAccessImpl(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
+ ChanAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *ci) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &c) override;
+
+ time_t GetLastSeen() override;
+ void SetLastSeen(const time_t &t) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &t) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+
+ Serialize::Object *GetObj() override;
+ void SetObj(Serialize::Object *) override;
+
+ Anope::string Mask() override;
+ NickServ::Account *GetAccount() override;
+
+ bool Matches(const User *u, NickServ::Account *acc) override;
+};
diff --git a/include/modules/chanserv/mode.h b/include/modules/chanserv/mode.h
new file mode 100644
index 000000000..d580982b6
--- /dev/null
+++ b/include/modules/chanserv/mode.h
@@ -0,0 +1,133 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class ModeLock : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "modelock";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual bool GetSet() anope_abstract;
+ virtual void SetSet(const bool &) anope_abstract;
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetParam() anope_abstract;
+ virtual void SetParam(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetSetter() anope_abstract;
+ virtual void SetSetter(const Anope::string &) anope_abstract;
+
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &) anope_abstract;
+};
+
+class ModeLocks : public Service
+{
+ public:
+ static constexpr const char *NAME = "mlocks";
+
+ ModeLocks(Module *me) : Service(me, NAME) { }
+
+ typedef std::vector<ModeLock *> ModeList;
+
+ /** Check if a mode is mlocked
+ * @param mode The mode
+ * @param An optional param
+ * @param status True to check mlock on, false for mlock off
+ * @return true on success, false on fail
+ */
+ virtual bool HasMLock(ChanServ::Channel *, ChannelMode *mode, const Anope::string &param, bool status) const anope_abstract;
+
+ /** Set a mlock
+ * @param mode The mode
+ * @param status True for mlock on, false for mlock off
+ * @param param An optional param arg for + mlocked modes
+ * @param setter Who is setting the mlock
+ * @param created When the mlock was created
+ * @return true on success, false on failure (module blocking)
+ */
+ virtual bool SetMLock(ChanServ::Channel *, ChannelMode *mode, bool status, const Anope::string &param = "", Anope::string setter = "", time_t created = Anope::CurTime) anope_abstract;
+
+ /** Remove a mlock
+ * @param mode The mode
+ * @param status True for mlock on, false for mlock off
+ * @param param The param of the mode, required if it is a list or status mode
+ * @return true on success, false on failure
+ */
+ virtual bool RemoveMLock(ChanServ::Channel *, ChannelMode *mode, bool status, const Anope::string &param = "") anope_abstract;
+
+ /** Clear all mlocks on the channel
+ */
+ virtual void ClearMLock(ChanServ::Channel *) anope_abstract;
+
+ /** Get all of the mlocks for this channel
+ * @return The mlocks
+ */
+ virtual ModeList GetMLock(ChanServ::Channel *) const anope_abstract;
+
+ /** Get a list of mode locks on a channel
+ * @param name The mode name to get a list of
+ * @return a list of mlocks for the given mode
+ */
+ virtual std::list<ModeLock *> GetModeLockList(ChanServ::Channel *, const Anope::string &name) anope_abstract;
+
+ /** Get details for a specific mlock
+ * @param mname The mode name
+ * @param An optional param to match with
+ * @return The MLock, if any
+ */
+ virtual ModeLock *GetMLock(ChanServ::Channel *, const Anope::string &mname, const Anope::string &param = "") anope_abstract;
+
+ /** Get the current mode locks as a string
+ * @param complete True to show mlock parameters as well
+ * @return A string of mode locks, eg: +nrt
+ */
+ virtual Anope::string GetMLockAsString(ChanServ::Channel *, bool complete) const anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport MLockEvents : Events
+ {
+ static constexpr const char *NAME = "mlockevents";
+
+ using Events::Events;
+
+ /** Called when a mode is about to be mlocked
+ * @param ci The channel the mode is being locked on
+ * @param lock The mode lock
+ * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
+ */
+ virtual EventReturn OnMLock(ChanServ::Channel *ci, ModeLock *lock) anope_abstract;
+
+ /** Called when a mode is about to be unlocked
+ * @param ci The channel the mode is being unlocked from
+ * @param lock The mode lock
+ * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
+ */
+ virtual EventReturn OnUnMLock(ChanServ::Channel *ci, ModeLock *lock) anope_abstract;
+ };
+}
diff --git a/include/modules/chanserv/set.h b/include/modules/chanserv/set.h
new file mode 100644
index 000000000..e28818299
--- /dev/null
+++ b/include/modules/chanserv/set.h
@@ -0,0 +1,38 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport SetChannelOption : Events
+ {
+ static constexpr const char *NAME = "setchanneloption";
+
+ using Events::Events;
+
+ /** Called when a chanserv/set command is used
+ * @param source The source of the command
+ * @param cmd The command
+ * @param ci The channel the command was used on
+ * @param setting The setting passed to the command. Probably ON/OFF.
+ * @return EVENT_ALLOW to bypass access checks, EVENT_STOP to halt immediately.
+ */
+ virtual EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChanServ::Channel *ci, const Anope::string &setting) anope_abstract;
+ };
+}
+
diff --git a/include/modules/chanserv/set_misc.h b/include/modules/chanserv/set_misc.h
new file mode 100644
index 000000000..ade348ae4
--- /dev/null
+++ b/include/modules/chanserv/set_misc.h
@@ -0,0 +1,36 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class CSMiscData : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "csmiscdata";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetData() anope_abstract;
+ virtual void SetData(const Anope::string &) anope_abstract;
+};
diff --git a/include/modules/chanserv/suspend.h b/include/modules/chanserv/suspend.h
new file mode 100644
index 000000000..3d968c0db
--- /dev/null
+++ b/include/modules/chanserv/suspend.h
@@ -0,0 +1,69 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class CSSuspendInfo : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "cssuspendinfo";
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
+
+ virtual Anope::string GetBy() anope_abstract;
+ virtual void SetBy(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual time_t GetWhen() anope_abstract;
+ virtual void SetWhen(const time_t &) anope_abstract;
+
+ virtual time_t GetExpires() anope_abstract;
+ virtual void SetExpires(const time_t &) anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport ChanSuspend : Events
+ {
+ static constexpr const char *NAME = "chansuspend";
+
+ using Events::Events;
+
+ /** Called when a channel is suspended
+ * @param ci The channel
+ */
+ virtual void OnChanSuspend(ChanServ::Channel *ci) anope_abstract;
+ };
+ struct CoreExport ChanUnsuspend : Events
+ {
+ static constexpr const char *NAME = "chanunsuspend";
+
+ using Events::Events;
+
+ /** Called when a channel is unsuspended
+ * @param ci The channel
+ */
+ virtual void OnChanUnsuspend(ChanServ::Channel *ci) anope_abstract;
+ };
+}
+
diff --git a/include/modules/cs_entrymsg.h b/include/modules/cs_entrymsg.h
deleted file mode 100644
index 8636bfdbb..000000000
--- a/include/modules/cs_entrymsg.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-struct EntryMsg
-{
- Anope::string chan;
- Anope::string creator;
- Anope::string message;
- time_t when;
-
- virtual ~EntryMsg() { }
- protected:
- EntryMsg() { }
-};
-
-struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >
-{
- protected:
- EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
-
- public:
- virtual ~EntryMessageList()
- {
- for (unsigned i = (*this)->size(); i > 0; --i)
- delete (*this)->at(i - 1);
- }
-
- virtual EntryMsg* Create() = 0;
-};
diff --git a/include/modules/cs_log.h b/include/modules/cs_log.h
deleted file mode 100644
index d14179c70..000000000
--- a/include/modules/cs_log.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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.
- */
-
-struct LogSetting
-{
- Anope::string chan;
- /* Our service name of the command */
- Anope::string service_name;
- /* The name of the client the command is on */
- Anope::string command_service;
- /* Name of the command to the user, can have spaces */
- Anope::string command_name;
- Anope::string method, extra;
- Anope::string creator;
- time_t created;
-
- virtual ~LogSetting() { }
- protected:
- LogSetting() { }
-};
-
-struct LogSettings : Serialize::Checker<std::vector<LogSetting *> >
-{
- typedef std::vector<LogSetting *>::iterator iterator;
-
- protected:
- LogSettings() : Serialize::Checker<std::vector<LogSetting *> >("LogSetting")
- {
- }
-
- public:
- virtual ~LogSettings() { }
- virtual LogSetting *Create() = 0;
-};
diff --git a/include/modules/cs_mode.h b/include/modules/cs_mode.h
deleted file mode 100644
index 29a9a63ff..000000000
--- a/include/modules/cs_mode.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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.
- */
-
-struct ModeLock
-{
- Anope::string ci;
- bool set;
- Anope::string name;
- Anope::string param;
- Anope::string setter;
- time_t created;
-
- virtual ~ModeLock() { }
- protected:
- ModeLock() { }
-};
-
-struct ModeLocks
-{
- typedef std::vector<ModeLock *> ModeList;
-
- virtual ~ModeLocks() { }
-
- /** Check if a mode is mlocked
- * @param mode The mode
- * @param An optional param
- * @param status True to check mlock on, false for mlock off
- * @return true on success, false on fail
- */
- virtual bool HasMLock(ChannelMode *mode, const Anope::string &param, bool status) const = 0;
-
- /** Set a mlock
- * @param mode The mode
- * @param status True for mlock on, false for mlock off
- * @param param An optional param arg for + mlocked modes
- * @param setter Who is setting the mlock
- * @param created When the mlock was created
- * @return true on success, false on failure (module blocking)
- */
- virtual bool SetMLock(ChannelMode *mode, bool status, const Anope::string &param = "", Anope::string setter = "", time_t created = Anope::CurTime) = 0;
-
- /** Remove a mlock
- * @param mode The mode
- * @param status True for mlock on, false for mlock off
- * @param param The param of the mode, required if it is a list or status mode
- * @return true on success, false on failure
- */
- virtual bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string &param = "") = 0;
-
- virtual void RemoveMLock(ModeLock *mlock) = 0;
-
- /** Clear all mlocks on the channel
- */
- virtual void ClearMLock() = 0;
-
- /** Get all of the mlocks for this channel
- * @return The mlocks
- */
- virtual const ModeList &GetMLock() const = 0;
-
- /** Get a list of mode locks on a channel
- * @param name The mode name to get a list of
- * @return a list of mlocks for the given mode
- */
- virtual std::list<ModeLock *> GetModeLockList(const Anope::string &name) = 0;
-
- /** Get details for a specific mlock
- * @param mname The mode name
- * @param An optional param to match with
- * @return The MLock, if any
- */
- virtual const ModeLock *GetMLock(const Anope::string &mname, const Anope::string &param = "") = 0;
-
- /** Get the current mode locks as a string
- * @param complete True to show mlock parameters as well
- * @return A string of mode locks, eg: +nrt
- */
- virtual Anope::string GetMLockAsString(bool complete) const = 0;
-
- virtual void Check() = 0;
-};
diff --git a/include/modules/dns.h b/include/modules/dns.h
index 646691cb1..e98826ce7 100644
--- a/include/modules/dns.h
+++ b/include/modules/dns.h
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#ifndef DNS_H
@@ -78,11 +86,11 @@ namespace DNS
Question() : type(QUERY_NONE), qclass(0) { }
Question(const Anope::string &n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
- inline bool operator==(const Question & other) const { return name == other.name && type == other.type && qclass == other.qclass; }
+ inline bool operator==(const Question & other) const { return name == other.name && type == other.type && qclass == other.qclass; }
struct hash
{
- size_t operator()(const Question &q) const
+ size_t operator()(const Question &q) const
{
return Anope::hash_ci()(q.name);
}
@@ -94,7 +102,7 @@ namespace DNS
unsigned int ttl;
Anope::string rdata;
time_t created;
-
+
ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(Anope::CurTime) { }
ResourceRecord(const Question &q) : Question(q), ttl(0), created(Anope::CurTime) { }
};
@@ -104,7 +112,7 @@ namespace DNS
std::vector<Question> questions;
std::vector<ResourceRecord> answers, authorities, additional;
Error error;
-
+
Query() : error(ERROR_NONE) { }
Query(const Question &q) : error(ERROR_NONE) { questions.push_back(q); }
};
@@ -117,17 +125,19 @@ namespace DNS
class Manager : public Service
{
public:
- Manager(Module *creator) : Service(creator, "DNS::Manager", "dns/manager") { }
+ static constexpr const char *NAME = "dns/manager";
+
+ Manager(Module *creator) : Service(creator, NAME) { }
virtual ~Manager() { }
- virtual void Process(Request *req) = 0;
- virtual void RemoveRequest(Request *req) = 0;
+ virtual void Process(Request *req) anope_abstract;
+ virtual void RemoveRequest(Request *req) anope_abstract;
- virtual bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from) = 0;
+ virtual bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from) anope_abstract;
- virtual void UpdateSerial() = 0;
- virtual void Notify(const Anope::string &zone) = 0;
- virtual uint32_t GetSerial() const = 0;
+ virtual void UpdateSerial() anope_abstract;
+ virtual void Notify(const Anope::string &zone) anope_abstract;
+ virtual uint32_t GetSerial() const anope_abstract;
};
/** A DNS query.
@@ -154,7 +164,7 @@ namespace DNS
/** Called when this request succeeds
* @param r The query sent back from the nameserver
*/
- virtual void OnLookupComplete(const Query *r) = 0;
+ virtual void OnLookupComplete(const Query *r) anope_abstract;
/** Called when this request fails or times out.
* @param r The query sent back from the nameserver, check the error code.
@@ -164,7 +174,7 @@ namespace DNS
/** Used to time out the query, xalls OnError and lets the TimerManager
* delete this request.
*/
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name;
Query rr(*this);
@@ -175,4 +185,22 @@ namespace DNS
} // namespace DNS
+namespace Event
+{
+ struct CoreExport DnsRequest : Events
+ {
+ static constexpr const char *NAME = "dnsrequest";
+
+ using Events::Events;
+
+ /** Called when a DNS request (question) is recieved.
+ * @param req The dns request
+ * @param reply The reply that will be sent
+ */
+ virtual void OnDnsRequest(DNS::Query &req, DNS::Query *reply) anope_abstract;
+ };
+}
+
#endif // DNS_H
+
+
diff --git a/include/modules/encryption.h b/include/modules/encryption.h
index 50ca066c3..3f4af559d 100644
--- a/include/modules/encryption.h
+++ b/include/modules/encryption.h
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace Encryption
@@ -18,18 +26,21 @@ namespace Encryption
{
public:
virtual ~Context() { }
- virtual void Update(const unsigned char *data, size_t len) = 0;
- virtual void Finalize() = 0;
- virtual Hash GetFinalizedHash() = 0;
+ virtual void Update(const unsigned char *data, size_t len) anope_abstract;
+ virtual void Finalize() anope_abstract;
+ virtual Hash GetFinalizedHash() anope_abstract;
};
class Provider : public Service
{
public:
- Provider(Module *creator, const Anope::string &sname) : Service(creator, "Encryption::Provider", sname) { }
+ static constexpr const char *NAME = "hash";
+
+ Provider(Module *creator, const Anope::string &sname) : Service(creator, NAME, sname) { }
virtual ~Provider() { }
- virtual Context *CreateContext(IV * = NULL) = 0;
- virtual IV GetDefaultIV() = 0;
+ virtual Context *CreateContext(IV * = NULL) anope_abstract;
+ virtual IV GetDefaultIV() anope_abstract;
};
}
+
diff --git a/include/modules/fantasy.h b/include/modules/fantasy.h
new file mode 100644
index 000000000..463dc1c39
--- /dev/null
+++ b/include/modules/fantasy.h
@@ -0,0 +1,54 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct BotFantasy : Events
+ {
+ static constexpr const char *NAME = "botfantasy";
+
+ using Events::Events;
+
+ /** Called on fantasy command
+ * @param source The source of the command
+ * @param c The command
+ * @param ci The channel it's being used in
+ * @param params The params
+ * @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
+ */
+ virtual EventReturn OnBotFantasy(CommandSource &source, Command *c, ChanServ::Channel *ci, const std::vector<Anope::string> &params) anope_abstract;
+ };
+
+ struct CoreExport BotNoFantasyAccess : Events
+ {
+ static constexpr const char *NAME = "botnofantasyaccess";
+
+ using Events::Events;
+
+ /** Called on fantasy command without access
+ * @param source The source of the command
+ * @param c The command
+ * @param ci The channel it's being used in
+ * @param params The params
+ * @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
+ */
+ virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChanServ::Channel *ci, const std::vector<Anope::string> &params) anope_abstract;
+ };
+}
+
diff --git a/include/modules/global.h b/include/modules/global.h
new file mode 100644
index 000000000..2d49f895e
--- /dev/null
+++ b/include/modules/global.h
@@ -0,0 +1,40 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Global
+{
+ class GlobalService : public Service
+ {
+ public:
+ static constexpr const char *NAME = "global";
+
+ GlobalService(Module *m) : Service(m, NAME)
+ {
+ }
+
+ /** Send out a global message to all users
+ * @param sender Our client which should send the global
+ * @param source The sender of the global
+ * @param message The message
+ */
+ virtual void SendGlobal(ServiceBot *sender, const Anope::string &source, const Anope::string &message) anope_abstract;
+ };
+}
+
+
diff --git a/include/modules/help.h b/include/modules/help.h
new file mode 100644
index 000000000..5ba2214b7
--- /dev/null
+++ b/include/modules/help.h
@@ -0,0 +1,42 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport Help : Events
+ {
+ static constexpr const char *NAME = "help";
+
+ using Events::Events;
+
+ /** Called when someone uses the generic/help command
+ * @param source Command source
+ * @param params Params
+ * @return EVENT_STOP to stop processing
+ */
+ virtual EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_abstract;
+
+ /** 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) anope_abstract;
+ };
+}
+
diff --git a/include/modules/hostserv/del.h b/include/modules/hostserv/del.h
new file mode 100644
index 000000000..5ba1c4238
--- /dev/null
+++ b/include/modules/hostserv/del.h
@@ -0,0 +1,34 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport DeleteVhost : Events
+ {
+ static constexpr const char *NAME = "deletevhost";
+
+ using Events::Events;
+
+ /** Called when a vhost is deleted
+ * @param na The nickalias of the vhost
+ */
+ virtual void OnDeleteVhost(NickServ::Nick *na) anope_abstract;
+ };
+}
+
diff --git a/include/modules/httpd.h b/include/modules/httpd.h
index 8df3c181b..ce28e0622 100644
--- a/include/modules/httpd.h
+++ b/include/modules/httpd.h
@@ -1,13 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef ANOPE_HTTPD_H
-#define ANOPE_HTTPD_H
+#pragma once
enum HTTPError
{
@@ -112,7 +122,7 @@ class HTTPPage : public Base
* @param The HTTP header sent from the client to request the page
* @param The HTTP header that will be sent back to the client
*/
- virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0;
+ virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_abstract;
};
class HTTPClient : public ClientSocket, public BinarySocket, public Base
@@ -131,8 +141,8 @@ class HTTPClient : public ClientSocket, public BinarySocket, public Base
return this->clientaddr.addr();
}
- virtual void SendError(HTTPError err, const Anope::string &msg) = 0;
- virtual void SendReply(HTTPReply *) = 0;
+ virtual void SendError(HTTPError err, const Anope::string &msg) anope_abstract;
+ virtual void SendReply(HTTPReply *) anope_abstract;
};
class HTTPProvider : public ListenSocket, public Service
@@ -140,11 +150,16 @@ class HTTPProvider : public ListenSocket, public Service
Anope::string ip;
unsigned short port;
bool ssl;
+
public:
+ static constexpr const char *NAME = "http";
+
Anope::string ext_ip;
std::vector<Anope::string> ext_headers;
- HTTPProvider(Module *c, const Anope::string &n, const Anope::string &i, const unsigned short p, bool s) : ListenSocket(i, p, i.find(':') != Anope::string::npos), Service(c, "HTTPProvider", n), ip(i), port(p), ssl(s) { }
+ HTTPProvider(Module *c, const Anope::string &n, const Anope::string &i, const unsigned short p, bool s)
+ : ListenSocket(i, p, i.find(':') != Anope::string::npos)
+ , Service(c, NAME, n), ip(i), port(p), ssl(s) { }
const Anope::string &GetIP() const
{
@@ -161,9 +176,9 @@ class HTTPProvider : public ListenSocket, public Service
return this->ssl;
}
- virtual bool RegisterPage(HTTPPage *page) = 0;
- virtual void UnregisterPage(HTTPPage *page) = 0;
- virtual HTTPPage* FindPage(const Anope::string &name) = 0;
+ virtual bool RegisterPage(HTTPPage *page) anope_abstract;
+ virtual void UnregisterPage(HTTPPage *page) anope_abstract;
+ virtual HTTPPage* FindPage(const Anope::string &name) anope_abstract;
};
namespace HTTPUtils
@@ -236,5 +251,3 @@ namespace HTTPUtils
return dst;
}
}
-
-#endif // ANOPE_HTTPD_H
diff --git a/include/modules/ldap.h b/include/modules/ldap.h
index 373c9cfa3..da560adf2 100644
--- a/include/modules/ldap.h
+++ b/include/modules/ldap.h
@@ -1,13 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef ANOPE_LDAP_H
-#define ANOPE_LDAP_H
+#pragma once
class LDAPException : public ModuleException
{
@@ -118,8 +128,8 @@ class LDAPInterface
LDAPInterface(Module *m) : owner(m) { }
virtual ~LDAPInterface() { }
- virtual void OnResult(const LDAPResult &r) = 0;
- virtual void OnError(const LDAPResult &err) = 0;
+ virtual void OnResult(const LDAPResult &r) anope_abstract;
+ virtual void OnError(const LDAPResult &err) anope_abstract;
virtual void OnDelete() { }
};
@@ -131,41 +141,39 @@ class LDAPProvider : public Service
/** Attempt to bind to the LDAP server as an admin
* @param i The LDAPInterface the result is sent to
*/
- virtual void BindAsAdmin(LDAPInterface *i) = 0;
+ virtual void BindAsAdmin(LDAPInterface *i) anope_abstract;
/** Bind to LDAP
* @param i The LDAPInterface the result is sent to
* @param who The binddn
* @param pass The password
*/
- virtual void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) = 0;
+ virtual void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) anope_abstract;
/** Search ldap for the specified filter
* @param i The LDAPInterface the result is sent to
* @param base The base DN to search
* @param filter The filter to apply
*/
- virtual void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) = 0;
+ virtual void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) anope_abstract;
/** Add an entry to LDAP
* @param i The LDAPInterface the result is sent to
* @param dn The dn of the entry to add
* @param attributes The attributes
*/
- virtual void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) = 0;
+ virtual void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) anope_abstract;
/** Delete an entry from LDAP
* @param i The LDAPInterface the result is sent to
* @param dn The dn of the entry to delete
*/
- virtual void Del(LDAPInterface *i, const Anope::string &dn) = 0;
+ virtual void Del(LDAPInterface *i, const Anope::string &dn) anope_abstract;
/** Modify an existing entry in LDAP
* @param i The LDAPInterface the result is sent to
* @param base The base DN to modify
* @param attributes The attributes to modify
*/
- virtual void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) = 0;
+ virtual void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) anope_abstract;
};
-
-#endif // ANOPE_LDAP_H
diff --git a/include/modules/memoserv.h b/include/modules/memoserv.h
new file mode 100644
index 000000000..1268facef
--- /dev/null
+++ b/include/modules/memoserv.h
@@ -0,0 +1,165 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "module.h"
+
+namespace MemoServ
+{
+ class Ignore;
+
+ class MemoServService : public Service
+ {
+ public:
+ static constexpr const char *NAME = "memoserv";
+
+ enum MemoResult
+ {
+ MEMO_SUCCESS,
+ MEMO_INVALID_TARGET,
+ MEMO_TOO_FAST,
+ MEMO_TARGET_FULL
+ };
+
+ MemoServService(Module *m) : Service(m, "MemoServService", NAME)
+ {
+ }
+
+ /** Sends a memo.
+ * @param source The source of the memo, can be anythin.
+ * @param target The target of the memo, nick or channel.
+ * @param message Memo text
+ * @param force true to force the memo, restrictions/delays etc are not checked
+ */
+ virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force = false) anope_abstract;
+
+ /** Check for new memos and notify the user if there are any
+ * @param u The user
+ */
+ virtual void Check(User *u) anope_abstract;
+
+ virtual MemoInfo *GetMemoInfo(const Anope::string &targ, bool &is_registered, bool &is_chan, bool create) anope_abstract;
+ };
+
+ extern MemoServService *service;
+
+ namespace Event
+ {
+ struct CoreExport MemoSend : Events
+ {
+ static constexpr const char *NAME = "memosend";
+
+ using Events::Events;
+
+ /** Called when a memo is sent
+ * @param source The source of the memo
+ * @param target The target of the memo
+ * @param mi Memo info for target
+ * @param m The memo
+ */
+ virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) anope_abstract;
+ };
+
+ struct CoreExport MemoDel : Events
+ {
+ static constexpr const char *NAME = "memodel";
+
+ using Events::Events;
+
+ /** Called when a memo is deleted
+ * @param target The target the memo is being deleted from (nick or channel)
+ * @param mi The memo info
+ * @param m The memo
+ */
+ virtual void OnMemoDel(const Anope::string &target, MemoInfo *mi, const Memo *m) anope_abstract;
+ };
+ }
+
+ class Memo : public Serialize::Object
+ {
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "memo";
+
+ virtual MemoInfo *GetMemoInfo() anope_abstract;
+ virtual void SetMemoInfo(MemoInfo *) anope_abstract;
+
+ virtual time_t GetTime() anope_abstract;
+ virtual void SetTime(const time_t &) anope_abstract;
+
+ virtual Anope::string GetSender() anope_abstract;
+ virtual void SetSender(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetText() anope_abstract;
+ virtual void SetText(const Anope::string &) anope_abstract;
+
+ virtual bool GetUnread() anope_abstract;
+ virtual void SetUnread(const bool &) anope_abstract;
+
+ virtual bool GetReceipt() anope_abstract;
+ virtual void SetReceipt(const bool &) anope_abstract;
+ };
+
+ /* Memo info structures. Since both nicknames and channels can have memos,
+ * we encapsulate memo data in a MemoInfo to make it easier to handle.
+ */
+ class MemoInfo : public Serialize::Object
+ {
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "memoinfo";
+
+ virtual Memo *GetMemo(unsigned index) anope_abstract;
+
+ virtual unsigned GetIndex(Memo *m) anope_abstract;
+
+ virtual void Del(unsigned index) anope_abstract;
+
+ virtual bool HasIgnore(User *u) anope_abstract;
+
+ virtual Serialize::Object *GetOwner() anope_abstract;
+ virtual void SetOwner(Serialize::Object *) anope_abstract;
+
+ virtual int16_t GetMemoMax() anope_abstract;
+ virtual void SetMemoMax(const int16_t &) anope_abstract;
+
+ virtual std::vector<Memo *> GetMemos() anope_abstract;
+ virtual std::vector<Ignore *> GetIgnores() anope_abstract;
+ };
+
+ class Ignore : public Serialize::Object
+ {
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "memoignore";
+
+ virtual MemoInfo *GetMemoInfo() anope_abstract;
+ virtual void SetMemoInfo(MemoInfo *) anope_abstract;
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &mask) anope_abstract;
+ };
+}
diff --git a/include/modules/nickserv.h b/include/modules/nickserv.h
new file mode 100644
index 000000000..43e2a21ce
--- /dev/null
+++ b/include/modules/nickserv.h
@@ -0,0 +1,327 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "event.h"
+#include "service.h"
+#include "serialize.h"
+
+namespace NickServ
+{
+ class Nick;
+ class Account;
+ class IdentifyRequestListener;
+
+ using nickalias_map = Anope::locale_hash_map<Nick *>;
+ using nickcore_map = Anope::locale_hash_map<Account *>;
+
+ class NickServService : public Service
+ {
+ public:
+ NickServService(Module *m) : Service(m, "NickServService", "NickServ")
+ {
+ }
+
+ virtual void Validate(User *u) anope_abstract;
+ virtual void Collide(User *u, Nick *na) anope_abstract;
+ virtual void Release(Nick *na) anope_abstract;
+
+ virtual IdentifyRequest *CreateIdentifyRequest(IdentifyRequestListener *l, Module *owner, const Anope::string &acc, const Anope::string &pass) anope_abstract;
+ virtual std::set<IdentifyRequest *>& GetIdentifyRequests() anope_abstract;
+
+ virtual std::vector<Nick *> GetNickList() anope_abstract;
+ virtual nickalias_map& GetNickMap() anope_abstract;
+
+ virtual std::vector<Account *> GetAccountList() anope_abstract;
+ virtual nickcore_map& GetAccountMap() anope_abstract;
+
+ virtual Nick *FindNick(const Anope::string &nick) anope_abstract;
+ virtual Account *FindAccount(const Anope::string &acc) anope_abstract;
+ };
+
+ extern NickServService *service;
+
+ inline Nick *FindNick(const Anope::string &nick)
+ {
+ return service ? service->FindNick(nick) : nullptr;
+ }
+
+ inline Account *FindAccount(const Anope::string &account)
+ {
+ return service ? service->FindAccount(account) : nullptr;
+ }
+
+ namespace Event
+ {
+ struct CoreExport PreNickExpire : Events
+ {
+ static constexpr const char *NAME = "prenickexpire";
+
+ using Events::Events;
+
+ /** Called before a nick expires
+ * @param na The nick
+ * @param expire Set to true to allow the nick to expire
+ */
+ virtual void OnPreNickExpire(Nick *na, bool &expire) anope_abstract;
+ };
+
+ struct CoreExport NickExpire : Events
+ {
+ static constexpr const char *NAME = "nickexpire";
+
+ using Events::Events;
+
+ /** Called when a nick drops
+ * @param na The nick
+ */
+ virtual void OnNickExpire(Nick *na) anope_abstract;
+ };
+
+ struct CoreExport NickRegister : Events
+ {
+ static constexpr const char *NAME = "nickregister";
+
+ using Events::Events;
+
+ /** Called when a nick is registered
+ * @param user The user registering the nick, of any
+ * @param The nick
+ * @param password The password of the nick
+ */
+ virtual void OnNickRegister(User *user, Nick *na, const Anope::string &password) anope_abstract;
+ };
+
+ struct CoreExport NickConfirm : Events
+ {
+ static constexpr const char *NAME = "nickconfirm";
+
+ using Events::Events;
+
+ virtual void OnNickConfirm(User *, Account *) anope_abstract;
+ };
+
+ struct CoreExport NickValidate : Events
+ {
+ static constexpr const char *NAME = "nickvalidate";
+
+ using Events::Events;
+
+ /** Called when a nick is validated. That is, to determine if a user is permissted
+ * to be on the given nick.
+ * @param u The user
+ * @param na The nick they are on
+ * @return EVENT_STOP to force the user off of the nick
+ */
+ virtual EventReturn OnNickValidate(User *u, Nick *na) anope_abstract;
+ };
+ }
+
+ /* A registered nickname.
+ * It matters that Base is here before Extensible (it is inherited by Serializable)
+ */
+ class CoreExport Nick : public Serialize::Object
+ {
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "nick";
+
+ virtual Anope::string GetNick() anope_abstract;
+ virtual void SetNick(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLastQuit() anope_abstract;
+ virtual void SetLastQuit(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLastRealname() anope_abstract;
+ virtual void SetLastRealname(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLastUsermask() anope_abstract;
+ virtual void SetLastUsermask(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLastRealhost() anope_abstract;
+ virtual void SetLastRealhost(const Anope::string &) anope_abstract;
+
+ virtual time_t GetTimeRegistered() anope_abstract;
+ virtual void SetTimeRegistered(const time_t &) anope_abstract;
+
+ virtual time_t GetLastSeen() anope_abstract;
+ virtual void SetLastSeen(const time_t &) anope_abstract;
+
+ virtual Account *GetAccount() anope_abstract;
+ virtual void SetAccount(Account *acc) anope_abstract;
+
+ /** Set a vhost for the user
+ * @param ident The ident
+ * @param host The host
+ * @param creator Who created the vhost
+ * @param time When the vhost was craated
+ */
+ virtual void SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created = Anope::CurTime) anope_abstract;
+ virtual void RemoveVhost() anope_abstract;
+ virtual bool HasVhost() anope_abstract;
+
+ virtual Anope::string GetVhostIdent() anope_abstract;
+ virtual void SetVhostIdent(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetVhostHost() anope_abstract;
+ virtual void SetVhostHost(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetVhostCreator() anope_abstract;
+ virtual void SetVhostCreator(const Anope::string &) anope_abstract;
+
+ virtual time_t GetVhostCreated() anope_abstract;
+ virtual void SetVhostCreated(const time_t &) anope_abstract;
+ };
+
+ /* A registered account. Each account must have a Nick with the same nick as the
+ * account's display.
+ * It matters that Base is here before Extensible (it is inherited by Serializable)
+ */
+ class CoreExport Account : public Serialize::Object
+ {
+ public:
+ static constexpr const char *const NAME = "account";
+
+ /* Set if this user is a services operattor. o->ot must exist. */
+ Serialize::Reference<Oper> o;
+
+ /* Unsaved data */
+
+ /* Last time an email was sent to this user */
+ time_t lastmail = 0;
+ /* Users online now logged into this account */
+ std::vector<User *> users;
+
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ virtual Anope::string GetDisplay() anope_abstract;
+ virtual void SetDisplay(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetPassword() anope_abstract;
+ virtual void SetPassword(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetEmail() anope_abstract;
+ virtual void SetEmail(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetLanguage() anope_abstract;
+ virtual void SetLanguage(const Anope::string &) anope_abstract;
+
+ /** Changes the display for this account
+ * @param na The new display, must be grouped to this account.
+ */
+ virtual void SetDisplay(Nick *na) anope_abstract;
+
+ /** Checks whether this account is a services oper or not.
+ * @return True if this account is a services oper, false otherwise.
+ */
+ virtual bool IsServicesOper() const anope_abstract;
+
+ /** Is the given user on this accounts access list?
+ *
+ * @param u The user
+ *
+ * @return true if the user is on the access list
+ */
+ virtual bool IsOnAccess(User *u) anope_abstract;
+
+ virtual MemoServ::MemoInfo *GetMemos() anope_abstract;
+
+ virtual unsigned int GetChannelCount() anope_abstract;
+ };
+
+ /* A request to check if an account/password is valid. These can exist for
+ * extended periods due to the time some authentication modules take.
+ */
+ class CoreExport IdentifyRequest
+ {
+ protected:
+ /* Owner of this request, used to cleanup requests if a module is unloaded
+ * while a request us pending */
+ Module *owner;
+ IdentifyRequestListener *l;
+ Anope::string account;
+ Anope::string password;
+
+ std::set<Module *> holds;
+ bool dispatched = false;
+ bool success = false;
+
+ IdentifyRequest(IdentifyRequestListener *li, Module *o, const Anope::string &acc, const Anope::string &pass) : owner(o), l(li), account(acc), password(pass) { }
+ public:
+ virtual ~IdentifyRequest() { }
+
+ const Anope::string &GetAccount() const { return account; }
+ const Anope::string &GetPassword() const { return password; }
+ Module *GetOwner() const { return owner; }
+
+ /* Holds this request. When a request is held it must be Released later
+ * for the request to complete. Multiple modules may hold a request at any time,
+ * but the request is not complete until every module has released it. If you do not
+ * require holding this (eg, your password check is done in this thread and immediately)
+ * then you don't need to hold the request before Successing it.
+ * @param m The module holding this request
+ */
+ virtual void Hold(Module *m) anope_abstract;
+
+ /** Releases a held request
+ * @param m The module releaseing the hold
+ */
+ virtual void Release(Module *m) anope_abstract;
+
+ /** Called by modules when this IdentifyRequest has successeded successfully.
+ * If this request is behind held it must still be Released after calling this.
+ * @param m The module confirming authentication
+ */
+ virtual void Success(Module *m) anope_abstract;
+
+ /** Used to either finalize this request or marks
+ * it as dispatched and begins waiting for the module(s)
+ * that have holds to finish.
+ */
+ virtual void Dispatch() anope_abstract;
+ };
+
+ class IdentifyRequestListener
+ {
+ public:
+ virtual ~IdentifyRequestListener() { }
+ virtual void OnSuccess(IdentifyRequest *) anope_abstract;
+ virtual void OnFail(IdentifyRequest *) anope_abstract;
+ };
+
+ class Mode : public Serialize::Object
+ {
+ public:
+ static constexpr const char *const NAME = "mode";
+
+ using Serialize::Object::Object;
+
+ virtual Account *GetAccount() anope_abstract;
+ virtual void SetAccount(Account *) anope_abstract;
+
+ virtual Anope::string GetMode() anope_abstract;
+ virtual void SetMode(const Anope::string &) anope_abstract;
+ };
+
+}
diff --git a/include/modules/nickserv/access.h b/include/modules/nickserv/access.h
new file mode 100644
index 000000000..e8fb70f18
--- /dev/null
+++ b/include/modules/nickserv/access.h
@@ -0,0 +1,34 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class NickAccess : public Serialize::Object
+{
+ public:
+ static constexpr const char *const NAME = "nsaccess";
+
+ using Serialize::Object::Object;
+
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+};
+
+
diff --git a/include/modules/nickserv/ajoin.h b/include/modules/nickserv/ajoin.h
new file mode 100644
index 000000000..c23eecbe9
--- /dev/null
+++ b/include/modules/nickserv/ajoin.h
@@ -0,0 +1,37 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class AutoJoin : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "autojoin";
+
+ virtual NickServ::Account *GetOwner() anope_abstract;
+ virtual void SetOwner(NickServ::Account *acc) anope_abstract;
+
+ virtual Anope::string GetChannel() anope_abstract;
+ virtual void SetChannel(const Anope::string &c) anope_abstract;
+
+ virtual Anope::string GetKey() anope_abstract;
+ virtual void SetKey(const Anope::string &k) anope_abstract;
+};
+
diff --git a/include/modules/nickserv/cert.h b/include/modules/nickserv/cert.h
new file mode 100644
index 000000000..be33b3d4a
--- /dev/null
+++ b/include/modules/nickserv/cert.h
@@ -0,0 +1,76 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class NSCertEntry;
+
+class CertService : public Service
+{
+ public:
+ static constexpr const char *NAME = "certs";
+
+ CertService(Module *c) : Service(c, NAME) { }
+
+ virtual NickServ::Account* FindAccountFromCert(const Anope::string &cert) anope_abstract;
+
+ virtual bool Matches(User *, NickServ::Account *) anope_abstract;
+
+ virtual NSCertEntry *FindCert(const std::vector<NSCertEntry *> &cl, const Anope::string &certfp) anope_abstract;
+};
+
+class NSCertEntry : public Serialize::Object
+{
+ public:
+ static constexpr const char *NAME = "nscert";
+
+ using Serialize::Object::Object;
+
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual Anope::string GetCert() anope_abstract;
+ virtual void SetCert(const Anope::string &) anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport NickCertEvents : Events
+ {
+ static constexpr const char *NAME = "nickcertevents";
+
+ using Events::Events;
+
+ /** Called when a user adds an entry to their cert list
+ * @param nc The nick
+ * @param entry The entry
+ */
+ virtual void OnNickAddCert(NickServ::Account *nc, const Anope::string &entry) anope_abstract;
+
+ /** Called from NickServ::Account::EraseCert()
+ * @param nc pointer to the NickServ::Account
+ * @param entry The fingerprint
+ */
+ virtual void OnNickEraseCert(NickServ::Account *nc, const Anope::string &entry) anope_abstract;
+
+ /** called from NickServ::Account::ClearCert()
+ * @param nc pointer to the NickServ::Account
+ */
+ virtual void OnNickClearCert(NickServ::Account *nc) anope_abstract;
+ };
+}
+
diff --git a/include/modules/nickserv/drop.h b/include/modules/nickserv/drop.h
new file mode 100644
index 000000000..3363e63ed
--- /dev/null
+++ b/include/modules/nickserv/drop.h
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport NickDrop : Events
+ {
+ static constexpr const char *NAME = "nickdrop";
+
+ using Events::Events;
+
+ /** Called when a nick is dropped
+ * @param source The source of the command
+ * @param na The nick
+ */
+ virtual void OnNickDrop(CommandSource &source, NickServ::Nick *na) anope_abstract;
+ };
+}
+
diff --git a/include/modules/nickserv/group.h b/include/modules/nickserv/group.h
new file mode 100644
index 000000000..b403f5d4e
--- /dev/null
+++ b/include/modules/nickserv/group.h
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport NickGroup : Events
+ {
+ static constexpr const char *NAME = "nickgroup";
+
+ using Events::Events;
+
+ /** Called when a user groups their nick
+ * @param u The user grouping
+ * @param target The target they're grouping to
+ */
+ virtual void OnNickGroup(User *u, NickServ::Nick *target) anope_abstract;
+ };
+}
+
diff --git a/include/modules/nickserv/info.h b/include/modules/nickserv/info.h
new file mode 100644
index 000000000..2a1777bd3
--- /dev/null
+++ b/include/modules/nickserv/info.h
@@ -0,0 +1,37 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport NickInfo : Events
+ {
+ static constexpr const char *NAME = "nickinfo";
+
+ using Events::Events;
+
+ /** Called when a user requests info for a nick
+ * @param source The user requesting info
+ * @param na The nick the user is requesting info from
+ * @param info Data to show the user requesting information
+ * @param show_hidden true if we should show the user everything
+ */
+ virtual void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) anope_abstract;
+ };
+}
+
diff --git a/include/modules/nickserv/set.h b/include/modules/nickserv/set.h
new file mode 100644
index 000000000..f635b81b0
--- /dev/null
+++ b/include/modules/nickserv/set.h
@@ -0,0 +1,38 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport SetNickOption : Events
+ {
+ static constexpr const char *NAME = "setnickoption";
+
+ using Events::Events;
+
+ /** Called when a nickserv/set command is used.
+ * @param source The source of the command
+ * @param cmd The command
+ * @param nc The nickcore being modifed
+ * @param setting The setting passed to the command. Probably ON/OFF.
+ * @return EVENT_STOP to halt immediately
+ */
+ virtual EventReturn OnSetNickOption(CommandSource &source, Command *cmd, NickServ::Account *nc, const Anope::string &setting) anope_abstract;
+ };
+}
+
diff --git a/include/modules/nickserv/set_misc.h b/include/modules/nickserv/set_misc.h
new file mode 100644
index 000000000..da042e353
--- /dev/null
+++ b/include/modules/nickserv/set_misc.h
@@ -0,0 +1,37 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class NSMiscData : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "nsmiscdata";
+
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetData() anope_abstract;
+ virtual void SetData(const Anope::string &) anope_abstract;
+};
+
diff --git a/include/modules/nickserv/suspend.h b/include/modules/nickserv/suspend.h
new file mode 100644
index 000000000..c690a95f7
--- /dev/null
+++ b/include/modules/nickserv/suspend.h
@@ -0,0 +1,69 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class NSSuspendInfo : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "nssuspendinfo";
+
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual Anope::string GetBy() anope_abstract;
+ virtual void SetBy(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual time_t GetWhen() anope_abstract;
+ virtual void SetWhen(const time_t &) anope_abstract;
+
+ virtual time_t GetExpires() anope_abstract;
+ virtual void SetExpires(const time_t &) anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport NickSuspend : Events
+ {
+ static constexpr const char *NAME = "nicksuspend";
+
+ using Events::Events;
+
+ /** Called when a nick is suspended
+ * @param na The nick alias
+ */
+ virtual void OnNickSuspend(NickServ::Nick *na) anope_abstract;
+ };
+
+ struct CoreExport NickUnsuspend : Events
+ {
+ static constexpr const char *NAME = "nickunsuspend";
+
+ using Events::Events;
+
+ /** Called when a nick is unsuspneded
+ * @param na The nick alias
+ */
+ virtual void OnNickUnsuspend(NickServ::Nick *na) anope_abstract;
+ };
+}
diff --git a/include/modules/nickserv/update.h b/include/modules/nickserv/update.h
new file mode 100644
index 000000000..0dbc1424f
--- /dev/null
+++ b/include/modules/nickserv/update.h
@@ -0,0 +1,34 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport NickUpdate : Events
+ {
+ static constexpr const char *NAME = "nickupdate";
+
+ using Events::Events;
+
+ /** Called when a user does /ns update
+ * @param u The user
+ */
+ virtual void OnNickUpdate(User *u) anope_abstract;
+ };
+}
+
diff --git a/include/modules/ns_cert.h b/include/modules/ns_cert.h
deleted file mode 100644
index 637948923..000000000
--- a/include/modules/ns_cert.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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.
- */
-
-struct NSCertList
-{
- protected:
- NSCertList() { }
- public:
- virtual ~NSCertList() { }
-
- /** Add an entry to the nick's certificate list
- *
- * @param entry The fingerprint to add to the cert list
- *
- * Adds a new entry into the cert list.
- */
- virtual void AddCert(const Anope::string &entry) = 0;
-
- /** Get an entry from the nick's cert list by index
- *
- * @param entry Index in the certificaate list vector to retrieve
- * @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
- *
- * Retrieves an entry from the certificate list corresponding to the given index.
- */
- virtual Anope::string GetCert(unsigned entry) const = 0;
-
- virtual unsigned GetCertCount() const = 0;
-
- /** Find an entry in the nick's cert list
- *
- * @param entry The fingerprint to search for
- * @return True if the fingerprint is found in the cert list, false otherwise
- *
- * Search for an fingerprint within the cert list.
- */
- virtual bool FindCert(const Anope::string &entry) const = 0;
-
- /** Erase a fingerprint from the nick's certificate list
- *
- * @param entry The fingerprint to remove
- *
- * Removes the specified fingerprint from the cert list.
- */
- virtual void EraseCert(const Anope::string &entry) = 0;
-
- /** Clears the entire nick's cert list
- *
- * Deletes all the memory allocated in the certificate list vector and then clears the vector.
- */
- virtual void ClearCert() = 0;
-
- virtual void Check() = 0;
-};
-
-class CertService : public Service
-{
- public:
- CertService(Module *c) : Service(c, "CertService", "certs") { }
-
- virtual NickCore* FindAccountFromCert(const Anope::string &cert) = 0;
-};
diff --git a/include/modules/operserv/defcon.h b/include/modules/operserv/defcon.h
new file mode 100644
index 000000000..735081405
--- /dev/null
+++ b/include/modules/operserv/defcon.h
@@ -0,0 +1,34 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Event
+{
+ struct CoreExport DefconLevel : Events
+ {
+ static constexpr const char *NAME = "defconlevel";
+
+ using Events::Events;
+
+ /** Called when defcon level changes
+ * @param level The level
+ */
+ virtual void OnDefconLevel(int level) anope_abstract;
+ };
+}
+
diff --git a/include/modules/operserv/dns.h b/include/modules/operserv/dns.h
new file mode 100644
index 000000000..af413a92c
--- /dev/null
+++ b/include/modules/operserv/dns.h
@@ -0,0 +1,83 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class DNSZone : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "dnszone";
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+};
+
+class DNSServer : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "dnsserver";
+
+ virtual DNSZone *GetZone() anope_abstract;
+ virtual void SetZone(DNSZone *) anope_abstract;
+
+ virtual Anope::string GetName() anope_abstract;
+ virtual void SetName(const Anope::string &) anope_abstract;
+
+ virtual unsigned int GetLimit() anope_abstract;
+ virtual void SetLimit(const unsigned int &) anope_abstract;
+
+ virtual bool GetPooled() anope_abstract;
+ virtual void SetPool(const bool &) anope_abstract;
+};
+
+class DNSZoneMembership : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "dnszonemembership";
+
+ virtual DNSServer *GetServer() anope_abstract;
+ virtual void SetServer(DNSServer *) anope_abstract;
+
+ virtual DNSZone *GetZone() anope_abstract;
+ virtual void SetZone(DNSZone *) anope_abstract;
+};
+
+class DNSIP : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "dnsip";
+
+ virtual DNSServer *GetServer() anope_abstract;
+ virtual void SetServer(DNSServer *) anope_abstract;
+
+ virtual Anope::string GetIP() anope_abstract;
+ virtual void SetIP(const Anope::string &) anope_abstract;
+};
+
+
diff --git a/include/modules/operserv/forbid.h b/include/modules/operserv/forbid.h
new file mode 100644
index 000000000..2b87d707d
--- /dev/null
+++ b/include/modules/operserv/forbid.h
@@ -0,0 +1,68 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+enum ForbidType
+{
+ FT_NICK = 1,
+ FT_CHAN,
+ FT_EMAIL,
+ FT_REGISTER,
+ FT_SIZE
+};
+
+class ForbidData : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *NAME = "forbid";
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &) anope_abstract;
+
+ virtual time_t GetExpires() anope_abstract;
+ virtual void SetExpires(const time_t &) anope_abstract;
+
+ virtual ForbidType GetType() anope_abstract;
+ virtual void SetType(const ForbidType &) anope_abstract;
+};
+
+class ForbidService : public Service
+{
+ public:
+ static constexpr const char *NAME = "forbid";
+
+ ForbidService(Module *m) : Service(m, NAME) { }
+
+ virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) anope_abstract;
+
+ virtual std::vector<ForbidData *> GetForbids() anope_abstract;
+};
+
+
diff --git a/include/modules/operserv/ignore.h b/include/modules/operserv/ignore.h
new file mode 100644
index 000000000..56235f6da
--- /dev/null
+++ b/include/modules/operserv/ignore.h
@@ -0,0 +1,49 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class Ignore : public Serialize::Object
+{
+ public:
+ static constexpr const char *NAME = "ignore";
+
+ using Serialize::Object::Object;
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual time_t GetTime() anope_abstract;
+ virtual void SetTime(const time_t &) anope_abstract;
+};
+
+class IgnoreService : public Service
+{
+ public:
+ static constexpr const char *NAME = "ignore";
+
+ IgnoreService(Module *c) : Service(c, NAME) { }
+
+ virtual Ignore *Find(const Anope::string &mask) anope_abstract;
+};
+
diff --git a/include/modules/operserv/info.h b/include/modules/operserv/info.h
new file mode 100644
index 000000000..0e2198880
--- /dev/null
+++ b/include/modules/operserv/info.h
@@ -0,0 +1,39 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class OperInfo : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *const NAME = "operinfo";
+
+ virtual Serialize::Object *GetTarget() anope_abstract;
+ virtual void SetTarget(Serialize::Object *) anope_abstract;
+
+ virtual Anope::string GetInfo() anope_abstract;
+ virtual void SetInfo(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &) anope_abstract;
+
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &) anope_abstract;
+};
diff --git a/include/modules/operserv/news.h b/include/modules/operserv/news.h
new file mode 100644
index 000000000..46c720d3d
--- /dev/null
+++ b/include/modules/operserv/news.h
@@ -0,0 +1,47 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+enum NewsType
+{
+ NEWS_LOGON,
+ NEWS_RANDOM,
+ NEWS_OPER
+};
+
+class NewsItem : public Serialize::Object
+{
+ public:
+ static constexpr const char *const NAME = "newsitem";
+
+ using Serialize::Object::Object;
+
+ virtual NewsType GetNewsType() anope_abstract;
+ virtual void SetNewsType(const NewsType &) anope_abstract;
+
+ virtual Anope::string GetText() anope_abstract;
+ virtual void SetText(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetWho() anope_abstract;
+ virtual void SetWho(const Anope::string &) anope_abstract;
+
+ virtual time_t GetTime() anope_abstract;
+ virtual void SetTime(const time_t &) anope_abstract;
+};
diff --git a/include/modules/operserv/session.h b/include/modules/operserv/session.h
new file mode 100644
index 000000000..5373609a0
--- /dev/null
+++ b/include/modules/operserv/session.h
@@ -0,0 +1,97 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+struct Session
+{
+ cidr addr; /* A cidr (sockaddrs + len) representing this session */
+ unsigned int count = 1; /* Number of clients with this host */
+ unsigned int hits = 0; /* Number of subsequent kills for a host */
+
+ Session(const sockaddrs &ip, int len) : addr(ip, len) { }
+};
+
+class Exception : public Serialize::Object
+{
+ protected:
+ using Serialize::Object::Object;
+
+ public:
+ static constexpr const char *NAME = "exception";
+
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
+
+ virtual unsigned int GetLimit() anope_abstract;
+ virtual void SetLimit(unsigned int) anope_abstract;
+
+ virtual Anope::string GetWho() anope_abstract;
+ virtual void SetWho(const Anope::string &) anope_abstract;
+
+ virtual Anope::string GetReason() anope_abstract;
+ virtual void SetReason(const Anope::string &) anope_abstract;
+
+ virtual time_t GetTime() anope_abstract;
+ virtual void SetTime(const time_t &) anope_abstract;
+
+ virtual time_t GetExpires() anope_abstract;
+ virtual void SetExpires(const time_t &) anope_abstract;
+};
+
+class SessionService : public Service
+{
+ public:
+ static constexpr const char *NAME = "session";
+
+ typedef std::unordered_map<cidr, Session *, cidr::hash> SessionMap;
+
+ SessionService(Module *m) : Service(m, NAME) { }
+
+ virtual Exception *FindException(User *u) anope_abstract;
+
+ virtual Exception *FindException(const Anope::string &host) anope_abstract;
+
+ virtual Session *FindSession(const Anope::string &ip) anope_abstract;
+
+ virtual SessionMap &GetSessions() anope_abstract;
+};
+
+namespace Event
+{
+ struct CoreExport Exception : Events
+ {
+ static constexpr const char *NAME = "exception";
+
+ using Events::Events;
+
+ /** 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
+ */
+ virtual EventReturn OnExceptionAdd(::Exception *ex) anope_abstract;
+
+ /** Called before an exception is deleted
+ * @param source The source deleting it
+ * @param ex The exceotion
+ */
+ virtual void OnExceptionDel(CommandSource &source, ::Exception *ex) anope_abstract;
+ };
+}
+
diff --git a/include/modules/operserv/stats.h b/include/modules/operserv/stats.h
new file mode 100644
index 000000000..9e6878c73
--- /dev/null
+++ b/include/modules/operserv/stats.h
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+class Stats : public Serialize::Object
+{
+ public:
+ static constexpr const char *const NAME = "stats";
+
+ using Serialize::Object::Object;
+
+ virtual unsigned int GetMaxUserCount() anope_abstract;
+ virtual void SetMaxUserCount(unsigned int i) anope_abstract;
+
+ virtual time_t GetMaxUserTime() anope_abstract;
+ virtual void SetMaxUserTime(time_t t) anope_abstract;
+};
+
diff --git a/include/modules/os_forbid.h b/include/modules/os_forbid.h
deleted file mode 100644
index b4702d844..000000000
--- a/include/modules/os_forbid.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef OS_FORBID_H
-#define OS_FORBID_H
-
-enum ForbidType
-{
- FT_NICK = 1,
- FT_CHAN,
- FT_EMAIL,
- FT_REGISTER,
- FT_SIZE
-};
-
-struct ForbidData
-{
- Anope::string mask;
- Anope::string creator;
- Anope::string reason;
- time_t created;
- time_t expires;
- ForbidType type;
-
- virtual ~ForbidData() { }
- protected:
- ForbidData() : created(0), expires(0) { }
-};
-
-class ForbidService : public Service
-{
- public:
- ForbidService(Module *m) : Service(m, "ForbidService", "forbid") { }
-
- virtual void AddForbid(ForbidData *d) = 0;
-
- virtual void RemoveForbid(ForbidData *d) = 0;
-
- virtual ForbidData* CreateForbid() = 0;
-
- virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0;
-
- virtual std::vector<ForbidData *> GetForbids() = 0;
-};
-
-static ServiceReference<ForbidService> forbid_service("ForbidService", "forbid");
-
-#endif
diff --git a/include/modules/os_ignore.h b/include/modules/os_ignore.h
deleted file mode 100644
index 9ba07a92d..000000000
--- a/include/modules/os_ignore.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* OperServ ignore interface
- *
- * (C) 2003-2016 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.
- */
-
-struct IgnoreData
-{
- Anope::string mask;
- Anope::string creator;
- Anope::string reason;
- time_t time; /* When do we stop ignoring them? */
-
- virtual ~IgnoreData() { }
- protected:
- IgnoreData() : time(0) { }
-};
-
-class IgnoreService : public Service
-{
- protected:
- IgnoreService(Module *c) : Service(c, "IgnoreService", "ignore") { }
-
- public:
- virtual void AddIgnore(IgnoreData *) = 0;
-
- virtual void DelIgnore(IgnoreData *) = 0;
-
- virtual void ClearIgnores() = 0;
-
- virtual IgnoreData *Create() = 0;
-
- virtual IgnoreData *Find(const Anope::string &mask) = 0;
-
- virtual std::vector<IgnoreData *> &GetIgnores() = 0;
-};
-
-static ServiceReference<IgnoreService> ignore_service("IgnoreService", "ignore");
diff --git a/include/modules/os_news.h b/include/modules/os_news.h
deleted file mode 100644
index e7303850a..000000000
--- a/include/modules/os_news.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef OS_NEWS
-#define OS_NEWS
-
-enum NewsType
-{
- NEWS_LOGON,
- NEWS_RANDOM,
- NEWS_OPER
-};
-
-struct NewsMessages
-{
- NewsType type;
- Anope::string name;
- const char *msgs[10];
-};
-
-struct NewsItem : Serializable
-{
- NewsType type;
- Anope::string text;
- Anope::string who;
- time_t time;
-
- NewsItem() : Serializable("NewsItem") { }
-};
-
-class NewsService : public Service
-{
- public:
- NewsService(Module *m) : Service(m, "NewsService", "news") { }
-
- virtual NewsItem *CreateNewsItem() = 0;
-
- virtual void AddNewsItem(NewsItem *n) = 0;
-
- virtual void DelNewsItem(NewsItem *n) = 0;
-
- virtual std::vector<NewsItem *> &GetNewsList(NewsType t) = 0;
-};
-
-static ServiceReference<NewsService> news_service("NewsService", "news");
-
-#endif // OS_NEWS
diff --git a/include/modules/os_session.h b/include/modules/os_session.h
deleted file mode 100644
index a1bab86ad..000000000
--- a/include/modules/os_session.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef OS_SESSION_H
-#define OS_SESSION_H
-
-struct Session
-{
- cidr addr; /* A cidr (sockaddrs + len) representing this session */
- unsigned count; /* Number of clients with this host */
- unsigned hits; /* Number of subsequent kills for a host */
-
- Session(const sockaddrs &ip, int len) : addr(ip, len), count(1), hits(0) { }
-};
-
-struct Exception : Serializable
-{
- Anope::string mask; /* Hosts to which this exception applies */
- unsigned limit; /* Session limit for exception */
- Anope::string who; /* Nick of person who added the exception */
- Anope::string reason; /* Reason for exception's addition */
- time_t time; /* When this exception was added */
- time_t expires; /* Time when it expires. 0 == no expiry */
-
- Exception() : Serializable("Exception") { }
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-class SessionService : public Service
-{
- public:
- typedef TR1NS::unordered_map<cidr, Session *, cidr::hash> SessionMap;
- typedef std::vector<Exception *> ExceptionVector;
-
- SessionService(Module *m) : Service(m, "SessionService", "session") { }
-
- virtual Exception *CreateException() = 0;
-
- virtual void AddException(Exception *e) = 0;
-
- virtual void DelException(Exception *e) = 0;
-
- virtual Exception *FindException(User *u) = 0;
-
- virtual Exception *FindException(const Anope::string &host) = 0;
-
- virtual ExceptionVector &GetExceptions() = 0;
-
- virtual Session *FindSession(const Anope::string &ip) = 0;
-
- virtual SessionMap &GetSessions() = 0;
-};
-
-static ServiceReference<SessionService> session_service("SessionService", "session");
-
-void Exception::Serialize(Serialize::Data &data) const
-{
- data["mask"] << this->mask;
- data["limit"] << this->limit;
- data["who"] << this->who;
- data["reason"] << this->reason;
- data["time"] << this->time;
- data["expires"] << this->expires;
-}
-
-Serializable* Exception::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- if (!session_service)
- return NULL;
-
- Exception *ex;
- if (obj)
- ex = anope_dynamic_static_cast<Exception *>(obj);
- else
- ex = new Exception;
- data["mask"] >> ex->mask;
- data["limit"] >> ex->limit;
- data["who"] >> ex->who;
- data["reason"] >> ex->reason;
- data["time"] >> ex->time;
- data["expires"] >> ex->expires;
-
- if (!obj)
- session_service->AddException(ex);
- return ex;
-}
-
-#endif
diff --git a/include/modules/protocol/charybdis.h b/include/modules/protocol/charybdis.h
new file mode 100644
index 000000000..36de05544
--- /dev/null
+++ b/include/modules/protocol/charybdis.h
@@ -0,0 +1,60 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace charybdis
+{
+
+class Encap : public IRCDMessage
+{
+ ServiceReference<SASL::Service> sasl;
+
+ public:
+ Encap(Module *creator) : IRCDMessage(creator, "ENCAP", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT);}
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class EUID : public IRCDMessage
+{
+ public:
+ EUID(Module *creator) : IRCDMessage(creator, "EUID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Server : public IRCDMessage
+{
+ public:
+ Server(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ // SERVER dev.anope.de 1 :charybdis test server
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Pass : public IRCDMessage
+{
+ public:
+ Pass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+} // namespace charybdis
diff --git a/include/modules/protocol/hybrid.h b/include/modules/protocol/hybrid.h
new file mode 100644
index 000000000..4991ec624
--- /dev/null
+++ b/include/modules/protocol/hybrid.h
@@ -0,0 +1,129 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace hybrid
+{
+
+class BMask : public IRCDMessage
+{
+ public:
+ BMask(Module *creator) : IRCDMessage(creator, "BMASK", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class EOB : public IRCDMessage
+{
+ public:
+ EOB(Module *craetor) : IRCDMessage(craetor, "EOB", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Join : public Message::Join
+{
+ public:
+ Join(Module *creator) : Message::Join(creator, "JOIN") { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Nick : public IRCDMessage
+{
+ public:
+ Nick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Pong : public IRCDMessage
+{
+ public:
+ Pong(Module *creator) : IRCDMessage(creator, "PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Server : public IRCDMessage
+{
+ public:
+ Server(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class SID : public IRCDMessage
+{
+ public:
+ SID(Module *creator) : IRCDMessage(creator, "SID", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class SJoin : public IRCDMessage
+{
+ public:
+ SJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class SVSMode : public IRCDMessage
+{
+ public:
+ SVSMode(Module *creator) : IRCDMessage(creator, "SVSMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class TBurst : public IRCDMessage
+{
+ public:
+ TBurst(Module *creator) : IRCDMessage(creator, "TBURST", 5) { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class TMode : public IRCDMessage
+{
+ public:
+ TMode(Module *creator) : IRCDMessage(creator, "TMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class UID : public IRCDMessage
+{
+ public:
+ UID(Module *creator) : IRCDMessage(creator, "UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class CertFP : public IRCDMessage
+{
+ public:
+ CertFP(Module *creator) : IRCDMessage(creator, "CERTFP", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+} // namespace hybrid \ No newline at end of file
diff --git a/include/modules/protocol/plexus.h b/include/modules/protocol/plexus.h
new file mode 100644
index 000000000..1d6f79780
--- /dev/null
+++ b/include/modules/protocol/plexus.h
@@ -0,0 +1,50 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace plexus
+{
+
+class Encap : public IRCDMessage
+{
+ public:
+ Encap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Server : public IRCDMessage
+{
+ public:
+ Server(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class UID : public IRCDMessage
+{
+ public:
+ UID(Module *creator) : IRCDMessage(creator, "UID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+}
+
diff --git a/include/modules/protocol/ratbox.h b/include/modules/protocol/ratbox.h
new file mode 100644
index 000000000..d5101321a
--- /dev/null
+++ b/include/modules/protocol/ratbox.h
@@ -0,0 +1,66 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace ratbox
+{
+
+class Encap : public IRCDMessage
+{
+ public:
+ Encap(Module *creator) : IRCDMessage(creator, "ENCAP", 3) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ // Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Join : public Message::Join
+{
+ public:
+ Join(Module *creator) : Message::Join(creator, "JOIN") { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class Server : public IRCDMessage
+{
+ public:
+ Server(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class TB : public IRCDMessage
+{
+ public:
+ TB(Module *creator) : IRCDMessage(creator, "TB", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+class UID : public IRCDMessage
+{
+ public:
+ UID(Module *creator) : IRCDMessage(creator, "UID", 9) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override;
+};
+
+} // namespace ratbox
diff --git a/include/modules/pseudoclients/chanserv.h b/include/modules/pseudoclients/chanserv.h
deleted file mode 100644
index a10e07939..000000000
--- a/include/modules/pseudoclients/chanserv.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef CHANSERV_H
-#define CHANSERV_H
-
-class ChanServService : public Service
-{
- public:
- ChanServService(Module *m) : Service(m, "ChanServService", "ChanServ")
- {
- }
-
- /* Have ChanServ hold the channel, that is, join and set +nsti and wait
- * for a few minutes so no one can join or rejoin.
- */
- virtual void Hold(Channel *c) = 0;
-};
-
-#endif // CHANSERV_H
diff --git a/include/modules/pseudoclients/global.h b/include/modules/pseudoclients/global.h
deleted file mode 100644
index c557ce099..000000000
--- a/include/modules/pseudoclients/global.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef GLOBAL_H
-#define GLOBAL_H
-
-class GlobalService : public Service
-{
- public:
- GlobalService(Module *m) : Service(m, "GlobalService", "Global")
- {
- }
-
- /** Send out a global message to all users
- * @param sender Our client which should send the global
- * @param source The sender of the global
- * @param message The message
- */
- virtual void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0;
-};
-
-#endif // GLOBAL_H
diff --git a/include/modules/pseudoclients/memoserv.h b/include/modules/pseudoclients/memoserv.h
deleted file mode 100644
index abfbc3344..000000000
--- a/include/modules/pseudoclients/memoserv.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef MEMOSERV_H
-#define MEMOSERV_H
-
-class MemoServService : public Service
-{
- public:
- enum MemoResult
- {
- MEMO_SUCCESS,
- MEMO_INVALID_TARGET,
- MEMO_TOO_FAST,
- MEMO_TARGET_FULL
- };
-
- MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ")
- {
- }
-
- /** Sends a memo.
- * @param source The source of the memo, can be anythin.
- * @param target The target of the memo, nick or channel.
- * @param message Memo text
- * @param force true to force the memo, restrictions/delays etc are not checked
- */
- virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force = false) = 0;
-
- /** Check for new memos and notify the user if there are any
- * @param u The user
- */
- virtual void Check(User *u) = 0;
-};
-
-#endif // MEMOSERV_H
diff --git a/include/modules/pseudoclients/nickserv.h b/include/modules/pseudoclients/nickserv.h
deleted file mode 100644
index 1b1d3e422..000000000
--- a/include/modules/pseudoclients/nickserv.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef NICKSERV_H
-#define NICKSERV_H
-
-class NickServService : public Service
-{
- public:
- NickServService(Module *m) : Service(m, "NickServService", "NickServ")
- {
- }
-
- virtual void Validate(User *u) = 0;
- virtual void Collide(User *u, NickAlias *na) = 0;
- virtual void Release(NickAlias *na) = 0;
-};
-
-#endif // NICKSERV_H
diff --git a/include/modules/redis.h b/include/modules/redis.h
index 2f530735b..dc8c1e75f 100644
--- a/include/modules/redis.h
+++ b/include/modules/redis.h
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace Redis
@@ -23,7 +34,7 @@ namespace Redis
Reply() { Clear(); }
~Reply() { Clear(); }
-
+
void Clear()
{
type = NOT_PARSED;
@@ -47,26 +58,40 @@ namespace Redis
Module *owner;
Interface(Module *m) : owner(m) { }
- virtual ~Interface() { }
+ virtual ~Interface() = default;
- virtual void OnResult(const Reply &r) = 0;
+ virtual void OnResult(const Reply &r) anope_abstract;
virtual void OnError(const Anope::string &error) { Log(owner) << error; }
};
+ class FInterface : public Interface
+ {
+ public:
+ using Func = std::function<void(const Reply &)>;
+ Func function;
+
+ FInterface(Module *m, Func f) : Interface(m), function(f) { }
+
+ void OnResult(const Reply &r) override { function(r); }
+ };
+
class Provider : public Service
{
public:
- Provider(Module *c, const Anope::string &n) : Service(c, "Redis::Provider", n) { }
+ static constexpr const char *NAME = "redis";
+
+ Provider(Module *c, const Anope::string &n) : Service(c, NAME, n) { }
- virtual void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) = 0;
- virtual void SendCommand(Interface *i, const Anope::string &str) = 0;
+ virtual void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) anope_abstract;
+ virtual void SendCommand(Interface *i, const Anope::string &str) anope_abstract;
- virtual bool BlockAndProcess() = 0;
+ virtual bool BlockAndProcess() anope_abstract;
- virtual void Subscribe(Interface *i, const Anope::string &pattern) = 0;
- virtual void Unsubscribe(const Anope::string &pattern) = 0;
+ virtual void Subscribe(Interface *i, const Anope::string &) anope_abstract;
+ virtual void Unsubscribe(const Anope::string &pattern) anope_abstract;
- virtual void StartTransaction() = 0;
- virtual void CommitTransaction() = 0;
+ virtual void StartTransaction() anope_abstract;
+ virtual void CommitTransaction() anope_abstract;
};
}
+
diff --git a/include/modules/sasl.h b/include/modules/sasl.h
index 6cb1d21c9..50808b9ea 100644
--- a/include/modules/sasl.h
+++ b/include/modules/sasl.h
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2014-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace SASL
@@ -23,105 +34,74 @@ namespace SASL
class Service : public ::Service
{
public:
- Service(Module *o) : ::Service(o, "SASL::Service", "sasl") { }
+ static constexpr const char *NAME = "sasl";
+
+ Service(Module *o) : ::Service(o, NAME) { }
- virtual void ProcessMessage(const Message &) = 0;
+ virtual void ProcessMessage(const Message &) anope_abstract;
- virtual Anope::string GetAgent() = 0;
+ virtual Anope::string GetAgent() anope_abstract;
- virtual Session* GetSession(const Anope::string &uid) = 0;
+ virtual Session* GetSession(const Anope::string &uid) anope_abstract;
- virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) = 0;
+ virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) anope_abstract;
- virtual void Succeed(Session *, NickCore *) = 0;
- virtual void Fail(Session *) = 0;
- virtual void SendMechs(Session *) = 0;
- virtual void DeleteSessions(Mechanism *, bool = false) = 0;
- virtual void RemoveSession(Session *) = 0;
+ virtual void Succeed(Session *, NickServ::Account *) anope_abstract;
+ virtual void Fail(Session *) anope_abstract;
+ virtual void SendMechs(Session *) anope_abstract;
+ virtual void DeleteSessions(Mechanism *, bool = false) anope_abstract;
+ virtual void RemoveSession(Session *) anope_abstract;
};
- static ServiceReference<SASL::Service> sasl("SASL::Service", "sasl");
-
- struct Session
+ class Session
{
+ SASL::Service *service;
+
+ public:
time_t created;
Anope::string uid;
Reference<Mechanism> mech;
- Session(Mechanism *m, const Anope::string &u) : created(Anope::CurTime), uid(u), mech(m) { }
+ Session(SASL::Service *s, Mechanism *m, const Anope::string &u) : service(s), created(Anope::CurTime), uid(u), mech(m) { }
+
virtual ~Session()
{
- if (sasl)
- sasl->RemoveSession(this);
+ service->RemoveSession(this);
}
};
/* PLAIN, EXTERNAL, etc */
class Mechanism : public ::Service
{
+ SASL::Service *service;
+
public:
- Mechanism(Module *o, const Anope::string &sname) : Service(o, "SASL::Mechanism", sname) { }
+ static constexpr const char *NAME = "sasl/mechanism";
+
+ Mechanism(SASL::Service *s, Module *o, const Anope::string &sname) : Service(o, NAME, sname), service(s) { }
+
+ SASL::Service *GetService() const { return service; }
- virtual Session* CreateSession(const Anope::string &uid) { return new Session(this, uid); }
+ virtual Session* CreateSession(const Anope::string &uid) { return new Session(service, this, uid); }
- virtual void ProcessMessage(Session *session, const Message &) = 0;
+ virtual void ProcessMessage(Session *session, const Message &) anope_abstract;
virtual ~Mechanism()
{
- if (sasl)
- sasl->DeleteSessions(this, true);
+ service->DeleteSessions(this, true);
}
};
- class IdentifyRequest : public ::IdentifyRequest
+ class IdentifyRequestListener : public NickServ::IdentifyRequestListener
{
+ SASL::Service *service = nullptr;
Anope::string uid;
public:
- IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : ::IdentifyRequest(m, acc, pass), uid(id) { }
+ IdentifyRequestListener(SASL::Service *s, const Anope::string &id) : service(s), uid(id) { }
- void OnSuccess() anope_override
- {
- if (!sasl)
- return;
-
- NickAlias *na = NickAlias::Find(GetAccount());
- if (!na || na->nc->HasExt("NS_SUSPENDED"))
- return OnFail();
-
- unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
- if (maxlogins && na->nc->users.size() >= maxlogins)
- return OnFail();
-
- Session *s = sasl->GetSession(uid);
- if (s)
- {
- Log(Config->GetClient("NickServ"), "sasl") << "A user identified to account " << this->GetAccount() << " using SASL";
- sasl->Succeed(s, na->nc);
- delete s;
- }
- }
+ void OnSuccess(NickServ::IdentifyRequest *req) override;
- void OnFail() anope_override
- {
- if (!sasl)
- return;
-
- Session *s = sasl->GetSession(uid);
- if (s)
- {
- sasl->Fail(s);
- delete s;
- }
-
- Anope::string accountstatus;
- NickAlias *na = NickAlias::Find(GetAccount());
- if (!na)
- accountstatus = "nonexistent ";
- else if (na->nc->HasExt("NS_SUSPENDED"))
- accountstatus = "suspended ";
-
- Log(Config->GetClient("NickServ"), "sasl") << "A user failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
- }
+ void OnFail(NickServ::IdentifyRequest *req) override;
};
}
diff --git a/include/modules/set_misc.h b/include/modules/set_misc.h
deleted file mode 100644
index f925119e2..000000000
--- a/include/modules/set_misc.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-struct MiscData
-{
- Anope::string object;
- Anope::string name;
- Anope::string data;
-
- MiscData() { }
- virtual ~MiscData() { }
-};
diff --git a/include/modules/sql.h b/include/modules/sql.h
index 375de14b6..2e84db152 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -1,80 +1,24 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace SQL
{
-
- class Data : public Serialize::Data
- {
- public:
- typedef std::map<Anope::string, std::stringstream *> Map;
- Map data;
- std::map<Anope::string, Type> types;
-
- ~Data()
- {
- Clear();
- }
-
- std::iostream& operator[](const Anope::string &key) anope_override
- {
- std::stringstream *&ss = data[key];
- if (!ss)
- ss = new std::stringstream();
- return *ss;
- }
-
- std::set<Anope::string> KeySet() const anope_override
- {
- std::set<Anope::string> keys;
- for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- keys.insert(it->first);
- return keys;
- }
-
- size_t Hash() const anope_override
- {
- size_t hash = 0;
- for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- if (!it->second->str().empty())
- hash ^= Anope::hash_cs()(it->second->str());
- return hash;
- }
-
- std::map<Anope::string, std::iostream *> GetData() const
- {
- std::map<Anope::string, std::iostream *> d;
- for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- d[it->first] = it->second;
- return d;
- }
-
- void Clear()
- {
- for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- delete it->second;
- this->data.clear();
- }
-
- void SetType(const Anope::string &key, Type t) anope_override
- {
- this->types[key] = t;
- }
-
- Type GetType(const Anope::string &key) const anope_override
- {
- std::map<Anope::string, Type>::const_iterator it = this->types.find(key);
- if (it != this->types.end())
- return it->second;
- return DT_TEXT;
- }
- };
-
/** A SQL exception, can be thrown at various points
*/
class Exception : public ModuleException
@@ -92,6 +36,7 @@ namespace SQL
{
Anope::string data;
bool escape;
+ bool null;
};
struct Query
@@ -129,15 +74,41 @@ namespace SQL
}
catch (const ConvertException &ex) { }
}
+
+ void SetNull(const Anope::string &key)
+ {
+ QueryData &qd = this->parameters[key];
+
+ qd.data = "";
+ qd.escape = false;
+ qd.null = true;
+ }
+
+ Anope::string Unsafe() const
+ {
+ Anope::string q = query;
+ for (auto it = parameters.begin(); it != parameters.end(); ++it)
+ q = q.replace_all_cs("@" + it->first + "@", it->second.data);
+ return q;
+ }
};
/** A result from a SQL query
*/
class Result
{
+ public:
+ struct Value
+ {
+ bool null = false;
+ Anope::string value;
+ };
+
protected:
- /* Rows, column, item */
- std::vector<std::map<Anope::string, Anope::string> > entries;
+ std::vector<Anope::string> columns;
+ // row, column
+ std::vector<std::vector<Value>> values;
+
Query query;
Anope::string error;
public:
@@ -149,17 +120,20 @@ namespace SQL
inline operator bool() const { return this->error.empty(); }
- inline const unsigned int GetID() const { return this->id; }
+ inline unsigned int GetID() const { return this->id; }
inline const Query &GetQuery() const { return this->query; }
inline const Anope::string &GetError() const { return this->error; }
- int Rows() const { return this->entries.size(); }
+ int Rows() const
+ {
+ return this->values.size();
+ }
- const std::map<Anope::string, Anope::string> &Row(size_t index) const
+ const std::vector<Value> &Row(size_t index) const
{
try
{
- return this->entries.at(index);
+ return this->values.at(index);
}
catch (const std::out_of_range &)
{
@@ -167,15 +141,35 @@ namespace SQL
}
}
- const Anope::string Get(size_t index, const Anope::string &col) const
+ const Value &GetValue(size_t index, const Anope::string &col) const
{
- const std::map<Anope::string, Anope::string> rows = this->Row(index);
+ const std::vector<Value> &v = this->Row(index);
- std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col);
- if (it == rows.end())
+ auto it = std::find(this->columns.begin(), this->columns.end(), col);
+ if (it == this->columns.end())
throw Exception("Unknown column name in SQLResult: " + col);
+ unsigned int col_idx = it - this->columns.begin();
- return it->second;
+ try
+ {
+ return v[col_idx];
+ }
+ catch (const std::out_of_range &)
+ {
+ throw Exception("Out of bounds access to SQLResult");
+ }
+ }
+
+ const Anope::string &Get(size_t index, const Anope::string &col) const
+ {
+ const Value &value = GetValue(index, col);
+ return value.value;
+ }
+
+ bool IsNull(size_t index, const Anope::string &col) const
+ {
+ const Value &value = GetValue(index, col);
+ return value.null;
}
};
@@ -189,8 +183,8 @@ namespace SQL
Interface(Module *m) : owner(m) { }
virtual ~Interface() { }
- virtual void OnResult(const Result &r) = 0;
- virtual void OnError(const Result &r) = 0;
+ virtual void OnResult(const Result &r) anope_abstract;
+ virtual void OnError(const Result &r) anope_abstract;
};
/** Class providing the SQL service, modules call this to execute queries
@@ -198,19 +192,27 @@ namespace SQL
class Provider : public Service
{
public:
- Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { }
+ static constexpr const char *NAME = "sql";
+
+ Provider(Module *c, const Anope::string &n) : Service(c, NAME, n) { }
- virtual void Run(Interface *i, const Query &query) = 0;
+ virtual void Run(Interface *i, const Query &query) anope_abstract;
- virtual Result RunQuery(const Query &query) = 0;
+ virtual Result RunQuery(const Query &query) anope_abstract;
- virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0;
+ virtual std::vector<Query> InitSchema(const Anope::string &prefix) anope_abstract;
+ virtual std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) anope_abstract;
+ virtual std::vector<Query> CreateTable(const Anope::string &prefix, const Anope::string &table) anope_abstract;
+ virtual std::vector<Query> AlterTable(const Anope::string &, const Anope::string &table, const Anope::string &field, bool object) anope_abstract;
+ virtual std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) anope_abstract;
- virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0;
+ virtual Query BeginTransaction() anope_abstract;
+ virtual Query Commit() anope_abstract;
- virtual Query GetTables(const Anope::string &prefix) = 0;
+ virtual Serialize::ID GetID(const Anope::string &) anope_abstract;
- virtual Anope::string FromUnixtime(time_t) = 0;
+ virtual Query GetTables(const Anope::string &prefix) anope_abstract;
};
}
+
diff --git a/include/modules/ssl.h b/include/modules/ssl.h
index d682933b5..f3bc2b067 100644
--- a/include/modules/ssl.h
+++ b/include/modules/ssl.h
@@ -1,15 +1,31 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+#pragma once
+
class SSLService : public Service
{
public:
- SSLService(Module *o, const Anope::string &n) : Service(o, "SSLService", n) { }
+ static constexpr const char *NAME = "ssl";
- virtual void Init(Socket *s) = 0;
+ SSLService(Module *o, const Anope::string &n) : Service(o, NAME, n) { }
+
+ virtual void Init(Socket *s) anope_abstract;
};
+
diff --git a/include/modules/suspend.h b/include/modules/suspend.h
deleted file mode 100644
index c5255b317..000000000
--- a/include/modules/suspend.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *
- * (C) 2003-2016 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.
- */
-
-struct SuspendInfo
-{
- Anope::string what, by, reason;
- time_t when, expires;
-
- SuspendInfo() { }
- virtual ~SuspendInfo() { }
-};
diff --git a/include/modules/xmlrpc.h b/include/modules/xmlrpc.h
index 87fa353ed..2e943f70f 100644
--- a/include/modules/xmlrpc.h
+++ b/include/modules/xmlrpc.h
@@ -1,11 +1,24 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+#pragma once
+
#include "httpd.h"
class XMLRPCRequest
@@ -17,7 +30,7 @@ class XMLRPCRequest
Anope::string id;
std::deque<Anope::string> data;
HTTPReply& r;
-
+
XMLRPCRequest(HTTPReply &_r) : r(_r) { }
inline void reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.insert(std::make_pair(dname, ddata)); }
inline const std::map<Anope::string, Anope::string> &get_replies() { return this->replies; }
@@ -29,19 +42,22 @@ class XMLRPCEvent
{
public:
virtual ~XMLRPCEvent() { }
- virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) = 0;
+ virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) anope_abstract;
};
class XMLRPCServiceInterface : public Service
{
public:
- XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "XMLRPCServiceInterface", sname) { }
+ static constexpr const char *NAME = "XMLRPCServiceInterface";
+
+ XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, NAME) { }
- virtual void Register(XMLRPCEvent *event) = 0;
+ virtual void Register(XMLRPCEvent *event) anope_abstract;
- virtual void Unregister(XMLRPCEvent *event) = 0;
+ virtual void Unregister(XMLRPCEvent *event) anope_abstract;
- virtual Anope::string Sanitize(const Anope::string &string) = 0;
+ virtual Anope::string Sanitize(const Anope::string &string) anope_abstract;
- virtual void Reply(XMLRPCRequest &request) = 0;
+ virtual void Reply(XMLRPCRequest &request) anope_abstract;
};
+
diff --git a/include/opertype.h b/include/opertype.h
index 3727bdb2c..da8460e44 100644
--- a/include/opertype.h
+++ b/include/opertype.h
@@ -1,39 +1,64 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef OPERTYPE_H
-#define OPERTYPE_H
+#pragma once
#include "services.h"
-#include "account.h"
+#include "serialize.h"
-/* A services operator. Usually made by the configuration file, but not always.
- * NickAlias::Find(name)->nc->o == this
- */
-struct CoreExport Oper
+class Oper : public Serialize::Object
{
- /* The oper's nick */
- Anope::string name;
- /* The type of operator this operator is */
- OperType *ot;
- /* Whether the user must be an IRC operator (umode +o) to be considered a services operator */
- bool require_oper;
- Anope::string password;
- Anope::string certfp;
- /* Hosts allowed to use this operator block */
- std::vector<Anope::string> hosts;
- Anope::string vhost;
-
- Oper(const Anope::string &n, OperType *o);
- virtual ~Oper();
-
- static std::vector<Oper *> opers;
-
+ friend class OperBlockType;
+
+ Anope::string name, password, certfp, host, vhost, type;
+ bool require_oper = false;
+
+ public:
+ static constexpr const char *const NAME = "oper";
+
+ Configuration::Conf *conf = nullptr;
+ Module *owner = nullptr;
+
+ using Serialize::Object::Object;
+
+ Anope::string GetName();
+ void SetName(const Anope::string &);
+
+ Anope::string GetPassword();
+ void SetPassword(const Anope::string &);
+
+ Anope::string GetCertFP();
+ void SetCertFP(const Anope::string &);
+
+ Anope::string GetHost();
+ void SetHost(const Anope::string &);
+
+ Anope::string GetVhost();
+ void SetVhost(const Anope::string &);
+
+ OperType *GetType();
+ void SetType(OperType *);
+
+ bool GetRequireOper();
+ void SetRequireOper(const bool &);
+
/** Find an oper block by name
* @param name The name
* @return the oper block
@@ -41,6 +66,24 @@ struct CoreExport Oper
static Oper *Find(const Anope::string &name);
};
+class OperBlockType : public Serialize::Type<Oper>
+{
+ public:
+ Serialize::Field<Oper, Anope::string> name, password, certfp, host, vhost, type;
+ Serialize::Field<Oper, bool> require_oper;
+
+ OperBlockType() : Serialize::Type<Oper>(nullptr)
+ , name(this, "name", &Oper::name)
+ , password(this, "password", &Oper::password)
+ , certfp(this, "certfp", &Oper::certfp)
+ , host(this, "host", &Oper::host)
+ , vhost(this, "vhost", &Oper::vhost)
+ , type(this, "type", &Oper::type)
+ , require_oper(this, "require_oper", &Oper::require_oper)
+ {
+ }
+};
+
class CoreExport OperType
{
private:
@@ -124,4 +167,3 @@ class CoreExport OperType
const std::list<Anope::string> GetPrivs() const;
};
-#endif // OPERTYPE_H
diff --git a/include/protocol.h b/include/protocol.h
index d8029d53d..4fdc97f0c 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -1,21 +1,30 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef PROTOCOL_H
-#define PROTOCOL_H
+#pragma once
#include "services.h"
#include "anope.h"
#include "service.h"
+class IRCMessage;
+
/* Encapsultes the IRCd protocol we are speaking. */
class CoreExport IRCDProto : public Service
{
@@ -24,6 +33,8 @@ class CoreExport IRCDProto : public Service
protected:
IRCDProto(Module *creator, const Anope::string &proto_name);
public:
+ static constexpr const char *NAME = "ircdproto";
+
virtual ~IRCDProto();
virtual void SendSVSKillInternal(const MessageSource &, User *, const Anope::string &);
@@ -40,7 +51,7 @@ class CoreExport IRCDProto : public Service
const Anope::string &GetProtocolName();
virtual void Parse(const Anope::string &, Anope::string &, Anope::string &, std::vector<Anope::string> &);
- virtual Anope::string Format(const Anope::string &source, const Anope::string &message);
+ virtual Anope::string Format(IRCMessage &);
/* Modes used by default by our clients */
Anope::string DefaultPseudoclientModes;
@@ -104,20 +115,20 @@ class CoreExport IRCDProto : public Service
* @param u The user affected by the akill, if known
* @param x The akill
*/
- virtual void SendAkill(User *, XLine *) = 0;
- virtual void SendAkillDel(const XLine *) = 0;
+ virtual void SendAkill(User *, XLine *) anope_abstract;
+ virtual void SendAkillDel(XLine *) anope_abstract;
/* Realname ban */
- virtual void SendSGLine(User *, const XLine *) { }
- virtual void SendSGLineDel(const XLine *) { }
+ virtual void SendSGLine(User *, XLine *) { }
+ virtual void SendSGLineDel(XLine *) { }
/* IP ban */
- virtual void SendSZLine(User *u, const XLine *) { }
- virtual void SendSZLineDel(const XLine *) { }
+ virtual void SendSZLine(User *u, XLine *) { }
+ virtual void SendSZLineDel(XLine *) { }
/* Nick ban (and sometimes channel) */
- virtual void SendSQLine(User *, const XLine *x) { }
- virtual void SendSQLineDel(const XLine *x) { }
+ virtual void SendSQLine(User *, XLine *x) { }
+ virtual void SendSQLineDel(XLine *x) { }
virtual void SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason);
@@ -134,7 +145,7 @@ class CoreExport IRCDProto : public Service
/** Introduces a client to the rest of the network
* @param u The client to introduce
*/
- virtual void SendClientIntroduction(User *u) = 0;
+ virtual void SendClientIntroduction(User *u) anope_abstract;
virtual void SendKick(const MessageSource &source, const Channel *chan, User *user, const char *fmt, ...);
@@ -143,11 +154,18 @@ class CoreExport IRCDProto : public Service
virtual void SendAction(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
virtual void SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
- virtual void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) = 0;
- virtual void SendGlobalPrivmsg(BotInfo *bi, const Server *desc, const Anope::string &msg) = 0;
+ virtual void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) anope_abstract;
+ virtual void SendGlobalPrivmsg(ServiceBot *bi, const Server *desc, const Anope::string &msg) anope_abstract;
virtual void SendQuit(User *u, const char *fmt, ...);
virtual void SendPing(const Anope::string &servname, const Anope::string &who);
+
+ /**
+ * Send a PONG reply to a received PING.
+ * servname should be left empty to send a one param reply.
+ * @param servname Daemon or client that is responding to the PING.
+ * @param who Origin of the PING and destination of the PONG message.
+ **/
virtual void SendPong(const Anope::string &servname, const Anope::string &who);
/** Joins one of our users to a channel.
@@ -157,7 +175,7 @@ class CoreExport IRCDProto : public Service
* be set on the user. This may include the modes in the join, but will usually place them on the mode
* stacker to be set "soon".
*/
- virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status) = 0;
+ virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status) anope_abstract;
virtual void SendPart(User *u, const Channel *chan, const char *fmt, ...);
/** Force joins a user that isn't ours to a channel.
@@ -181,7 +199,7 @@ class CoreExport IRCDProto : public Service
/** Sets oper flags on a user, currently only supported by Unreal
*/
- virtual void SendSVSO(BotInfo *, const Anope::string &, const Anope::string &) { }
+ virtual void SendSVSO(ServiceBot *, const Anope::string &, const Anope::string &) { }
/** Sends a nick change of one of our clients.
*/
@@ -194,8 +212,8 @@ class CoreExport IRCDProto : public Service
/** Used to introduce ourselves to our uplink. Usually will SendServer(Me) and any other
* initial handshake requirements.
*/
- virtual void SendConnect() = 0;
-
+ virtual void SendConnect() anope_abstract;
+
/** Called right before we begin our burst, after we have handshaked successfully with the uplink/
* At this point none of our servesr, users, or channels exist on the uplink
*/
@@ -209,13 +227,13 @@ class CoreExport IRCDProto : public Service
/** Introduces a server to the uplink
*/
- virtual void SendServer(const Server *) = 0;
+ virtual void SendServer(const Server *) anope_abstract;
virtual void SendSquit(Server *, const Anope::string &message);
virtual void SendNumeric(int numeric, const Anope::string &dest, const char *fmt, ...);
- virtual void SendLogin(User *u, NickAlias *na) = 0;
- virtual void SendLogout(User *u) = 0;
+ virtual void SendLogin(User *u, NickServ::Nick *na) anope_abstract;
+ virtual void SendLogout(User *u) anope_abstract;
/** Send a channel creation message to the uplink.
* On most TS6 IRCds this is a SJOIN with no nick
@@ -256,9 +274,10 @@ class CoreExport MessageSource
MessageSource(User *u);
MessageSource(Server *s);
const Anope::string &GetName() const;
+ const Anope::string &GetUID() const;
const Anope::string &GetSource() const;
User *GetUser() const;
- BotInfo *GetBot() const;
+ ServiceBot *GetBot() const;
Server *GetServer() const;
};
@@ -275,9 +294,11 @@ class CoreExport IRCDMessage : public Service
unsigned param_count;
std::set<IRCDMessageFlag> flags;
public:
+ static constexpr const char *NAME = "IRCDMessage";
+
IRCDMessage(Module *owner, const Anope::string &n, unsigned p = 0);
unsigned GetParamCount() const;
- virtual void Run(MessageSource &, const std::vector<Anope::string> &params) = 0;
+ virtual void Run(MessageSource &, const std::vector<Anope::string> &params) anope_abstract;
void SetFlag(IRCDMessageFlag f) { flags.insert(f); }
bool HasFlag(IRCDMessageFlag f) const { return flags.count(f); }
@@ -285,4 +306,58 @@ class CoreExport IRCDMessage : public Service
extern CoreExport IRCDProto *IRCD;
-#endif // PROTOCOL_H
+class IRCMessage
+{
+ MessageSource source;
+ Anope::string command;
+ std::vector<Anope::string> parameters;
+
+ void Push() { }
+
+ public:
+ template<typename... Args>
+ IRCMessage(const MessageSource &_source, const Anope::string &_command, Args&&... args)
+ : source(_source)
+ , command(_command)
+ {
+ parameters.reserve(sizeof...(args));
+
+ Push(std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ void Push(const T& t, Args&&... args)
+ {
+ parameters.push_back(stringify(t));
+
+ Push(std::forward<Args>(args)...);
+ }
+
+ void TokenizeAndPush(const Anope::string &buf, char sepToken = ' ')
+ {
+ sepstream sep(buf, sepToken);
+ Anope::string token;
+ while (sep.GetToken(token))
+ Push(token);
+ }
+
+ const MessageSource &GetSource() const
+ {
+ return source;
+ }
+
+ void SetSource(const MessageSource &source)
+ {
+ this->source = source;
+ }
+
+ const Anope::string &GetCommand() const
+ {
+ return command;
+ }
+
+ const std::vector<Anope::string> &GetParameters() const
+ {
+ return parameters;
+ }
+};
diff --git a/include/pstdint.h b/include/pstdint.h
deleted file mode 100644
index a8de63fd7..000000000
--- a/include/pstdint.h
+++ /dev/null
@@ -1,800 +0,0 @@
-/* A portable stdint.h
- ****************************************************************************
- * BSD License:
- ****************************************************************************
- *
- * Copyright (c) 2005-2011 Paul Hsieh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************
- *
- * Version 0.1.12
- *
- * The ANSI C standard committee, for the C99 standard, specified the
- * inclusion of a new standard include file called stdint.h. This is
- * a very useful and long desired include file which contains several
- * very precise definitions for integer scalar types that is
- * critically important for making portable several classes of
- * applications including cryptography, hashing, variable length
- * integer libraries and so on. But for most developers its likely
- * useful just for programming sanity.
- *
- * The problem is that most compiler vendors have decided not to
- * implement the C99 standard, and the next C++ language standard
- * (which has a lot more mindshare these days) will be a long time in
- * coming and its unknown whether or not it will include stdint.h or
- * how much adoption it will have. Either way, it will be a long time
- * before all compilers come with a stdint.h and it also does nothing
- * for the extremely large number of compilers available today which
- * do not include this file, or anything comparable to it.
- *
- * So that's what this file is all about. Its an attempt to build a
- * single universal include file that works on as many platforms as
- * possible to deliver what stdint.h is supposed to. A few things
- * that should be noted about this file:
- *
- * 1) It is not guaranteed to be portable and/or present an identical
- * interface on all platforms. The extreme variability of the
- * ANSI C standard makes this an impossibility right from the
- * very get go. Its really only meant to be useful for the vast
- * majority of platforms that possess the capability of
- * implementing usefully and precisely defined, standard sized
- * integer scalars. Systems which are not intrinsically 2s
- * complement may produce invalid constants.
- *
- * 2) There is an unavoidable use of non-reserved symbols.
- *
- * 3) Other standard include files are invoked.
- *
- * 4) This file may come in conflict with future platforms that do
- * include stdint.h. The hope is that one or the other can be
- * used with no real difference.
- *
- * 5) In the current version, if your platform can't represent
- * int32_t, int16_t and int8_t, it just dumps out with a compiler
- * error.
- *
- * 6) 64 bit integers may or may not be defined. Test for their
- * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
- * Note that this is different from the C99 specification which
- * requires the existence of 64 bit support in the compiler. If
- * this is not defined for your platform, yet it is capable of
- * dealing with 64 bits then it is because this file has not yet
- * been extended to cover all of your system's capabilities.
- *
- * 7) (u)intptr_t may or may not be defined. Test for its presence
- * with the test: #ifdef PTRDIFF_MAX. If this is not defined
- * for your platform, then it is because this file has not yet
- * been extended to cover all of your system's capabilities, not
- * because its optional.
- *
- * 8) The following might not been defined even if your platform is
- * capable of defining it:
- *
- * WCHAR_MIN
- * WCHAR_MAX
- * (u)int64_t
- * PTRDIFF_MIN
- * PTRDIFF_MAX
- * (u)intptr_t
- *
- * 9) The following have not been defined:
- *
- * WINT_MIN
- * WINT_MAX
- *
- * 10) The criteria for defining (u)int_least(*)_t isn't clear,
- * except for systems which don't have a type that precisely
- * defined 8, 16, or 32 bit types (which this include file does
- * not support anyways). Default definitions have been given.
- *
- * 11) The criteria for defining (u)int_fast(*)_t isn't something I
- * would trust to any particular compiler vendor or the ANSI C
- * committee. It is well known that "compatible systems" are
- * commonly created that have very different performance
- * characteristics from the systems they are compatible with,
- * especially those whose vendors make both the compiler and the
- * system. Default definitions have been given, but its strongly
- * recommended that users never use these definitions for any
- * reason (they do *NOT* deliver any serious guarantee of
- * improved performance -- not in this file, nor any vendor's
- * stdint.h).
- *
- * 12) The following macros:
- *
- * PRINTF_INTMAX_MODIFIER
- * PRINTF_INT64_MODIFIER
- * PRINTF_INT32_MODIFIER
- * PRINTF_INT16_MODIFIER
- * PRINTF_LEAST64_MODIFIER
- * PRINTF_LEAST32_MODIFIER
- * PRINTF_LEAST16_MODIFIER
- * PRINTF_INTPTR_MODIFIER
- *
- * are strings which have been defined as the modifiers required
- * for the "d", "u" and "x" printf formats to correctly output
- * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
- * (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
- * PRINTF_INTPTR_MODIFIER is not defined for some systems which
- * provide their own stdint.h. PRINTF_INT64_MODIFIER is not
- * defined if INT64_MAX is not defined. These are an extension
- * beyond what C99 specifies must be in stdint.h.
- *
- * In addition, the following macros are defined:
- *
- * PRINTF_INTMAX_HEX_WIDTH
- * PRINTF_INT64_HEX_WIDTH
- * PRINTF_INT32_HEX_WIDTH
- * PRINTF_INT16_HEX_WIDTH
- * PRINTF_INT8_HEX_WIDTH
- * PRINTF_INTMAX_DEC_WIDTH
- * PRINTF_INT64_DEC_WIDTH
- * PRINTF_INT32_DEC_WIDTH
- * PRINTF_INT16_DEC_WIDTH
- * PRINTF_INT8_DEC_WIDTH
- *
- * Which specifies the maximum number of characters required to
- * print the number of that type in either hexadecimal or decimal.
- * These are an extension beyond what C99 specifies must be in
- * stdint.h.
- *
- * Compilers tested (all with 0 warnings at their highest respective
- * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
- * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
- * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
- *
- * This file should be considered a work in progress. Suggestions for
- * improvements, especially those which increase coverage are strongly
- * encouraged.
- *
- * Acknowledgements
- *
- * The following people have made significant contributions to the
- * development and testing of this file:
- *
- * Chris Howie
- * John Steele Scott
- * Dave Thorup
- * John Dill
- *
- */
-
-#include <stddef.h>
-#include <limits.h>
-#include <signal.h>
-
-/*
- * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
- * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
- */
-
-#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
-#include <stdint.h>
-#define _PSTDINT_H_INCLUDED
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-# endif
-# ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-# endif
-# ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-# endif
-# ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-# endif
-# ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "20"
-# endif
-# ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-# endif
-# ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-# endif
-# ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
-# endif
-
-/*
- * Something really weird is going on with Open Watcom. Just pull some of
- * these duplicated definitions from Open Watcom's stdint.h file for now.
- */
-
-# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
-# if !defined (INT64_C)
-# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
-# endif
-# if !defined (UINT64_C)
-# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
-# endif
-# if !defined (INT32_C)
-# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
-# endif
-# if !defined (UINT32_C)
-# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
-# endif
-# if !defined (INT16_C)
-# define INT16_C(x) (x)
-# endif
-# if !defined (UINT16_C)
-# define UINT16_C(x) (x)
-# endif
-# if !defined (INT8_C)
-# define INT8_C(x) (x)
-# endif
-# if !defined (UINT8_C)
-# define UINT8_C(x) (x)
-# endif
-# if !defined (UINT64_MAX)
-# define UINT64_MAX 18446744073709551615ULL
-# endif
-# if !defined (INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-# endif
-# if !defined (UINT32_MAX)
-# define UINT32_MAX 4294967295UL
-# endif
-# if !defined (INT32_MAX)
-# define INT32_MAX 2147483647L
-# endif
-# if !defined (INTMAX_MAX)
-# define INTMAX_MAX INT64_MAX
-# endif
-# if !defined (INTMAX_MIN)
-# define INTMAX_MIN INT64_MIN
-# endif
-# endif
-#endif
-
-#ifndef _PSTDINT_H_INCLUDED
-#define _PSTDINT_H_INCLUDED
-
-#ifndef SIZE_MAX
-# define SIZE_MAX (~(size_t)0)
-#endif
-
-/*
- * Deduce the type assignments from limits.h under the assumption that
- * integer sizes in bits are powers of 2, and follow the ANSI
- * definitions.
- */
-
-#ifndef UINT8_MAX
-# define UINT8_MAX 0xff
-#endif
-#ifndef uint8_t
-# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
- typedef unsigned char uint8_t;
-# define UINT8_C(v) ((uint8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef INT8_MAX
-# define INT8_MAX 0x7f
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN INT8_C(0x80)
-#endif
-#ifndef int8_t
-# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
- typedef signed char int8_t;
-# define INT8_C(v) ((int8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef UINT16_MAX
-# define UINT16_MAX 0xffff
-#endif
-#ifndef uint16_t
-#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
- typedef unsigned int uint16_t;
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-# define UINT16_C(v) ((uint16_t) (v))
-#elif (USHRT_MAX == UINT16_MAX)
- typedef unsigned short uint16_t;
-# define UINT16_C(v) ((uint16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT16_MAX
-# define INT16_MAX 0x7fff
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN INT16_C(0x8000)
-#endif
-#ifndef int16_t
-#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
- typedef signed int int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT16_MAX)
- typedef signed short int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef UINT32_MAX
-# define UINT32_MAX (0xffffffffUL)
-#endif
-#ifndef uint32_t
-#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
- typedef unsigned long uint32_t;
-# define UINT32_C(v) v ## UL
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (UINT_MAX == UINT32_MAX)
- typedef unsigned int uint32_t;
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-# define UINT32_C(v) v ## U
-#elif (USHRT_MAX == UINT32_MAX)
- typedef unsigned short uint32_t;
-# define UINT32_C(v) ((unsigned short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT32_MAX
-# define INT32_MAX (0x7fffffffL)
-#endif
-#ifndef INT32_MIN
-# define INT32_MIN INT32_C(0x80000000)
-#endif
-#ifndef int32_t
-#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
- typedef signed long int32_t;
-# define INT32_C(v) v ## L
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (INT_MAX == INT32_MAX)
- typedef signed int int32_t;
-# define INT32_C(v) v
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT32_MAX)
- typedef signed short int32_t;
-# define INT32_C(v) ((short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-/*
- * The macro stdint_int64_defined is temporarily used to record
- * whether or not 64 integer support is available. It must be
- * defined for any 64 integer extensions for new platforms that are
- * added.
- */
-
-#undef stdint_int64_defined
-#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
-# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# endif
-#endif
-
-#if !defined (stdint_int64_defined)
-# if defined(__GNUC__)
-# define stdint_int64_defined
- __extension__ typedef long long int64_t;
- __extension__ typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
-# define stdint_int64_defined
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
-# define UINT64_C(v) v ## UI64
-# define INT64_C(v) v ## I64
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "I64"
-# endif
-# endif
-#endif
-
-#if !defined (LONG_LONG_MAX) && defined (INT64_C)
-# define LONG_LONG_MAX INT64_C (9223372036854775807)
-#endif
-#ifndef ULONG_LONG_MAX
-# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
-#endif
-
-#if !defined (INT64_MAX) && defined (INT64_C)
-# define INT64_MAX INT64_C (9223372036854775807)
-#endif
-#if !defined (INT64_MIN) && defined (INT64_C)
-# define INT64_MIN INT64_C (-9223372036854775808)
-#endif
-#if !defined (UINT64_MAX) && defined (INT64_C)
-# define UINT64_MAX UINT64_C (18446744073709551615)
-#endif
-
-/*
- * Width of hexadecimal for number field.
- */
-
-#ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-#endif
-#ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-#endif
-#ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-#endif
-#ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-#endif
-
-#ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "20"
-#endif
-#ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-#endif
-#ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-#endif
-#ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-#endif
-
-/*
- * Ok, lets not worry about 128 bit integers for now. Moore's law says
- * we don't need to worry about that until about 2040 at which point
- * we'll have bigger things to worry about.
- */
-
-#ifdef stdint_int64_defined
- typedef int64_t intmax_t;
- typedef uint64_t uintmax_t;
-# define INTMAX_MAX INT64_MAX
-# define INTMAX_MIN INT64_MIN
-# define UINTMAX_MAX UINT64_MAX
-# define UINTMAX_C(v) UINT64_C(v)
-# define INTMAX_C(v) INT64_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
-# endif
-#else
- typedef int32_t intmax_t;
- typedef uint32_t uintmax_t;
-# define INTMAX_MAX INT32_MAX
-# define UINTMAX_MAX UINT32_MAX
-# define UINTMAX_C(v) UINT32_C(v)
-# define INTMAX_C(v) INT32_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
-# endif
-#endif
-
-/*
- * Because this file currently only supports platforms which have
- * precise powers of 2 as bit sizes for the default integers, the
- * least definitions are all trivial. Its possible that a future
- * version of this file could have different definitions.
- */
-
-#ifndef stdint_least_defined
- typedef int8_t int_least8_t;
- typedef uint8_t uint_least8_t;
- typedef int16_t int_least16_t;
- typedef uint16_t uint_least16_t;
- typedef int32_t int_least32_t;
- typedef uint32_t uint_least32_t;
-# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
-# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
-# define UINT_LEAST8_MAX UINT8_MAX
-# define INT_LEAST8_MAX INT8_MAX
-# define UINT_LEAST16_MAX UINT16_MAX
-# define INT_LEAST16_MAX INT16_MAX
-# define UINT_LEAST32_MAX UINT32_MAX
-# define INT_LEAST32_MAX INT32_MAX
-# define INT_LEAST8_MIN INT8_MIN
-# define INT_LEAST16_MIN INT16_MIN
-# define INT_LEAST32_MIN INT32_MIN
-# ifdef stdint_int64_defined
- typedef int64_t int_least64_t;
- typedef uint64_t uint_least64_t;
-# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
-# define UINT_LEAST64_MAX UINT64_MAX
-# define INT_LEAST64_MAX INT64_MAX
-# define INT_LEAST64_MIN INT64_MIN
-# endif
-#endif
-#undef stdint_least_defined
-
-/*
- * The ANSI C committee pretending to know or specify anything about
- * performance is the epitome of misguided arrogance. The mandate of
- * this file is to *ONLY* ever support that absolute minimum
- * definition of the fast integer types, for compatibility purposes.
- * No extensions, and no attempt to suggest what may or may not be a
- * faster integer type will ever be made in this file. Developers are
- * warned to stay away from these types when using this or any other
- * stdint.h.
- */
-
-typedef int_least8_t int_fast8_t;
-typedef uint_least8_t uint_fast8_t;
-typedef int_least16_t int_fast16_t;
-typedef uint_least16_t uint_fast16_t;
-typedef int_least32_t int_fast32_t;
-typedef uint_least32_t uint_fast32_t;
-#define UINT_FAST8_MAX UINT_LEAST8_MAX
-#define INT_FAST8_MAX INT_LEAST8_MAX
-#define UINT_FAST16_MAX UINT_LEAST16_MAX
-#define INT_FAST16_MAX INT_LEAST16_MAX
-#define UINT_FAST32_MAX UINT_LEAST32_MAX
-#define INT_FAST32_MAX INT_LEAST32_MAX
-#define INT_FAST8_MIN INT_LEAST8_MIN
-#define INT_FAST16_MIN INT_LEAST16_MIN
-#define INT_FAST32_MIN INT_LEAST32_MIN
-#ifdef stdint_int64_defined
- typedef int_least64_t int_fast64_t;
- typedef uint_least64_t uint_fast64_t;
-# define UINT_FAST64_MAX UINT_LEAST64_MAX
-# define INT_FAST64_MAX INT_LEAST64_MAX
-# define INT_FAST64_MIN INT_LEAST64_MIN
-#endif
-
-#undef stdint_int64_defined
-
-/*
- * Whatever piecemeal, per compiler thing we can do about the wchar_t
- * type limits.
- */
-
-#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
-# include <wchar.h>
-# ifndef WCHAR_MIN
-# define WCHAR_MIN 0
-# endif
-# ifndef WCHAR_MAX
-# define WCHAR_MAX ((wchar_t)-1)
-# endif
-#endif
-
-/*
- * Whatever piecemeal, per compiler/platform thing we can do about the
- * (u)intptr_t types and limits.
- */
-
-#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-#ifndef STDINT_H_UINTPTR_T_DEFINED
-# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
-# define stdint_intptr_bits 64
-# elif defined (__WATCOMC__) || defined (__TURBOC__)
-# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
-# define stdint_intptr_bits 16
-# else
-# define stdint_intptr_bits 32
-# endif
-# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
-# define stdint_intptr_bits 32
-# elif defined (__INTEL_COMPILER)
-/* TODO -- what did Intel do about x86-64? */
-# endif
-
-# ifdef stdint_intptr_bits
-# define stdint_intptr_glue3_i(a,b,c) a##b##c
-# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
-# ifndef PRINTF_INTPTR_MODIFIER
-# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
-# endif
-# ifndef PTRDIFF_MAX
-# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef PTRDIFF_MIN
-# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef UINTPTR_MAX
-# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MAX
-# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MIN
-# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef INTPTR_C
-# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
-# endif
-# ifndef UINTPTR_C
-# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
-# endif
- typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
- typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
-# else
-/* TODO -- This following is likely wrong for some platforms, and does
- nothing for the definition of uintptr_t. */
- typedef ptrdiff_t intptr_t;
-# endif
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-/*
- * Assumes sig_atomic_t is signed and we have a 2s complement machine.
- */
-
-#ifndef SIG_ATOMIC_MAX
-# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
-#endif
-
-#endif
-
-#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
-
-/*
- * Please compile with the maximum warning settings to make sure macros are not
- * defined more than once.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define glue3_aux(x,y,z) x ## y ## z
-#define glue3(x,y,z) glue3_aux(x,y,z)
-
-#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0);
-#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0);
-
-#define DECL(us,bits) glue3(DECL,us,) (bits)
-
-#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits)
-
-int main () {
- DECL(I,8)
- DECL(U,8)
- DECL(I,16)
- DECL(U,16)
- DECL(I,32)
- DECL(U,32)
-#ifdef INT64_MAX
- DECL(I,64)
- DECL(U,64)
-#endif
- intmax_t imax = INTMAX_C(0);
- uintmax_t umax = UINTMAX_C(0);
- char str0[256], str1[256];
-
- sprintf (str0, "%d %x\n", 0, ~0);
-
- sprintf (str1, "%d %x\n", i8, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1);
- sprintf (str1, "%u %x\n", u8, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1);
- sprintf (str1, "%d %x\n", i16, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1);
- sprintf (str1, "%u %x\n", u16, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1);
- sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1);
- sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1);
-#ifdef INT64_MAX
- sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1);
-#endif
- sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1);
- sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
- if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1);
-
- TESTUMAX(8);
- TESTUMAX(16);
- TESTUMAX(32);
-#ifdef INT64_MAX
- TESTUMAX(64);
-#endif
-
- return EXIT_SUCCESS;
-}
-
-#endif
diff --git a/include/regchannel.h b/include/regchannel.h
deleted file mode 100644
index d4c3e0b59..000000000
--- a/include/regchannel.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- *
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#ifndef REGCHANNEL_H
-#define REGCHANNEL_H
-
-#include "memo.h"
-#include "modes.h"
-#include "extensible.h"
-#include "logger.h"
-#include "modules.h"
-#include "serialize.h"
-#include "bots.h"
-
-typedef Anope::hash_map<ChannelInfo *> registered_channel_map;
-
-extern CoreExport Serialize::Checker<registered_channel_map> RegisteredChannelList;
-
-/* AutoKick data. */
-class CoreExport AutoKick : public Serializable
-{
- public:
- /* Channel this autokick is on */
- Serialize::Reference<ChannelInfo> ci;
-
- Anope::string mask;
- Serialize::Reference<NickCore> nc;
-
- Anope::string reason;
- Anope::string creator;
- time_t addtime;
- time_t last_used;
-
- AutoKick();
- ~AutoKick();
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-};
-
-/* It matters that Base is here before Extensible (it is inherited by Serializable)
- */
-class CoreExport ChannelInfo : public Serializable, public Extensible
-{
- /* channels who reference this one */
- Anope::map<int> references;
- private:
- Serialize::Reference<NickCore> founder; /* Channel founder */
- Serialize::Reference<NickCore> successor; /* Who gets the channel if the founder nick is dropped or expires */
- Serialize::Checker<std::vector<ChanAccess *> > access; /* List of authorized users */
- Serialize::Checker<std::vector<AutoKick *> > akick; /* List of users to kickban */
- Anope::map<int16_t> levels;
-
- public:
- friend class ChanAccess;
- friend class AutoKick;
-
- Anope::string name; /* Channel name */
- Anope::string desc;
-
- time_t time_registered;
- time_t last_used;
-
- Anope::string last_topic; /* The last topic that was set on this channel */
- Anope::string last_topic_setter; /* Setter */
- time_t last_topic_time; /* Time */
-
- Channel::ModeList last_modes; /* The last modes set on this channel */
-
- int16_t bantype;
-
- MemoInfo memos;
-
- Channel *c; /* Pointer to channel, if the channel exists */
-
- /* For BotServ */
- Serialize::Reference<BotInfo> bi; /* Bot used on this channel */
-
- time_t banexpire; /* Time bans expire in */
-
- /** Constructor
- * @param chname The channel name
- */
- ChannelInfo(const Anope::string &chname);
-
- /** Copy constructor
- * @param ci The ChannelInfo to copy settings from
- */
- ChannelInfo(const ChannelInfo &ci);
-
- ~ChannelInfo();
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-
- /** Change the founder of the channek
- * @params nc The new founder
- */
- void SetFounder(NickCore *nc);
-
- /** Get the founder of the channel
- * @return The founder
- */
- NickCore *GetFounder() const;
-
- void SetSuccessor(NickCore *nc);
- NickCore *GetSuccessor() const;
-
- /** Find which bot should send mode/topic/etc changes for this channel
- * @return The bot
- */
- BotInfo *WhoSends() const;
-
- /** Add an entry to the channel access list
- * @param access The entry
- */
- void AddAccess(ChanAccess *access);
-
- /** Get an entry from the channel access list by index
- *
- * @param index The index in the access list vector
- * @return A ChanAccess struct corresponding to the index given, or NULL if outside the bounds
- *
- * Retrieves an entry from the access list that matches the given index.
- */
- ChanAccess *GetAccess(unsigned index) const;
-
- /** Retrieve the access for a user or group in the form of a vector of access entries
- * (as multiple entries can affect a single user).
- */
- AccessGroup AccessFor(const User *u, bool updateLastUsed = true);
- AccessGroup AccessFor(const NickCore *nc, bool updateLastUsed = true);
-
- /** Get the size of the accss vector for this channel
- * @return The access vector size
- */
- unsigned GetAccessCount() const;
-
- /** Get the number of access entries for this channel,
- * including those that are on other channels.
- */
- unsigned GetDeepAccessCount() const;
-
- /** Erase an entry from the channel access list
- *
- * @param index The index in the access list vector
- *
- * @return The erased entry
- */
- ChanAccess *EraseAccess(unsigned index);
-
- /** Clear the entire channel access list
- *
- * Clears the entire access list by deleting every item and then clearing the vector.
- */
- void ClearAccess();
-
- /** Add an akick entry to the channel by NickCore
- * @param user The user who added the akick
- * @param akicknc The nickcore being akicked
- * @param reason The reason for the akick
- * @param t The time the akick was added, defaults to now
- * @param lu The time the akick was last used, defaults to never
- */
- AutoKick* AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0);
-
- /** Add an akick entry to the channel by reason
- * @param user The user who added the akick
- * @param mask The mask of the akick
- * @param reason The reason for the akick
- * @param t The time the akick was added, defaults to now
- * @param lu The time the akick was last used, defaults to never
- */
- AutoKick* AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0);
-
- /** Get an entry from the channel akick list
- * @param index The index in the akick vector
- * @return The akick structure, or NULL if not found
- */
- AutoKick* GetAkick(unsigned index) const;
-
- /** Get the size of the akick vector for this channel
- * @return The akick vector size
- */
- unsigned GetAkickCount() const;
-
- /** Erase an entry from the channel akick list
- * @param index The index of the akick
- */
- void EraseAkick(unsigned index);
-
- /** Clear the whole akick list
- */
- void ClearAkick();
-
- /** Get the level entries for the channel.
- * @return The levels for the channel.
- */
- const Anope::map<int16_t> &GetLevelEntries();
-
- /** Get the level for a privilege
- * @param priv The privilege name
- * @return the level
- * @throws CoreException if priv is not a valid privilege
- */
- int16_t GetLevel(const Anope::string &priv) const;
-
- /** Set the level for a privilege
- * @param priv The privilege priv
- * @param level The new level
- */
- void SetLevel(const Anope::string &priv, int16_t level);
-
- /** Remove a privilege from the channel
- * @param priv The privilege
- */
- void RemoveLevel(const Anope::string &priv);
-
- /** Clear all privileges from the channel
- */
- void ClearLevels();
-
- /** Gets a ban mask for the given user based on the bantype
- * of the channel.
- * @param u The user
- * @return A ban mask that affects the user
- */
- Anope::string GetIdealBan(User *u) const;
-
- /** Finds a ChannelInfo
- * @param name channel name to lookup
- * @return the ChannelInfo associated with the channel
- */
- static ChannelInfo* Find(const Anope::string &name);
-
- void AddChannelReference(const Anope::string &what);
- void RemoveChannelReference(const Anope::string &what);
- void GetChannelReferences(std::deque<Anope::string> &chans);
-};
-
-/** Is the user the real founder?
- * @param user The user
- * @param ci The channel
- * @return true or false
- */
-extern CoreExport bool IsFounder(const User *user, const ChannelInfo *ci);
-
-#endif // REGCHANNEL_H
diff --git a/include/regexpr.h b/include/regexpr.h
deleted file mode 100644
index 1ad4bc81e..000000000
--- a/include/regexpr.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *
- * (C) 2003-2016 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.
- */
-
-#ifndef REGEXPR_H
-#define REGEXPR_H
-
-#include "services.h"
-#include "anope.h"
-#include "service.h"
-
-class RegexException : public CoreException
-{
- public:
- RegexException(const Anope::string &reason = "") : CoreException(reason) { }
-
- virtual ~RegexException() throw() { }
-};
-
-class CoreExport Regex
-{
- Anope::string expression;
- protected:
- Regex(const Anope::string &expr) : expression(expr) { }
- public:
- virtual ~Regex() { }
- const Anope::string &GetExpression() { return expression; }
- virtual bool Matches(const Anope::string &str) = 0;
-};
-
-class CoreExport RegexProvider : public Service
-{
- public:
- RegexProvider(Module *o, const Anope::string &n) : Service(o, "Regex", n) { }
- virtual Regex *Compile(const Anope::string &) = 0;
-};
-
-#endif // REGEXPR_H
diff --git a/include/serialize.h b/include/serialize.h
index bbc7acba7..8fbeb6615 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -1,335 +1,909 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SERIALIZE_H
-#define SERIALIZE_H
-
-#include <sstream>
+#pragma once
#include "anope.h"
#include "base.h"
+#include "extensible.h"
+#include "event.h"
namespace Serialize
{
- class Data
- {
- public:
- enum Type
- {
- DT_TEXT,
- DT_INT
- };
+ class Object;
+
+ class TypeBase;
+
+ class FieldBase;
+ template<typename> class FieldTypeBase;
+ template<typename, typename> class CommonFieldBase;
+ template<typename, typename> class Field;
+ template<typename, typename> class ObjectField;
+
+ template<typename T, typename> class Type;
+ template<typename T> class Reference;
+
+ // by id
+ extern std::unordered_map<ID, Object *> objects;
+ extern std::vector<FieldBase *> serializableFields;
+
+ extern Object *GetID(ID id);
+
+ template<typename T>
+ inline T GetObject();
+
+ template<typename T>
+ inline std::vector<T> GetObjects(const Anope::string &name);
- virtual ~Data() { }
+ template<typename T>
+ inline std::vector<T> GetObjects();
- virtual std::iostream& operator[](const Anope::string &key) = 0;
- virtual std::set<Anope::string> KeySet() const { throw CoreException("Not supported"); }
- virtual size_t Hash() const { throw CoreException("Not supported"); }
+ template<typename T>
+ inline T New();
- virtual void SetType(const Anope::string &key, Type t) { }
- virtual Type GetType(const Anope::string &key) const { return DT_TEXT; }
+ extern void Clear();
+
+ extern void Unregister(Module *);
+
+ struct Edge
+ {
+ Object *other;
+ FieldBase *field;
+ bool direction;
+
+ Edge(Object *o, FieldBase *f, bool d) : other(o), field(f), direction(d) { }
+
+ bool operator==(const Edge &e) const
+ {
+ return other == e.other && field == e.field && direction == e.direction;
+ }
};
- extern void RegisterTypes();
- extern void CheckTypes();
+ extern std::multimap<Anope::string, Anope::string> child_types;
- class Type;
- template<typename T> class Checker;
- template<typename T> class Reference;
+ extern void SetParent(const Anope::string &child, const Anope::string &parent);
+
+ extern std::vector<Serialize::TypeBase *> GetTypes(const Anope::string &name);
}
-/** A serialziable object. Serializable objects can be serialized into
- * abstract data types (Serialize::Data), and then reconstructed or
- * updated later at any time.
- */
-class CoreExport Serializable : public virtual Base
+class CoreExport Serialize::Object : public Extensible, public virtual Base
{
private:
- /* A list of every serializable item in Anope.
- * Some of these are static and constructed at runtime,
- * so this list must be on the heap, as it is not always
- * constructed before other objects are if it isn't.
- */
- static std::list<Serializable *> *SerializableItems;
- friend class Serialize::Type;
+ friend class Serialize::FieldBase;
+
/* The type of item this object is */
- Serialize::Type *s_type;
- /* Iterator into serializable_items */
- std::list<Serializable *>::iterator s_iter;
- /* The hash of the last serialized form of this object committed to the database */
- size_t last_commit;
- /* The last time this object was committed to the database */
- time_t last_commit_time;
+ TypeBase *s_type;
- protected:
- Serializable(const Anope::string &serialize_type);
- Serializable(const Serializable &);
+ std::map<TypeBase *, std::vector<Edge>> edges;
- Serializable &operator=(const Serializable &);
+ std::vector<Edge> GetRefs(TypeBase *);
public:
- virtual ~Serializable();
+ Object(TypeBase *type);
+ Object(TypeBase *type, ID);
+
+ virtual ~Object();
+
+ virtual void Delete();
- /* Unique ID (per type, not globally) for this object */
- uint64_t id;
+ /* Unique ID for this object */
+ ID id;
- /* Only used by redis, to ignore updates */
- unsigned short redis_ignore;
+ void AddEdge(Object *other, FieldBase *field);
- /** Marks the object as potentially being updated "soon".
+ void RemoveEdge(Object *other, FieldBase *field);
+
+ /**
+ * Get an object of type T that this object references.
*/
- void QueueUpdate();
+ template<typename T>
+ T GetRef()
+ {
+ std::vector<T> t = GetRefs<T>();
+ return !t.empty() ? t[0] : nullptr;
+ }
+
+ /**
+ * Gets all objects of type T that this object references
+ */
+ template<typename T>
+ std::vector<T> GetRefs();
- bool IsCached(Serialize::Data &);
- void UpdateCache(Serialize::Data &);
+ /**
+ * Get the value of a field on this object.
+ */
+ template<
+ typename Type,
+ template<typename, typename> class Field, // Field type being read
+ typename TypeImpl,
+ typename T // type of the Extensible
+ >
+ T Get(Field<TypeImpl, T> Type::*field)
+ {
+ static_assert(std::is_base_of<Object, TypeImpl>::value, "");
+ static_assert(std::is_base_of<Serialize::TypeBase, Type>::value, "");
+
+ Type *t = static_cast<Type *>(s_type);
+ Field<TypeImpl, T>& f = t->*field;
+ return f.GetField(f.Upcast(this));
+ }
- bool IsTSCached();
- void UpdateTS();
+ /**
+ * Get the value of a field on this object. Allows specifying return
+ * type if the return type can't be inferred.
+ */
+ template<typename Ret, typename Field, typename Type>
+ Ret Get(Field Type::*field)
+ {
+ static_assert(std::is_base_of<Serialize::TypeBase, Type>::value, "");
+
+ Type *t = static_cast<Type *>(s_type);
+ Field& f = t->*field;
+ return f.GetField(f.Upcast(this));
+ }
+
+ /**
+ * Set the value of a field on this object
+ */
+ template<
+ typename Type,
+ template<typename, typename> class Field,
+ typename TypeImpl,
+ typename T
+ >
+ void Set(Field<TypeImpl, T> Type::*field, const T& value)
+ {
+ static_assert(std::is_base_of<Object, TypeImpl>::value, "");
+ static_assert(std::is_base_of<Serialize::TypeBase, Type>::value, "");
+
+ Type *t = static_cast<Type *>(s_type);
+ Field<TypeImpl, T>& f = t->*field;
+ f.SetField(f.Upcast(this), value);
+ }
+
+ /**
+ * Set the value of a field on this object
+ */
+ template<typename Field, typename Type, typename T>
+ void Set(Field Type::*field, const T& value)
+ {
+ static_assert(std::is_base_of<Serialize::TypeBase, Type>::value, "");
+
+ Type *t = static_cast<Type *>(s_type);
+ Field& f = t->*field;
+ f.SetField(f.Upcast(this), value);
+ }
/** Get the type of serializable object this is
* @return The serializable object type
*/
- Serialize::Type* GetSerializableType() const { return this->s_type; }
+ TypeBase* GetSerializableType() const { return this->s_type; }
- virtual void Serialize(Serialize::Data &data) const = 0;
+ /** Set the value of a field on this object, by field name
+ */
+ template<typename T>
+ void SetS(const Anope::string &name, const T &what);
- static const std::list<Serializable *> &GetItems();
+ /** Unset a field on this object, by field name
+ */
+ template<typename T>
+ void UnsetS(const Anope::string &name);
+
+ /** Test if a field is set. Only useful with extensible fields,
+ * which can unset (vs set to the default value)
+ */
+ bool HasFieldS(const Anope::string &name);
};
-/* A serializable type. There should be one of these classes for each type
- * of class that inherits from Serialiable. Used for unserializing objects
- * of this type, as it requires a function pointer to a static member function.
- */
-class CoreExport Serialize::Type : public Base
+class CoreExport Serialize::TypeBase : public Service
{
- typedef Serializable* (*unserialize_func)(Serializable *obj, Serialize::Data &);
-
- static std::vector<Anope::string> TypeOrder;
- static std::map<Anope::string, Serialize::Type *> Types;
-
- /* The name of this type, should be a class name */
Anope::string name;
- unserialize_func unserialize;
+
/* Owner of this type. Used for placing objects of this type in separate databases
* based on what module, if any, owns it.
*/
Module *owner;
- /* The timesatmp for this type. All objects of this type are as up to date as
- * this timestamp. if curtime == timestamp then we have the most up to date
- * version of every object of this type.
- */
- time_t timestamp;
-
public:
- /* Map of Serializable::id to Serializable objects */
- std::map<uint64_t, Serializable *> objects;
+ static constexpr const char *NAME = "typebase";
+
+ std::set<Object *> objects;
- /** Creates a new serializable type
- * @param n Type name
- * @param f Func to unserialize objects
- * @param owner Owner of this type. Leave NULL for the core.
- */
- Type(const Anope::string &n, unserialize_func f, Module *owner = NULL);
- ~Type();
+ TypeBase(Module *owner, const Anope::string &n);
+ ~TypeBase();
+
+ void Unregister();
/** Gets the name for this type
* @return The name, eg "NickAlias"
*/
const Anope::string &GetName() { return this->name; }
- /** Unserialized an object.
- * @param obj NULL if this object doesn't yet exist. If this isn't NULL, instead
- * update the contents of this object.
- * @param data The data to unserialize
- * @return The unserialized object. If obj != NULL this should be obj.
+ /**
+ * Get all objects of the given type
+ */
+ template<typename T>
+ std::vector<T> List()
+ {
+ std::vector<ID> ids;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeList, this, ids);
+ if (result == EVENT_ALLOW)
+ {
+ std::vector<T> o;
+ for (ID id : ids)
+ {
+ Object *s = Require(id);
+ if (s)
+ o.push_back(anope_dynamic_static_cast<T>(s));
+ }
+ return o;
+ }
+
+ return GetObjects<T>();
+ }
+
+ /** Create a new object of this type.
*/
- Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
+ virtual Object *Create() anope_abstract;
- /** Check if this object type has any pending changes and update them.
+ /** Get or otherwise create an object of this type
+ * with the given ID.
*/
- void Check();
+ virtual Object *Require(Serialize::ID) anope_abstract;
- /** Gets the timestamp for the object type. That is, the time we know
- * all objects of this type are updated at least to.
+ /** Find a field on this type
*/
- time_t GetTimestamp() const;
+ FieldBase *GetField(const Anope::string &name);
- /** Bumps object type timestamp to current time
+ /** Get all fields of this type
*/
- void UpdateTimestamp();
+ std::vector<FieldBase *> GetFields();
Module* GetOwner() const { return this->owner; }
- static Serialize::Type *Find(const Anope::string &name);
+ static TypeBase *Find(const Anope::string &name);
+
+ static const std::map<Anope::string, TypeBase *>& GetTypes();
+};
+
+template<typename T, typename Base = Serialize::TypeBase>
+class Serialize::Type : public Base
+{
+ public:
+ Type(Module *module) : Base(module, T::NAME) { }
+ Type(Module *module, const Anope::string &name) : Base(module, name) { }
+
+ Object *Create() override
+ {
+ return new T(this);
+ }
+
+ Object *Require(Serialize::ID id) override
+ {
+ return RequireID(id);
+ }
+
+ T* RequireID(ID id)
+ {
+ Object *s = Serialize::GetID(id);
+ if (s == nullptr)
+ return new T(this, id);
- static const std::vector<Anope::string> &GetTypeOrder();
+ if (s->GetSerializableType() != this)
+ return nullptr;
- static const std::map<Anope::string, Serialize::Type *>& GetTypes();
+ return static_cast<T *>(s);
+ }
};
-/** Should be used to hold lists and other objects of a specific type,
- * but not a specific object. Used for ensuring that any access to
- * this object type is always up to date. These are usually constructed
- * at run time, before main is called, so no types are registered. This
- * is why there are static Serialize::Type* variables in every function.
+/** A reference to a serializable object. Serializable objects may not always
+ * exist in memory at all times, like if they exist in an external database,
+ * so you can't hold pointers to them. Instead, hold a Serialize::Reference
+ * which will properly fetch the object on demand from the underlying database
+ * system.
*/
template<typename T>
-class Serialize::Checker
+class Serialize::Reference
{
- Anope::string name;
- T obj;
- mutable ::Reference<Serialize::Type> type;
+ protected:
+ bool valid = false;
+ TypeBase *type;
+ /* ID of the object which we reference */
+ ID id;
+
+ public:
+ Serialize::Reference<T>& operator=(T* obj)
+ {
+ if (obj != nullptr)
+ {
+ type = obj->GetSerializableType();
+ id = obj->id;
+ valid = true;
+ }
+ else
+ {
+ valid = false;
+ }
+ return *this;
+ }
- inline void Check() const
+ explicit operator bool() const
{
- if (!type)
- type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ return Dereference() != nullptr;
}
+ operator T*() const { return Dereference(); }
+
+ T* operator*() const { return Dereference(); }
+ T* operator->() const { return Dereference(); }
+
+ private:
+ T* Dereference() const
+ {
+ if (!valid)
+ return nullptr;
+
+ Object *targ = GetID(id);
+ if (targ != nullptr && targ->GetSerializableType() == type)
+ return anope_dynamic_static_cast<T*>(targ);
+
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeDeref, id, type);
+ if (result == EVENT_ALLOW)
+ return anope_dynamic_static_cast<T *>(type->Require(id));
+
+ return nullptr;
+ }
+};
+
+/** A field, associated with a type.
+ */
+class Serialize::FieldBase : public Service
+{
public:
- Checker(const Anope::string &n) : name(n), type(NULL) { }
+ static constexpr const char *NAME = "fieldbase";
+
+ Anope::string serialize_type; // type the field is on
+ Anope::string serialize_name; // field name
+
+ /** For fields which reference other Objects. If true, when
+ * the object the field references gets deleted, this object
+ * gets deleted too.
+ */
+ bool depends;
+
+ FieldBase(Module *, const Anope::string &, const Anope::string &, bool);
+ virtual ~FieldBase();
+ void Unregister();
+
+ /** Serialize value of this field on the given object to string form
+ */
+ virtual Anope::string SerializeToString(Object *s) anope_abstract;
+
+ /** Unserialize value of this field on the given object from string form
+ */
+ virtual void UnserializeFromString(Object *s, const Anope::string &) anope_abstract;
+
+ /** Test if the given object has the given field, only usefil for extensible fields
+ */
+ virtual bool HasFieldS(Object *) anope_abstract;
+
+ /** Unset this field on the given object
+ */
+ virtual void UnsetS(Object *) anope_abstract;
+};
+
+template<typename T>
+class Serialize::FieldTypeBase : public FieldBase
+{
+ public:
+ using FieldBase::FieldBase;
+
+ /** Set this field to the given value on the given object.
+ */
+ virtual void SetFieldS(Object *, const T &) anope_abstract;
+};
+
+/** Base class for serializable fields and serializable object fields.
+ */
+template<
+ typename TypeImpl, // Serializable type
+ typename T // actual type of field
+>
+class Serialize::CommonFieldBase : public FieldTypeBase<T>
+{
+ static_assert(std::is_base_of<Object, TypeImpl>::value, "");
+
+ /** Extensible storage for value of fields. Only used if field
+ * isn't set. Note extensible fields can be "unset", where field
+ * pointers are never unset, but are T().
+ */
+ ExtensibleItem<T> *ext = nullptr;
+
+ /** Field pointer to storage in the TypeImpl object for
+ * this field.
+ */
+ T TypeImpl::*field = nullptr;
+
+ protected:
+ /** Set the value of a field in storage
+ */
+ void Set_(TypeImpl *object, const T &value)
+ {
+ if (field != nullptr)
+ object->*field = value;
+ else if (ext != nullptr)
+ ext->Set(object, value);
+ else
+ throw CoreException("No field or ext");
+ }
+
+ /* Get the value of a field from storage
+ */
+ T* Get_(TypeImpl *object)
+ {
+ if (field != nullptr)
+ return &(object->*field);
+ else if (ext != nullptr)
+ return ext->Get(object);
+ else
+ throw CoreException("No field or ext");
+ }
+
+ /** Unset a field from storage
+ */
+ void Unset_(TypeImpl *object)
+ {
+ if (field != nullptr)
+ object->*field = T();
+ else if (ext != nullptr)
+ ext->Unset(object);
+ else
+ throw CoreException("No field or ext");
+ }
+
+ /** Check is a field is set. Only useful for
+ * extensible storage. Returns true for field storage.
+ */
+ bool HasField_(TypeImpl *object)
+ {
+ if (field != nullptr)
+ return true;
+ else if (ext != nullptr)
+ return ext->HasExt(object);
+ else
+ throw CoreException("No field or ext");
+ }
+
+ public:
+ CommonFieldBase(Serialize::TypeBase *t, const Anope::string &n, bool d)
+ : FieldTypeBase<T>(t->GetOwner(), n, t->GetName(), d)
+ {
+ ext = new ExtensibleItem<T>(t->GetOwner(), t->GetName(), n);
+ }
+
+ CommonFieldBase(Module *creator, const Anope::string &n, bool d)
+ : FieldTypeBase<T>(creator, n, TypeImpl::NAME, d)
+ {
+ ext = new ExtensibleItem<T>(creator, TypeImpl::NAME, n);
+ }
- inline const T* operator->() const
+ CommonFieldBase(Serialize::TypeBase *t,
+ const Anope::string &n,
+ T TypeImpl::*f,
+ bool d)
+ : FieldTypeBase<T>(t->GetOwner(), n, t->GetName(), d)
+ , field(f)
{
- this->Check();
- return &this->obj;
}
- inline T* operator->()
+
+ ~CommonFieldBase()
{
- this->Check();
- return &this->obj;
+ delete ext;
}
- inline const T& operator*() const
+ /** Get the value of this field on the given object
+ */
+ virtual T GetField(TypeImpl *) anope_abstract;
+
+ /** Unset this field on the given object
+ */
+ virtual void UnsetField(TypeImpl *) anope_abstract;
+
+ void UnsetS(Object *s) override
{
- this->Check();
- return this->obj;
+ UnsetField(Upcast(s));
}
- inline T& operator*()
+
+ bool HasFieldS(Object *s) override
{
- this->Check();
- return this->obj;
+ return HasField(Upcast(s));
}
- inline operator const T&() const
+ /** Cast a serializable object of type Object to type TypeImpl,
+ * if appropriate
+ */
+ TypeImpl* Upcast(Object *s)
{
- this->Check();
- return this->obj;
+ if (this->serialize_type != s->GetSerializableType()->GetName())
+ {
+ return nullptr;
+ }
+
+ return anope_dynamic_static_cast<TypeImpl *>(s);
}
- inline operator T&()
+
+ bool HasField(TypeImpl *s)
{
- this->Check();
- return this->obj;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeHasField, s, this);
+ if (result != EVENT_CONTINUE)
+ return true;
+
+ return this->HasField_(s);
}
};
-/** Used to hold references to serializable objects. Reference should always be
- * used when holding references to serializable objects for extended periods of time
- * to ensure that the object it refers to it always up to date. This also behaves like
- * Reference in that it will invalidate itself if the object it refers to is
- * destructed.
+/** Class for all fields that aren't to other serializable objects
*/
-template<typename T>
-class Serialize::Reference : public ReferenceBase
+template<typename TypeImpl, typename T>
+class Serialize::Field : public CommonFieldBase<TypeImpl, T>
{
- protected:
- T *ref;
-
public:
- Reference() : ref(NULL)
+ Field(TypeBase *t, const Anope::string &n) : CommonFieldBase<TypeImpl, T>(t, n, false)
{
}
- Reference(T *obj) : ref(obj)
+ Field(Module *creator, const Anope::string &n) : CommonFieldBase<TypeImpl, T>(creator, n, false)
{
- if (obj)
- obj->AddReference(this);
}
- Reference(const Reference<T> &other) : ReferenceBase(other), ref(other.ref)
+ Field(TypeBase *t, const Anope::string &n, T TypeImpl::*f) : CommonFieldBase<TypeImpl, T>(t, n, f, false)
{
- if (ref && !invalid)
- this->ref->AddReference(this);
}
- ~Reference()
+ T GetField(TypeImpl *s) override
{
- if (ref && !invalid)
- this->ref->DelReference(this);
- }
+ T* t = this->Get_(s);
- inline Reference<T>& operator=(const Reference<T> &other)
- {
- if (this != &other)
+ // If we have a non-default value for this field it is up to date and cached
+ if (t && *t != T())
+ return *t;
+
+ // Query modules
+ Anope::string value;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeGet, s, this, value);
+ if (result == EVENT_ALLOW)
{
- if (ref && !invalid)
- this->ref->DelReference(this);
+ // module returned us data, so we unserialize it
+ T t2 = this->Unserialize(value);
- this->ref = other.ref;
- this->invalid = other.invalid;
+ // Cache
+ this->Set_(s, t2);
- if (ref && !invalid)
- this->ref->AddReference(this);
+ return t2;
}
- return *this;
+
+ if (t)
+ return *t;
+
+ return T();
}
- inline operator bool() const
+ void SetFieldS(Object *s, const T &value) override
{
- if (!this->invalid)
- return this->ref != NULL;
- return false;
+ SetField(this->Upcast(s), value);
+ }
+
+ virtual void SetField(TypeImpl *s, const T &value)
+ {
+ Anope::string strvalue = this->Serialize(value);
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeSet, s, this, strvalue);
+
+ this->Set_(s, value);
+ }
+
+ void UnsetField(TypeImpl *s) override
+ {
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeUnset, s, this);
+
+ this->Unset_(s);
}
- inline operator T*() const
+ Anope::string Serialize(const T& t)
{
- if (!this->invalid)
+ try
{
- if (this->ref)
- // This can invalidate me
- this->ref->QueueUpdate();
- if (!this->invalid)
- return this->ref;
+ return stringify(t);
+ }
+ catch (const ConvertException &)
+ {
+ Log(LOG_DEBUG) << "Unable to stringify " << t;
+ return "";
}
- return NULL;
}
- inline T* operator*() const
+ T Unserialize(const Anope::string &str)
{
- if (!this->invalid)
+ if (str.empty())
+ return T();
+
+ try
+ {
+ return convertTo<T>(str);
+ }
+ catch (const ConvertException &)
{
- if (this->ref)
- // This can invalidate me
- this->ref->QueueUpdate();
- if (!this->invalid)
- return this->ref;
+ return T();
}
- return NULL;
}
- inline T* operator->() const
+ Anope::string SerializeToString(Object *s) override
+ {
+ T t = GetField(this->Upcast(s));
+ return this->Serialize(t);
+ }
+
+ void UnserializeFromString(Object *s, const Anope::string &v) override
+ {
+ T t = this->Unserialize(v);
+ SetField(this->Upcast(s), t);
+ }
+
+ void Set(Extensible *obj, const T &value)
+ {
+ TypeImpl *s = anope_dynamic_static_cast<TypeImpl *>(obj);
+ SetField(s, value);
+ }
+
+ void Unset(Extensible *obj)
+ {
+ TypeImpl *s = anope_dynamic_static_cast<TypeImpl *>(obj);
+ this->UnsetField(s);
+ }
+
+ T Get(Extensible *obj)
+ {
+ TypeImpl *s = anope_dynamic_static_cast<TypeImpl *>(obj);
+ return this->GetField(s);
+ }
+
+ bool HasExt(Extensible *obj)
+ {
+ TypeImpl *s = anope_dynamic_static_cast<TypeImpl *>(obj);
+ return this->HasField(s);
+ }
+};
+
+/** Class for all fields that contain a reference to another serializable object.
+ */
+template<typename TypeImpl, typename T>
+class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
+{
+ public:
+ ObjectField(TypeBase *t, const Anope::string &n, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, d)
+ {
+ }
+
+ ObjectField(TypeBase *t, const Anope::string &n, T TypeImpl::*field, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, field, d)
+ {
+ }
+
+ T GetField(TypeImpl *s)
+ {
+ T *t = this->Get_(s);
+ if (t && *t != nullptr)
+ return *t;
+
+ Anope::string type;
+ ID sid;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeGetSerializable, s, this, type, sid);
+ if (result != EVENT_CONTINUE)
+ {
+ Serialize::TypeBase *base = Serialize::TypeBase::Find(type);
+ if (base == nullptr)
+ {
+ Log(LOG_DEBUG_2) << "OnSerializeGetSerializable returned unknown type " << type;
+ return nullptr;
+ }
+
+ T t2 = result == EVENT_ALLOW ? static_cast<T>(base->Require(sid)) : nullptr;
+
+ this->Set_(s, t2);
+
+ return t2;
+ }
+
+ if (t)
+ return *t;
+
+ return T();
+ }
+
+ void SetFieldS(Object *s, const T &value) override
+ {
+ SetField(this->Upcast(s), value);
+ }
+
+ virtual void SetField(TypeImpl *s, T value)
+ {
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeSetSerializable, s, this, value);
+
+ T *old = this->Get_(s);
+ if (old != nullptr && *old != nullptr)
+ s->RemoveEdge(*old, this);
+
+ this->Set_(s, value);
+
+ if (value != nullptr)
+ s->AddEdge(value, this);
+ }
+
+ void UnsetField(TypeImpl *s) override
+ {
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeUnsetSerializable, s, this);
+
+ this->Unset_(s);
+ }
+
+ Anope::string SerializeToString(Object *s) override
+ {
+ T t = GetField(this->Upcast(s));
+ return this->Serialize(t);
+ }
+
+ void UnserializeFromString(Object *s, const Anope::string &v) override
+ {
+ T t = this->Unserialize(v);
+ SetField(this->Upcast(s), t);
+ }
+
+ Anope::string Serialize(const T& t)
{
- if (!this->invalid)
+ return t ? t->GetSerializableType()->GetName() + ":" + stringify(t->id) : "";
+ }
+
+ T Unserialize(const Anope::string &str)
+ {
+ size_t c = str.rfind(':');
+ if (c == Anope::string::npos)
+ return nullptr;
+
+ Anope::string type = str.substr(0, c);
+ ID id;
+ try
{
- if (this->ref)
- // This can invalidate me
- this->ref->QueueUpdate();
- if (!this->invalid)
- return this->ref;
+ id = convertTo<ID>(str.substr(c + 1));
}
- return NULL;
+ catch (const ConvertException &)
+ {
+ return nullptr;
+ }
+
+ TypeBase *t = TypeBase::Find(type);
+ if (!t)
+ {
+ return nullptr;
+ }
+
+ return anope_dynamic_static_cast<T>(t->Require(id));
}
};
-#endif // SERIALIZE_H
+template<typename T>
+T Serialize::GetObject()
+{
+ std::vector<T> v = GetObjects<T>();
+ return v.empty() ? nullptr : v[0];
+}
+
+template<typename T>
+std::vector<T> Serialize::GetObjects(const Anope::string &name)
+{
+ std::vector<T> objs;
+
+ for (TypeBase *t : GetTypes(name))
+ for (Object *s : t->objects)
+ objs.push_back(anope_dynamic_static_cast<T>(s));
+
+ return objs;
+}
+
+template<typename T>
+std::vector<T> Serialize::GetObjects()
+{
+ const char* const name = std::remove_pointer<T>::type::NAME;
+ return GetObjects<T>(name);
+}
+
+template<typename T>
+T Serialize::New()
+{
+ const char* const name = std::remove_pointer<T>::type::NAME;
+ Serialize::TypeBase *type = TypeBase::Find(name);
+
+ if (type == nullptr)
+ {
+ Log(LOG_DEBUG) << "Serialize::New with unknown type " << name;
+ return nullptr;
+ }
+
+ return static_cast<T>(type->Create());
+}
+
+template<typename T>
+std::vector<T> Serialize::Object::GetRefs()
+{
+ const char* const name = std::remove_pointer<T>::type::NAME;
+ std::vector<Serialize::TypeBase *> types = GetTypes(name);
+ std::vector<T> objs;
+
+ if (types.empty())
+ {
+ Log(LOG_DEBUG) << "GetRefs for unknown type on #" << this->id << " type " << s_type->GetName() << " named " << name;
+ return objs;
+ }
+
+ for (Serialize::TypeBase *t : types)
+ for (const Serialize::Edge &edge : GetRefs(t))
+ if (!edge.direction)
+ objs.push_back(anope_dynamic_static_cast<T>(edge.other));
+
+ return objs;
+}
+
+template<typename T>
+void Serialize::Object::SetS(const Anope::string &name, const T &what)
+{
+ FieldBase *field = s_type->GetField(name);
+ if (field == nullptr)
+ {
+ Log(LOG_DEBUG) << "Set for unknown field " << name << " on " << s_type->GetName();
+ return;
+ }
+
+ FieldTypeBase<T> *fieldt = static_cast<FieldTypeBase<T> *>(field);
+ fieldt->SetFieldS(this, what);
+}
+
+template<typename T>
+void Serialize::Object::UnsetS(const Anope::string &name)
+{
+ FieldBase *field = s_type->GetField(name);
+ if (field == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unset for unknown field " << name << " on " << s_type->GetName();
+ return;
+ }
+
+ FieldTypeBase<T> *fieldt = static_cast<FieldTypeBase<T> *>(field);
+ fieldt->UnsetS(this);
+}
+
+inline bool Serialize::Object::HasFieldS(const Anope::string &name)
+{
+ FieldBase *field = s_type->GetField(name);
+ if (field == nullptr)
+ {
+ Log(LOG_DEBUG) << "HasField for unknown field " << name << " on " << s_type->GetName();
+ return false;
+ }
+
+ FieldTypeBase<void *> *fieldt = static_cast<FieldTypeBase<void *> *>(field);
+ return fieldt->HasFieldS(this);
+}
+
diff --git a/include/servers.h b/include/servers.h
index f06acb156..64a265a85 100644
--- a/include/servers.h
+++ b/include/servers.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SERVERS_H
-#define SERVERS_H
+#pragma once
#include "services.h"
#include "anope.h"
@@ -82,6 +89,8 @@ class CoreExport Server : public Extensible
/* Number of users on the server */
unsigned users;
+ void Burst();
+
/** Delete this server with a reason
* @param reason The reason
*/
@@ -174,7 +183,7 @@ class CoreExport Server : public Extensible
* @param source The source of the message
* @param message The message
*/
- void Notice(BotInfo *source, const Anope::string &message);
+ void Notice(ServiceBot *source, const Anope::string &message);
/** Find a server
* @param name The name or SID/numeric
@@ -184,4 +193,3 @@ class CoreExport Server : public Extensible
static Server *Find(const Anope::string &name, bool name_only = false);
};
-#endif // SERVERS_H
diff --git a/include/service.h b/include/service.h
index 9c4d1f172..fd5e2245a 100644
--- a/include/service.h
+++ b/include/service.h
@@ -1,16 +1,24 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2016 Adam <Adam@anope.org>
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SERVICE_H
-#define SERVICE_H
+#pragma once
#include "services.h"
#include "anope.h"
@@ -23,151 +31,145 @@
*/
class CoreExport Service : public virtual Base
{
- static std::map<Anope::string, std::map<Anope::string, Service *> > Services;
- static std::map<Anope::string, std::map<Anope::string, Anope::string> > Aliases;
-
- static Service *FindService(const std::map<Anope::string, Service *> &services, const std::map<Anope::string, Anope::string> *aliases, const Anope::string &n)
- {
- std::map<Anope::string, Service *>::const_iterator it = services.find(n);
- if (it != services.end())
- return it->second;
-
- if (aliases != NULL)
- {
- std::map<Anope::string, Anope::string>::const_iterator it2 = aliases->find(n);
- if (it2 != aliases->end())
- return FindService(services, aliases, it2->second);
- }
-
- return NULL;
- }
+ Module *owner;
+ /* Service type, which should be the class name (eg "Command") */
+ Anope::string type;
+ /* Service name, commands are usually named service/command */
+ Anope::string name;
public:
- static Service *FindService(const Anope::string &t, const Anope::string &n)
- {
- std::map<Anope::string, std::map<Anope::string, Service *> >::const_iterator it = Services.find(t);
- if (it == Services.end())
- return NULL;
+ Service(Module *o, const Anope::string &t, const Anope::string &n);
+
+ Service(Module *o, const Anope::string &t) : Service(o, t, "") { }
- std::map<Anope::string, std::map<Anope::string, Anope::string> >::const_iterator it2 = Aliases.find(t);
- if (it2 != Aliases.end())
- return FindService(it->second, &it2->second, n);
+ virtual ~Service();
- return FindService(it->second, NULL, n);
- }
+ Module *GetOwner() const { return owner; }
- static std::vector<Anope::string> GetServiceKeys(const Anope::string &t)
- {
- std::vector<Anope::string> keys;
- std::map<Anope::string, std::map<Anope::string, Service *> >::iterator it = Services.find(t);
- if (it != Services.end())
- for (std::map<Anope::string, Service *>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
- keys.push_back(it2->first);
- return keys;
- }
+ const Anope::string &GetType() const { return type; }
- static void AddAlias(const Anope::string &t, const Anope::string &n, const Anope::string &v)
- {
- std::map<Anope::string, Anope::string> &smap = Aliases[t];
- smap[n] = v;
- }
+ const Anope::string &GetName() const { return name; }
+};
- static void DelAlias(const Anope::string &t, const Anope::string &n)
- {
- std::map<Anope::string, Anope::string> &smap = Aliases[t];
- smap.erase(n);
- if (smap.empty())
- Aliases.erase(t);
- }
+class ServiceReferenceBase
+{
+ Anope::string type, name;
- Module *owner;
- /* Service type, which should be the class name (eg "Command") */
- Anope::string type;
- /* Service name, commands are usually named service/command */
- Anope::string name;
+ protected:
+ std::vector<Service *> services;
- Service(Module *o, const Anope::string &t, const Anope::string &n) : owner(o), type(t), name(n)
- {
- this->Register();
- }
+ public:
- virtual ~Service()
- {
- this->Unregister();
- }
+ ServiceReferenceBase() = default;
- void Register()
+ ServiceReferenceBase(const Anope::string &_type, const Anope::string &_name);
+ ServiceReferenceBase(const Anope::string &_type);
+
+ virtual ~ServiceReferenceBase();
+
+ explicit operator bool() const
{
- std::map<Anope::string, Service *> &smap = Services[this->type];
- if (smap.find(this->name) != smap.end())
- throw ModuleException("Service " + this->type + " with name " + this->name + " already exists");
- smap[this->name] = this;
+ return !this->services.empty();
}
- void Unregister()
- {
- std::map<Anope::string, Service *> &smap = Services[this->type];
- smap.erase(this->name);
- if (smap.empty())
- Services.erase(this->type);
- }
+ const Anope::string &GetType() const { return type; }
+ const Anope::string &GetName() const { return name; }
+
+ Service *GetService() const { return services.empty() ? nullptr : services[0]; }
+ const std::vector<Service *> &GetServices() const { return services; }
+ void SetService(Service *service);
+ void SetServices(const std::vector<Service *> &s);
};
-/** Like Reference, but used to refer to Services.
- */
template<typename T>
-class ServiceReference : public Reference<T>
+class ServiceReference : public ServiceReferenceBase
{
- Anope::string type;
- Anope::string name;
+ static_assert(std::is_base_of<Service, T>::value, "");
public:
- ServiceReference() { }
+ ServiceReference() : ServiceReferenceBase(T::NAME) { }
+ ServiceReference(const Anope::string &n) : ServiceReferenceBase(T::NAME, n) { }
- ServiceReference(const Anope::string &t, const Anope::string &n) : type(t), name(n)
+ operator T*() const
{
+ return static_cast<T*>(GetService());
}
- inline void operator=(const Anope::string &n)
+ T* operator->() const
{
- this->name = n;
- this->invalid = true;
+ return static_cast<T*>(GetService());
}
- operator bool() anope_override
+ T* operator*() const
{
- if (this->invalid)
- {
- this->invalid = false;
- this->ref = NULL;
- }
- if (!this->ref)
- {
- /* This really could be dynamic_cast in every case, except for when a module
- * creates its own service type (that other modules must include the header file
- * for), as the core is not compiled with it so there is no RTTI for it.
- */
- this->ref = static_cast<T *>(::Service::FindService(this->type, this->name));
- if (this->ref)
- this->ref->AddReference(this);
- }
- return this->ref;
+ return static_cast<T*>(GetService());
}
};
-class ServiceAlias
+template<typename T>
+class ServiceReferenceList : public ServiceReferenceBase
{
- Anope::string t, f;
+ static_assert(std::is_base_of<Service, T>::value, "");
+
public:
- ServiceAlias(const Anope::string &type, const Anope::string &from, const Anope::string &to) : t(type), f(from)
+ using ServiceReferenceBase::ServiceReferenceBase;
+
+ std::vector<T *> GetServices() const
{
- Service::AddAlias(type, from, to);
+ std::vector<T *> out;
+ std::transform(services.begin(), services.end(), std::back_inserter(out), [](Service *e) { return static_cast<T *>(e); });
+ return out;
}
+};
+
+class ServiceManager
+{
+ std::vector<ServiceReferenceBase *> references; // managed references
+ std::vector<Service *> services; // all registered services
+
+ /* Lookup services for a reference */
+ void Lookup(ServiceReferenceBase *reference);
- ~ServiceAlias()
+ /* Lookup services for all managed references */
+ void LookupAll();
+
+ std::vector<Service *> FindServices(const Anope::string &type);
+
+ static ServiceManager *manager;
+
+ public:
+ Service *FindService(const Anope::string &name);
+ Service *FindService(const Anope::string &type, const Anope::string &name);
+
+ template<typename T>
+ std::vector<T> FindServices()
{
- Service::DelAlias(t, f);
+ static_assert(std::is_base_of<Service, typename std::remove_pointer<T>::type>::value, "");
+ const char *type = std::remove_pointer<T>::type::NAME;
+ std::vector<Service *> s = FindServices(type);
+ std::vector<T> out;
+ std::transform(s.begin(), s.end(), std::back_inserter(out), [](Service *e) { return static_cast<T>(e); });
+ return out;
}
+
+ template<typename T>
+ T FindService(const Anope::string &name)
+ {
+ static_assert(std::is_base_of<Service, typename std::remove_pointer<T>::type>::value, "");
+ const char *type = std::remove_pointer<T>::type::NAME;
+ return static_cast<T>(FindService(type, name));
+ }
+
+ void Register(Service *service);
+
+ void Unregister(Service *service);
+
+ void RegisterReference(ServiceReferenceBase *reference);
+
+ void UnregisterReference(ServiceReferenceBase *reference);
+
+ static void Init();
+ static ServiceManager *Get();
+ static void Destroy();
};
-#endif // SERVICE_H
diff --git a/include/services.h b/include/services.h
index 2fc7280b6..6b5832344 100644
--- a/include/services.h
+++ b/include/services.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SERVICES_H
-#define SERVICES_H
+#pragma once
#include "sysconf.h"
@@ -19,12 +26,10 @@
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
+#include <cstdint>
#include <stdexcept>
#include <string.h>
-#if HAVE_STRINGS_H
-# include <strings.h>
-#endif
#ifndef _WIN32
#include <unistd.h>
@@ -43,19 +48,13 @@
#include <set>
#include <algorithm>
#include <iterator>
+#include <regex>
+#include <stack>
#include "defs.h"
#define _(x) x
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-# define anope_override override
-# define anope_final final
-#else
-# define anope_override
-# define anope_final
-#endif
-
#ifndef _WIN32
# define DllExport
# define CoreExport
@@ -65,4 +64,10 @@
# include "anope_windows.h"
#endif
-#endif // SERVICES_H
+#ifndef DEBUG_BUILD
+# define NDEBUG
+#endif
+#include <assert.h>
+
+#define anope_abstract = 0
+
diff --git a/include/socketengine.h b/include/socketengine.h
index 36eb253a4..b7a1c6c6e 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SOCKETENGINE_H
-#define SOCKETENGINE_H
+#pragma once
#include "services.h"
#include "sockets.h"
@@ -47,4 +54,3 @@ class CoreExport SocketEngine
static bool IgnoreErrno();
};
-#endif // SOCKETENGINE_H
diff --git a/include/sockets.h b/include/sockets.h
index 89ca79dde..afc335c4f 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef SOCKETS_H
-#define SOCKETS_H
+#pragma once
#ifndef _WIN32
#include <netinet/in.h>
@@ -286,12 +293,12 @@ class CoreExport BufferedSocket : public virtual Socket
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
- bool ProcessRead() anope_override;
+ bool ProcessRead() override;
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
- bool ProcessWrite() anope_override;
+ bool ProcessWrite() override;
/** Gets the new line from the input buffer, if any
*/
@@ -340,12 +347,12 @@ class CoreExport BinarySocket : public virtual Socket
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
- bool ProcessRead() anope_override;
+ bool ProcessRead() override;
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
- bool ProcessWrite() anope_override;
+ bool ProcessWrite() override;
/** Write data to the socket
* @param buffer The data to write
@@ -377,14 +384,14 @@ class CoreExport ListenSocket : public virtual Socket
/** Process what has come in from the connection
* @return false to destroy this socket
*/
- bool ProcessRead();
+ bool ProcessRead() override;
/** Called when a connection is accepted
* @param fd The FD for the new connection
* @param addr The sockaddr for where the connection came from
* @return The new socket
*/
- virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr) = 0;
+ virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_abstract;
};
class CoreExport ConnectionSocket : public virtual Socket
@@ -403,12 +410,12 @@ class CoreExport ConnectionSocket : public virtual Socket
* Used to determine whether or not this socket is connected yet.
* @return true to continue to call ProcessRead/ProcessWrite, false to not continue
*/
- bool Process() anope_override;
+ bool Process() override;
/** Called when there is an error for this socket
* @return true on success, false to drop this socket
*/
- void ProcessError() anope_override;
+ void ProcessError() override;
/** Called on a successful connect
*/
@@ -438,12 +445,12 @@ class CoreExport ClientSocket : public virtual Socket
* Used to determine whether or not this socket is connected yet.
* @return true to continue to call ProcessRead/ProcessWrite, false to not continue
*/
- bool Process() anope_override;
+ bool Process() override;
/** Called when there is an error for this socket
* @return true on success, false to drop this socket
*/
- void ProcessError() anope_override;
+ void ProcessError() override;
/** Called when a client has been accepted() successfully.
*/
@@ -467,7 +474,7 @@ class CoreExport Pipe : public Socket
/** Called when data is to be read, reads the data then calls OnNotify
*/
- bool ProcessRead() anope_override;
+ bool ProcessRead() override;
/** Write data to this pipe
* @param data The data to write
@@ -496,11 +503,10 @@ class CoreExport Pipe : public Socket
/** Called after ProcessRead comes back from Notify(), overload to do something useful
*/
- virtual void OnNotify() = 0;
+ virtual void OnNotify() anope_abstract;
};
extern CoreExport uint32_t TotalRead;
extern CoreExport uint32_t TotalWritten;
extern CoreExport SocketIO NormalSocketIO;
-#endif // SOCKET_H
diff --git a/include/sysconf.h.cmake b/include/sysconf.h.cmake
index 5f0e275c3..2d2ede9de 100644
--- a/include/sysconf.h.cmake
+++ b/include/sysconf.h.cmake
@@ -1,47 +1,28 @@
-#ifndef _SYSCONF_H_
-#define _SYSCONF_H_
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
#cmakedefine DEBUG_BUILD
#cmakedefine DEFUMASK @DEFUMASK@
-#cmakedefine HAVE_CSTDINT 1
-#cmakedefine HAVE_STDINT_H 1
-#cmakedefine HAVE_STDDEF_H 1
-#cmakedefine HAVE_STRCASECMP 1
-#cmakedefine HAVE_STRICMP 1
-#cmakedefine HAVE_STRINGS_H 1
#cmakedefine HAVE_UMASK 1
-#cmakedefine HAVE_EVENTFD 1
-#cmakedefine HAVE_EPOLL 1
-#cmakedefine HAVE_POLL 1
#cmakedefine GETTEXT_FOUND 1
+#cmakedefine Boost_FOUND 1
-#ifdef HAVE_CSTDINT
-# include <cstdint>
-#else
-# ifdef HAVE_STDINT_H
-# include <stdint.h>
-# else
-# include "pstdint.h"
-# endif
-#endif
-#ifdef HAVE_STDDEF_H
-# include <stddef.h>
-#endif
-
-#ifdef _WIN32
-# define popen _popen
-# define pclose _pclose
-# define ftruncate _chsize
-# ifdef MSVCPP
-# define PATH_MAX MAX_PATH
-# endif
-# define MAXPATHLEN MAX_PATH
-# define bzero(buf, size) memset(buf, 0, size)
-# ifdef MSVCPP
-# define strcasecmp stricmp
-# endif
-# define sleep(x) Sleep(x * 1000)
-#endif
-
-#endif
diff --git a/include/threadengine.h b/include/threadengine.h
index 20a35cb09..81b5dcd13 100644
--- a/include/threadengine.h
+++ b/include/threadengine.h
@@ -1,21 +1,31 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef THREADENGINE_H
-#define THREADENGINE_H
+#pragma once
#include "sockets.h"
#include "extensible.h"
+#include <thread>
+#include <mutex>
+#include <condition_variable>
-class CoreExport Thread : public Pipe, public Extensible
+class CoreExport Thread : public Pipe
{
private:
/* Set to true to tell the thread to finish and we are waiting for it */
@@ -23,7 +33,7 @@ class CoreExport Thread : public Pipe, public Extensible
public:
/* Handle for this thread */
- pthread_t handle;
+ std::thread handle;
/** Threads constructor
*/
@@ -41,10 +51,6 @@ class CoreExport Thread : public Pipe, public Extensible
*/
void SetExitState();
- /** Exit the thread. Note that the thread still must be joined to free resources!
- */
- void Exit();
-
/** Launch the thread
*/
void Start();
@@ -56,65 +62,33 @@ class CoreExport Thread : public Pipe, public Extensible
/** Called when this thread should be joined to
*/
- void OnNotify();
+ void OnNotify() override;
/** Called when the thread is run.
*/
- virtual void Run() = 0;
+ virtual void Run() anope_abstract;
};
-class CoreExport Mutex
+class Mutex
{
protected:
- /* A mutex, used to keep threads in sync */
- pthread_mutex_t mutex;
+ std::mutex m;
public:
- /** Constructor
- */
- Mutex();
-
- /** Destructor
- */
- ~Mutex();
-
- /** Attempt to lock the mutex, will hang until a lock can be achieved
- */
void Lock();
- /** Unlock the mutex, it must be locked first
- */
- void Unlock();
-
- /** Attempt to lock the mutex, will return true on success and false on fail
- * Does not block
- * @return true or false
- */
bool TryLock();
+
+ void Unlock();
};
-class CoreExport Condition : public Mutex
+class Condition : public Mutex
{
- private:
- /* A condition */
- pthread_cond_t cond;
+ std::condition_variable_any cv;
public:
- /** Constructor
- */
- Condition();
-
- /** Destructor
- */
- ~Condition();
-
- /** Called to wakeup the waiter
- */
void Wakeup();
- /** Called to wait for a Wakeup() call
- */
void Wait();
};
-#endif // THREADENGINE_H
diff --git a/include/timers.h b/include/timers.h
index b15d2899f..1425a8fc4 100644
--- a/include/timers.h
+++ b/include/timers.h
@@ -1,16 +1,23 @@
-/* Timer include stuff.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef TIMERS_H
-#define TIMERS_H
+#pragma once
#include "anope.h"
@@ -95,7 +102,7 @@ class CoreExport Timer
/** Called when the timer ticks
* This should be overridden with something useful
*/
- virtual void Tick(time_t ctime) = 0;
+ virtual void Tick(time_t ctime) anope_abstract;
};
/** This class manages sets of Timers, and triggers them at their defined times.
@@ -128,4 +135,3 @@ class CoreExport TimerManager
static void DeleteTimersFor(Module *m);
};
-#endif // TIMERS_H
diff --git a/include/uplink.h b/include/uplink.h
index 64cc1e08e..0075b5d44 100644
--- a/include/uplink.h
+++ b/include/uplink.h
@@ -1,16 +1,23 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef UPLINK_H
-#define UPLINK_H
+#pragma once
#include "sockets.h"
#include "protocol.h"
@@ -18,6 +25,21 @@
namespace Uplink
{
extern void Connect();
+ extern void SendMessage(IRCMessage &);
+
+ template<typename... Args>
+ void Send(const MessageSource &source, const Anope::string &command, Args&&... args)
+ {
+ IRCMessage message(source, command, std::forward<Args>(args)...);
+ SendMessage(message);
+ }
+
+ template<typename... Args>
+ void Send(const Anope::string &command, Args&&... args)
+ {
+ IRCMessage message(MessageSource(""), command, std::forward<Args>(args)...);
+ SendMessage(message);
+ }
}
/* This is the socket to our uplink */
@@ -27,27 +49,10 @@ class UplinkSocket : public ConnectionSocket, public BufferedSocket
bool error;
UplinkSocket();
~UplinkSocket();
- bool ProcessRead() anope_override;
- void OnConnect() anope_override;
- void OnError(const Anope::string &) anope_override;
-
- /* A message sent over the uplink socket */
- class CoreExport Message
- {
- MessageSource source;
- std::stringstream buffer;
-
- public:
- Message();
- Message(const MessageSource &);
- ~Message();
- template<typename T> Message &operator<<(const T &val)
- {
- this->buffer << val;
- return *this;
- }
- };
+ bool ProcessRead() override;
+ void OnConnect() override;
+ void OnError(const Anope::string &) override;
};
+
extern CoreExport UplinkSocket *UplinkSock;
-#endif // UPLINK_H
diff --git a/include/users.h b/include/users.h
index 6f50d0cbd..dacb7045e 100644
--- a/include/users.h
+++ b/include/users.h
@@ -1,35 +1,49 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2003-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef USERS_H
-#define USERS_H
+#pragma once
#include "anope.h"
#include "modes.h"
#include "extensible.h"
#include "serialize.h"
#include "commands.h"
-#include "account.h"
#include "sockets.h"
-typedef Anope::hash_map<User *> user_map;
+using user_map = Anope::locale_hash_map<User *>;
+using uid_map = std::unordered_map<Anope::string, User *, Anope::hash, Anope::compare>;
-extern CoreExport user_map UserListByNick, UserListByUID;
+extern CoreExport user_map UserListByNick;
+extern CoreExport uid_map UserListByUID;
extern CoreExport int OperCount;
-extern CoreExport unsigned MaxUserCount;
-extern CoreExport time_t MaxUserTime;
+
+enum class UserType
+{
+ USER,
+ //LOCAL_USER,
+ BOT
+};
/* Online user and channel data. */
-class CoreExport User : public virtual Base, public Extensible, public CommandReply
+class CoreExport User : public virtual Base, public virtual Extensible, public CommandReply
{
/* true if the user was quit or killed */
bool quit;
@@ -46,8 +60,8 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
bool on_access;
/* Map of user modes and the params this user has (if any) */
ModeList modes;
- /* NickCore account the user is currently loggged in as, if they are logged in */
- Serialize::Reference<NickCore> nc;
+ /* NickServ::Account account the user is currently loggged in as, if they are logged in */
+ Serialize::Reference<NickServ::Account> nc;
/* # of invalid password attempts */
unsigned short invalid_pw_count;
@@ -55,7 +69,9 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
time_t invalid_pw_time;
- public: // XXX: exposing a tiny bit too much
+ public:
+ UserType type = UserType::USER;
+
/* User's current nick */
Anope::string nick;
@@ -107,14 +123,14 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
* @param suid The unique identifier of the user.
* @param nc The account the user is identified as, if any
*/
- User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
+ User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *nc);
/** Destroy a user.
*/
virtual ~User();
public:
- static User* OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
+ static User* OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *nc);
/** Update the nickname of a user record accordingly, should be
* called from ircd protocol.
@@ -186,11 +202,16 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
/**
* Send a message (notice or privmsg, depending on settings) to a user
* @param source Sender
- * @param fmt Format of the Message
- * @param ... any number of parameters
+ * @param message Format of the Message
+ * @param args any number of parameters
*/
- void SendMessage(BotInfo *source, const char *fmt, ...);
- void SendMessage(BotInfo *source, const Anope::string &msg) anope_override;
+ template<typename... Args>
+ void SendMessage(const MessageSource &source, const char *message, Args&&... args)
+ {
+ const char *translated_message = Language::Translate(this->Account(), message);
+ SendMessage(source, Anope::Format(translated_message, std::forward<Args>(args)...));
+ }
+ void SendMessage(const MessageSource &, const Anope::string &msg) override;
/** Identify the user to a nick.
* updates last_seen, logs the user in,
@@ -198,12 +219,12 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
* @param na the nick to identify to, should be the same as
* the user's current nick
*/
- void Identify(NickAlias *na);
+ void Identify(NickServ::Nick *na);
/** Login the user to an account
* @param core The account
*/
- void Login(NickCore *core);
+ void Login(NickServ::Account *core);
/** Logout the user
*/
@@ -212,7 +233,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
/** Get the account the user is logged in using
* @return The account or NULL
*/
- NickCore *Account() const;
+ NickServ::Account *Account() const;
/** Check if the user is identified for their nick
* @param check_nick True to check if the user is identified to the nickname they are on too
@@ -271,34 +292,34 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
* @param um The user mode
* @param Param Optional param for the mode
*/
- void SetMode(BotInfo *bi, UserMode *um, const Anope::string &param = "");
+ void SetMode(ServiceBot *bi, UserMode *um, const Anope::string &param = "");
/** Set a mode on the user
* @param bi The client setting the mode
* @param name The mode name
* @param Param Optional param for the mode
*/
- void SetMode(BotInfo *bi, const Anope::string &name, const Anope::string &param = "");
+ void SetMode(ServiceBot *bi, const Anope::string &name, const Anope::string &param = "");
/** Remove a mode on the user
* @param bi The client setting the mode
* @param um The user mode
* @param param Optional param for the mode
*/
- void RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param = "");
+ void RemoveMode(ServiceBot *bi, UserMode *um, const Anope::string &param = "");
/** Remove a mode from the user
* @param bi The client setting the mode
* @param name The mode name
* @param param Optional param for the mode
*/
- void RemoveMode(BotInfo *bi, const Anope::string &name, const Anope::string &param = "");
+ void RemoveMode(ServiceBot *bi, const Anope::string &name, const Anope::string &param = "");
/** Set a string of modes on a user
* @param bi The client setting the modes
* @param umodes The modes
*/
- void SetModes(BotInfo *bi, const char *umodes, ...);
+ void SetModes(ServiceBot *bi, const char *umodes, ...);
/** Set a string of modes on a user internally
* @param setter who/what is setting the mode
@@ -372,4 +393,12 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
static void QuitUsers();
};
-#endif // USERS_H
+class LocalUser : public User
+{
+ public:
+ using User::User;
+
+ /* Last time this user said something */
+ time_t lastmsg = 0;
+};
+
diff --git a/include/version.cpp b/include/version.cpp
index 017924283..7dc0b3402 100644
--- a/include/version.cpp
+++ b/include/version.cpp
@@ -1,12 +1,20 @@
-/* Build bumper
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include <cstdlib>
@@ -28,7 +36,7 @@ static std::string get_git_hash(const std::string &git_dir)
fd.close();
return "";
}
-
+
fd.close();
filebuf = filebuf.substr(5);
diff --git a/include/xline.h b/include/xline.h
index 63d4bb8db..87b64d1da 100644
--- a/include/xline.h
+++ b/include/xline.h
@@ -1,64 +1,118 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-#ifndef XLINE_H
-#define XLINE_H
+
+#pragma once
#include "serialize.h"
#include "service.h"
#include "sockets.h"
-/* An Xline, eg, anything added with operserv/akill, or any of the operserv/sxline commands */
-class CoreExport XLine : public Serializable
+/* An XLine, eg, anything added with operserv/akill, or any of the operserv/sxline commands */
+class CoreExport XLine : public Serialize::Object
{
- void Init();
+ void Recache();
Anope::string nick, user, host, real;
+
+ friend class XLineType;
+
+ Anope::string type, mask, by, reason, id;
+ time_t created = 0, expires = 0;
+
public:
- cidr *c;
- Anope::string mask;
- Regex *regex;
- Anope::string by;
- time_t created;
- time_t expires;
- Anope::string reason;
- XLineManager *manager;
- Anope::string id;
-
- XLine(const Anope::string &mask, const Anope::string &reason = "", const Anope::string &uid = "");
-
- XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid = "");
+ static constexpr const char *const NAME = "xline";
+
+ cidr *c = nullptr;
+ std::regex *regex = nullptr;
+
+ using Serialize::Object::Object;
+
~XLine();
+ void SetType(const Anope::string &);
+ Anope::string GetType();
+
+ void SetMask(const Anope::string &);
+ Anope::string GetMask();
+
+ void SetBy(const Anope::string &);
+ Anope::string GetBy();
+
+ void SetReason(const Anope::string &);
+ Anope::string GetReason();
+
+ void SetID(const Anope::string &);
+ Anope::string GetID();
+
+ void SetCreated(const time_t &);
+ time_t GetCreated();
+
+ void SetExpires(const time_t &);
+ time_t GetExpires();
+
const Anope::string &GetNick() const;
const Anope::string &GetUser() const;
const Anope::string &GetHost() const;
const Anope::string &GetReal() const;
- Anope::string GetReason() const;
+ Anope::string GetReasonWithID();
bool HasNickOrReal() const;
- bool IsRegex() const;
+ bool IsRegex();
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
+ XLineManager *GetManager();
+};
+
+class XLineType : public Serialize::Type<XLine>
+{
+ public:
+ Serialize::Field<XLine, Anope::string> type;
+ struct Mask : Serialize::Field<XLine, Anope::string>
+ {
+ using Serialize::Field<XLine, Anope::string>::Field;
+
+ void SetField(XLine *s, const Anope::string &value) override;
+ } mask;
+ Serialize::Field<XLine, Anope::string> by, reason, id;
+ Serialize::Field<XLine, time_t> created, expires;
+
+ XLineType(Module *m) : Serialize::Type<XLine>(m)
+ , type(this, "type", &XLine::type)
+ , mask(this, "mask", &XLine::mask)
+ , by(this, "by", &XLine::by)
+ , reason(this, "reason", &XLine::reason)
+ , id(this, "id", &XLine::id)
+ , created(this, "created", &XLine::created)
+ , expires(this, "expires", &XLine::expires)
+ {
+ }
};
/* Managers XLines. There is one XLineManager per type of XLine. */
class CoreExport XLineManager : public Service
{
char type;
- /* List of XLines in this XLineManager */
- Serialize::Checker<std::vector<XLine *> > xlines;
- /* Akills can have the same IDs, sometimes */
- static Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLinesByUID;
public:
+ static constexpr const char *NAME = "xlinemanager";
+
/* List of XLine managers we check users against in XLineManager::CheckAll */
- static std::list<XLineManager *> XLineManagers;
+ static std::vector<XLineManager *> XLineManagers;
/** 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
@@ -95,31 +149,20 @@ class CoreExport XLineManager : public Service
/** The type of xline provided by this service
* @return The type
*/
- const char &Type();
-
- /** Get the number of XLines in this XLineManager
- * @return The number of XLines
- */
- size_t GetCount() const;
+ char Type();
/** Get the XLine vector
* @return The vector
*/
- const std::vector<XLine *> &GetList() const;
+ std::vector<XLine *> GetXLines() const;
+
+ inline unsigned int GetCount() const { return GetXLines().size(); }
/** Add an entry to this XLineManager
* @param x The entry
*/
void AddXLine(XLine *x);
- void RemoveXLine(XLine *);
-
- /** Delete an entry from this XLineManager
- * @param x The entry
- * @return true if the entry was found and deleted, else false
- */
- bool DelXLine(XLine *x);
-
/** Gets an entry by index
* @param index The index
* @return The XLine, or NULL if the index is out of bounds
@@ -156,29 +199,28 @@ class CoreExport XLineManager : public Service
* @param u The user
* @param x The xline
*/
- virtual bool Check(User *u, const XLine *x) = 0;
+ virtual bool Check(User *u, XLine *x) anope_abstract;
/** Called when a user matches a xline in this XLineManager
* @param u The user
* @param x The XLine they match
*/
- virtual void OnMatch(User *u, XLine *x) = 0;
+ virtual void OnMatch(User *u, XLine *x) anope_abstract;
/** Called when an XLine expires
* @param x The xline
*/
- virtual void OnExpire(const XLine *x);
+ virtual void OnExpire(XLine *x);
/** Called to send an XLine to the IRCd
* @param u The user, if we know it
* @param x The xline
*/
- virtual void Send(User *u, XLine *x) = 0;
+ virtual void Send(User *u, XLine *x) anope_abstract;
/** Called to remove an XLine from the IRCd
* @param x The XLine
*/
- virtual void SendDel(XLine *x) = 0;
+ virtual void SendDel(XLine *x) anope_abstract;
};
-#endif // XLINE_H
diff --git a/language/CMakeLists.txt b/language/CMakeLists.txt
index 577e132a3..a5135a273 100644
--- a/language/CMakeLists.txt
+++ b/language/CMakeLists.txt
@@ -2,7 +2,7 @@
if(GETTEXT_FOUND)
# Get all of the .po files
file(GLOB LANG_SRCS_PO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.*.po")
- sort_list(LANG_SRCS_PO)
+ list(SORT LANG_SRCS_PO)
foreach(LANG_PO ${LANG_SRCS_PO})
# Get the domain for this language file
@@ -26,12 +26,12 @@ if(GETTEXT_FOUND)
# Add to cpack ignored files if not on Windows.
if(NOT WIN32)
add_to_cpack_ignored_files("${LANG_MO}")
- endif(NOT WIN32)
+ endif()
# Install the new language file
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG_MO} DESTINATION ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES RENAME ${LANG_DOMAIN}.mo PERMISSIONS ${PERMS})
- endforeach(LANG_PO)
+ endforeach()
# Generate languages, depends on the mo files
add_custom_target(language DEPENDS ${LANG_SRCS_MO})
-endif(GETTEXT_FOUND)
+endif()
diff --git a/language/anope.ca_ES.po b/language/anope.ca_ES.po
index e4f76cb8b..33fa5bffd 100644
--- a/language/anope.ca_ES.po
+++ b/language/anope.ca_ES.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 20:12-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Catalan\n"
@@ -26,17 +26,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "El teu nickname ha estat expulsat."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "%s afegit a la llista de AKILLs."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s afegit a la llista d'accés de %s amb nivel %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s afegit a la llista d'accés de %s amb nivel %d."
@@ -46,7 +46,7 @@ msgstr "%s afegit a la llista d'accés de %s amb nivel %d."
msgid "%s added to %s autokick list."
msgstr "%s afegit a la llista de kicks automàtics en el canal %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s afegida a la llista de paraules malsonants de %s."
@@ -61,17 +61,17 @@ msgstr "%s afegit a la teva lllista d'accés."
msgid "%s added to %s's certificate list."
msgstr "%s afegit a la teva lllista d'accés."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s afegit a la teva lllista d'accés."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "%s afegit a la llista de AKILLs."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s afegit a la llista de AKILLs."
@@ -107,7 +107,7 @@ msgstr ""
"informació sobre un comanda especifica, escriu \n"
"/msg %s HELP comanda."
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -124,7 +124,7 @@ msgstr ""
"per més informació sobre una comanda especifica\n"
"escriu /msg %s HELP comanda."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -140,7 +140,7 @@ msgstr ""
"per més informació sobre una comanda especifica\n"
"escriu /msg %s HELP comanda."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -161,7 +161,7 @@ msgstr ""
"escriu /msg %s HELP comanda.\n"
" "
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s ja existeix a la llista de paraules malsonants de %s."
@@ -182,7 +182,7 @@ msgstr "%s already exists on the EXCEPTION list."
msgid "%s cannot be taken as times to ban."
msgstr "%s no pot ser pres com vegades a banegar"
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s changed your usermodes."
@@ -192,12 +192,12 @@ msgstr "%s changed your usermodes."
msgid "%s channel list:"
msgstr "Fi de la llista de canals."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s esborrat de la llista AOP de %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s esborrat de la llista d'accés de %s."
@@ -207,7 +207,7 @@ msgstr "%s esborrat de la llista d'accés de %s."
msgid "%s deleted from %s autokick list."
msgstr "%s esborrat de la llista de kicks automàtics del canal %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s esborrada de la llista de paraules malsonants de %s."
@@ -233,12 +233,12 @@ msgstr ""
msgid "%s deleted from the %s list."
msgstr "%s esborrat de la llista AOP de %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s esborrat de la llista de AKILLs."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s inhabilitat(s) en el canal %s."
@@ -311,7 +311,7 @@ msgstr "You are already in %s! "
msgid "%s is already in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s afegit a la teva lllista d'accés."
@@ -321,7 +321,7 @@ msgstr "%s afegit a la teva lllista d'accés."
msgid "%s is already suspended."
msgstr "You are already in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s no és un bot valid o un canal registrat."
@@ -351,7 +351,7 @@ msgstr "%s inhabilitat(s) en el canal %s."
msgid "%s is not in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "%s not found on ignore list."
@@ -383,12 +383,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s afegit a la llista de kicks automàtics en el canal %s."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "%s no trobat a la llista AOP de %s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s no trobat a la llista d'accés de %s."
@@ -398,7 +398,7 @@ msgstr "%s no trobat a la llista d'accés de %s."
msgid "%s not found on %s autokick list."
msgstr "%s no trobat a la llista de kicks automàtics en el canal %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s no trobada a la llista de paraules malsonants de %s."
@@ -435,17 +435,17 @@ msgstr "%s no trobat a a la llista d'excepcions al límit de sessions."
msgid "%s not found on the %s list."
msgstr "%s no trobat a la llista AOP de %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s no trobat a la llista de AKILLs."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "%s esborrat de la llista d'accés de %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s esborrat de la teva lllista d'accés."
@@ -477,11 +477,11 @@ msgstr ""
"Escriu /msg %s HELP opció per més informació\n"
"sobre una opció en particular."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -489,12 +489,12 @@ msgstr ""
"BOT CHANGE nick-antic nick-nou [usuari [host [nom-real]]]\n"
"BOT DEL nick"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <nick>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -509,6 +509,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -571,7 +574,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -589,18 +592,18 @@ msgstr "[auto-memo] The memo you sent to %s has been viewed."
msgid "[target] [password]"
msgstr "GROUP grup clau"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -643,7 +646,7 @@ msgstr "UNBAN canal [nick]"
msgid "channel nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR canal Modes-a-netegar"
@@ -653,7 +656,7 @@ msgstr "CLEAR canal Modes-a-netegar"
msgid "channel text"
msgstr "ACT canal text"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT canal text"
@@ -668,12 +671,12 @@ msgstr "KICK canal usuari raó"
msgid "channel what"
msgstr "TOPIC canal [tòpic]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE canal Modes"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -682,7 +685,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE canal Modes"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -691,19 +694,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC canal [tòpic]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP canal"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC canal [tòpic]"
@@ -718,7 +721,7 @@ msgstr "DROP canal"
msgid "channel DEL num"
msgstr "MODE canal Modes"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [canal] {numero | llista | ALL}"
@@ -728,7 +731,7 @@ msgstr "DEL [canal] {numero | llista | ALL}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | instància]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [canal] {numero | llista | ALL}"
@@ -737,7 +740,7 @@ msgstr "DEL [canal] {numero | llista | ALL}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP canal"
@@ -747,41 +750,50 @@ msgstr "DROP canal"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | instància]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | instància]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | instància]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET canal GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE canal Modes"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC canal [tòpic]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | instància]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [canal] {numero | llista | ALL}"
@@ -791,7 +803,7 @@ msgstr "DEL [canal] {numero | llista | ALL}"
msgid "channel [description]"
msgstr "REGISTER canal descripció"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN canal [nick]"
@@ -801,7 +813,7 @@ msgstr "UNBAN canal [nick]"
msgid "channel [parameters]"
msgstr "CLEAR canal Modes-a-netegar"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN canal [nick]"
@@ -816,23 +828,13 @@ msgstr "BAN #channel nick [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #channel nick [reason]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC canal [tòpic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP canal"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET canal XOP {ON | OFF}"
@@ -860,7 +862,7 @@ msgstr "KICK canal opció {ON|OFF} [establiments]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET canal XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -884,27 +886,27 @@ msgstr "SET canal XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE numero"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL missatge"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -914,8 +916,9 @@ msgid "new-password"
msgstr "GROUP grup clau"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO nick"
@@ -945,18 +948,18 @@ msgstr "SET <nick> <hostmask>."
msgid "nick newnick"
msgstr "SVSNICK nick newnick "
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK nickname"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID nickname rao"
@@ -966,7 +969,7 @@ msgstr "FORBID nickname rao"
msgid "nickname email"
msgstr "FORBID nickname rao"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID nickname rao"
@@ -976,12 +979,12 @@ msgstr "FORBID nickname rao"
msgid "nickname message"
msgstr "FORBID nickname rao"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID nickname rao"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST nickname [clau]"
@@ -991,7 +994,7 @@ msgstr "GHOST nickname [clau]"
msgid "nickname [parameter]"
msgstr "GHOST nickname [clau]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST nickname [clau]"
@@ -1006,15 +1009,15 @@ msgstr "FORBID nickname rao"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET nickname KILL {ON | QUICK | IMMED | OFF}"
@@ -1058,12 +1061,12 @@ msgstr "REGISTER clau email"
msgid "password"
msgstr "GROUP grup clau"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER clau email"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER clau email"
@@ -1083,7 +1086,7 @@ msgstr "LIST patro [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE nom-del-servidor [raó]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE canal Modes"
@@ -1093,7 +1096,7 @@ msgstr "MODE canal Modes"
msgid "user [reason]"
msgstr "JUPE nom-del-servidor [raó]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1110,7 +1113,7 @@ msgstr ""
"o un altre acció maliciosa. L'abus de %s resultara, com a\n"
"mínim, en la perdua del nickname esmentat."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1176,7 +1179,7 @@ msgstr ""
"\n"
"Limitat a operadors de serveis."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1239,7 +1242,7 @@ msgstr ""
"\n"
"Limitat a operadors de serveis."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1356,7 +1359,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1378,7 +1381,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1391,7 +1394,7 @@ msgstr ""
"veure la llista d'accés per qualsevol nickname\n"
"(/msg %s ACCESS LIST nick)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1413,7 +1416,7 @@ msgstr ""
"Veure l'accés, AKICK, i paràmetres de les llistes de nivells per a\n"
"qualsevol canal."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1422,7 +1425,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1484,7 +1497,7 @@ msgstr ""
"d'accés i /msg %s HELP SET XOP per a saber com canviar\n"
"entre la llista d'accés i el sistema de llistes xOP."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1508,7 +1521,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1571,7 +1584,7 @@ msgstr ""
"d'accés i /msg %s HELP SET XOP per a saber com canviar\n"
"entre la llista d'accés i el sistema de llistes xOP."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1634,7 +1647,7 @@ msgstr ""
"d'accés i /msg %s HELP SET XOP per a saber com canviar\n"
"entre la llista d'accés i el sistema de llistes xOP."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1701,9 +1714,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"Sintaxi: SET canal NOBOT {ON|OFF}\n"
"\n"
@@ -1713,7 +1726,7 @@ msgstr ""
"\n"
"Limitat a administradors de serveis."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1736,7 +1749,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1751,7 +1764,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "Providing command: /msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1765,7 +1778,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1777,7 +1790,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr " JUPE \"Jupiter\" (Mart,Saturn....) un servidor"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1796,17 +1809,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s no es notificat per memos nous."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -1831,8 +1844,8 @@ msgstr "%d nicknames en el grup."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "La llista AOP de %s esta buida."
@@ -1924,9 +1937,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr " Caps kicker : %s (mínim %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "La llista d'accés de %s esta buida."
@@ -1936,7 +1949,7 @@ msgstr "La llista d'accés de %s esta buida."
msgid "%s added to %s's auto join list."
msgstr "%s afegit a la llista de kicks automàtics en el canal %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "El bot %s ja existeix."
@@ -1947,7 +1960,7 @@ msgstr "El bot %s ja existeix."
msgid "%s autokick list is empty."
msgstr "La llista de kicks automàtics del canal %s esta buida."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "La llista de paraules malsonants de %s esta buida."
@@ -1957,8 +1970,8 @@ msgstr "La llista de paraules malsonants de %s esta buida."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s no pot ser el sucessor en el canal %s ja que n'es el fundador."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "%s commands:"
@@ -2058,7 +2071,7 @@ msgstr "%s Esta actualment online."
msgid "%s is a network service."
msgstr "%s Esta actualment online."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "%s ja esta cobert per %s."
@@ -2073,7 +2086,7 @@ msgstr "%s afegit a la teva lllista d'accés."
msgid "%s is an unconfirmed nickname."
msgstr "Aquest nickname no caducara."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2097,7 +2110,7 @@ msgstr "%s is disabled"
msgid "%s is enabled"
msgstr "%s is enable"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s no es un tipus de ban valid."
@@ -2143,7 +2156,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s inhabilitat(s) en el canal %s."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "Lllista d'accés per %s:"
@@ -2153,7 +2166,7 @@ msgstr "Lllista d'accés per %s:"
msgid "%s list is empty."
msgstr "La llista AOP de %s esta buida."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s no es notificat per memos nous."
@@ -2209,7 +2222,7 @@ msgstr ""
"%s ara et notificara dels teus memos quant et conectis o treguis el teu /"
"AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) afegit a la llista de bots."
@@ -2263,12 +2276,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s is enable"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2335,7 +2348,7 @@ msgstr "%s Esta actualment online."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2348,13 +2361,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "A massmemo has been sent to all registered users."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2393,7 +2406,7 @@ msgstr "GROUP grup clau"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
@@ -2413,12 +2426,12 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID nickname rao"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
@@ -2428,15 +2441,15 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2450,8 +2463,8 @@ msgstr "AKICK ENFORCE en %s completa; %d usuaris afectats."
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL AKILL all users on a specific channel"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "La llista de AKILLS esta buida."
@@ -2485,17 +2498,17 @@ msgstr "El nivell ha d'estar entre %d i %d inclosos."
msgid "Access level must be non-zero."
msgstr "El nivell de accés no pot ser zero."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Opcions del nivell d'accés pel canal %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Nivells d'accés per a %s canviats als valors originals."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "Lllista d'accés per %s:"
@@ -2509,24 +2522,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE Activa les opcions de seguretat de %s"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2550,7 +2555,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2590,13 +2595,7 @@ msgstr "Uplink server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2617,7 +2616,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Totes les linees O de %s han estat esborrades."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -2627,16 +2626,11 @@ msgstr "All vhost's in the group %s have been set to %s"
msgid "All available commands for %s:"
msgstr "No existeix ajuda per %s."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "All vhost's in the group %s have been set to %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Totes les notícies d'entrada esborrades."
@@ -2646,12 +2640,12 @@ msgstr "Totes les notícies d'entrada esborrades."
msgid "All memos for channel %s have been deleted."
msgstr "All memos for channel %s have been deleted."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2674,7 +2668,7 @@ msgstr "Totes les linees O de %s han estat esborrades."
msgid "All random news items deleted."
msgstr "Totes les notícies al azar esborrades."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -2686,12 +2680,12 @@ msgstr "Totes les linees O de %s han estat esborrades."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "All vhost's in the group %s have been set to %s"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "All vhost's in the group %s have been set to %s@%s"
#: src/access.cpp:41
@@ -2825,7 +2819,7 @@ msgstr ""
"Permet als Administrators a enviar missatges als usuaris de\n"
"la xarxa. El missatge sera enviat desde el nick %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2841,7 +2835,7 @@ msgstr ""
"\n"
"Limitat a operadors de serveis."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2855,7 +2849,7 @@ msgstr ""
"\n"
"Limitat a operadors de serveis."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2866,13 +2860,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2939,7 +2933,7 @@ msgstr ""
"\n"
"Ignores will not be enforced on IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -3010,7 +3004,7 @@ msgstr ""
"\n"
"Limitat a operadors de serveis."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -3018,19 +3012,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3079,7 +3071,7 @@ msgstr ""
"\n"
"Limitat a administradors de serveis."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3087,12 +3079,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3128,7 +3119,7 @@ msgstr ""
"\n"
"Opcions disponibles:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3146,7 +3137,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3159,7 +3150,7 @@ msgstr ""
"the given user. With MSG set, Services will use messages,\n"
"else they'll use notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3172,7 +3163,7 @@ msgstr ""
"comunicaran amb tu. Amb MSG establert, els serveis\n"
"utilitzaran msgs, de l'altra forma utilitzaran notícies. "
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3253,13 +3244,13 @@ msgstr ""
"rebràs informació sobre el bot, així com temps\n"
"de creació o nom de canals en els que aquest estigui."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Delete the vhost of another user"
@@ -3269,15 +3260,10 @@ msgstr " DEL Delete the vhost of another user"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s is a services operator of type %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr "ASSIGN Assigna un bot a un canal"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3287,16 +3273,21 @@ msgstr ""
"Desprès d'això pots configurar el bot segons\n"
"les teves necessitats."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr "ASSIGN Assigna un bot a un canal"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "ASSIGN Assigna un bot a un canal"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET Associa un salutació amb el teu nickname"
@@ -3306,12 +3297,12 @@ msgstr " GREET Associa un salutació amb el teu nickname"
msgid "Associate a greet message with your nickname"
msgstr " GREET Associa un salutació amb el teu nickname"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL Associa un E-mail amb el teu nickname"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL Associa un E-mail amb el teu nickname"
@@ -3321,12 +3312,12 @@ msgstr " EMAIL Associa un E-mail amb el teu nickname"
msgid "Associate oper info with a nick or channel"
msgstr "ASSIGN Assigna un bot a un canal"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL Associa un E-mail amb el teu nickname"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3339,7 +3330,7 @@ msgstr ""
"sera mostrat quant algu demani informació\n"
"sobre el teu nick amb la comanda INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3368,17 +3359,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "No existeix ajuda per %s."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "No existeix ajuda per %s."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3393,20 +3379,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr " Kicker per paraules malsonants : %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "Lllista d'accés per %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "La llista de paraules malsonants esta ara buida."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "El bot %s ja existeix."
@@ -3425,7 +3411,7 @@ msgstr "Tipus de ban pel canal %s es ara #%d."
msgid "Bans a given nick or mask on a channel"
msgstr " BAN Bans a selected nick on a channel"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3453,7 +3439,7 @@ msgstr "%s no es notificat per memos nous."
msgid "Bolds kicker"
msgstr " Kicker per negretes : %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "El bot %s ja existeix."
@@ -3468,12 +3454,12 @@ msgstr "El bot %s ja existeix."
msgid "Bot %s has been assigned to %s."
msgstr "El bot %s ha estat assignat al canal %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "El bot %s ha estat canviat a %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "El bot %s ha estat esborrat."
@@ -3503,42 +3489,42 @@ msgstr "Bot no kickejara ops en el canal %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot no kickejara voices en el canal %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Mode no bot ara activat en el canal %s."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "El bot %s ha estat esborrat."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot Hosts may only contain %d characters."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot Hosts may only contain valid host characters."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot Idents may only contain valid characters."
@@ -3556,12 +3542,12 @@ msgstr "Llista de bots:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot Nicks may only contain valid nick characters."
@@ -3654,8 +3640,8 @@ msgstr "El bot ja no kickejara flood."
msgid "Bot won't kick for repeats anymore."
msgstr "El bot ja no kickejara repeticions."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3694,12 +3680,12 @@ msgstr ""
"sempre i quan no hagi sigut llegit al moment en el que\n"
"vas fer servir la comanda."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Bot kickejara ops en el canal %s."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Imposible enviar email ara; per favor intenta en uns instants."
@@ -3798,24 +3784,24 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s changed your usermodes."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr ""
" MSG canvia el metode de comunicació amb els\n"
" serveis"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s changed your usermodes."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Changed usermodes of %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3827,7 +3813,7 @@ msgstr ""
"nicks en serveis. El nou display HA DE SER un nick\n"
"del teu grup."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3850,7 +3836,7 @@ msgstr ""
"Canvia el fundador d'un canal. El nou nickname ha de\n"
"ser un d'enregistrat."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3865,7 +3851,7 @@ msgstr ""
"numero ha de ser escollit de la llista de llenguatges\n"
"soportats:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3880,7 +3866,7 @@ msgstr ""
"numero ha de ser escollit de la llista de llenguatges\n"
"soportats:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3889,7 +3875,7 @@ msgstr ""
"Canvia la clau utilitzada per identificar-te com el\n"
"propietari del nick."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3918,7 +3904,7 @@ msgstr ""
"si no hi haguès un successor. El nou nickname ha de ser un\n"
"d'enregistrat."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP canal"
@@ -3998,12 +3984,12 @@ msgstr "El canal %s caducara."
msgid "Channel %s will not expire."
msgstr "El canal %s no caducara."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "La llista AOP de canals %s ha estat netegada."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "La llista d'accés pel canal %s ha estat netegada."
@@ -4013,7 +3999,7 @@ msgstr "La llista d'accés pel canal %s ha estat netegada."
msgid "Channel %s akick list has been cleared."
msgstr "La llista de kicks automàtics en canal %s ha estat netegada."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "Channel %s is now released."
@@ -4040,8 +4026,8 @@ msgstr ""
"Channels that %s has access on:\n"
" Num Channel Level Description "
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s no trobat a la llista d'accés de %s."
@@ -4107,7 +4093,7 @@ msgstr " CHECK Checks if last memo to a nick was read"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Syntax: CHECK nick\n"
"\n"
@@ -4207,7 +4193,7 @@ msgstr "KICK Configura kickers"
msgid "Configures reverses kicker"
msgstr "KICK Configura kickers"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "SET Configura opcions de bots"
@@ -4222,7 +4208,7 @@ msgstr "KICK Configura kickers"
msgid "Confirm a passcode"
msgstr " CONFIRM Confirm a nickserv auth code"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES neteja els Modes d'un canal"
@@ -4232,50 +4218,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr " Creat : %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr " Creat : %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Llista actual de AKILLs:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Llista actual de AKILLs:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "llista d'excepcions al límit de sessions actual:"
@@ -4329,13 +4315,13 @@ msgstr "FORBID nickname rao"
msgid "DEL [nickname] mask"
msgstr "MODE canal Modes"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [canal] {numero | llista | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [canal] {numero | llista | ALL}"
@@ -4354,19 +4340,19 @@ msgstr "Sintaxis: OPERNEWS DEL {numero | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} servidor"
@@ -4380,7 +4366,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4516,17 +4502,22 @@ msgstr ""
msgid "Delete a memo or memos"
msgstr " DEL Esborra un o més memos"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Delete the vhost for all nicks in a group"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Delete the vhost of another user"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "%d instàncies esborrades de la llista AOP de %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "%d instàncies esborrades de la llista d'accés de %s."
@@ -4537,7 +4528,7 @@ msgid "Deleted %d entries from %s autokick list."
msgstr ""
"%d instàncies esborrades de la llista de kicks automàtics del canal %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "%d paraules esborrades de la llista de paraules malsonants de %s."
@@ -4558,7 +4549,7 @@ msgstr "%d instàncies esborrades de la llista AOP de %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "%d instàncies esborrades de la llista de AKILLs."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "1 instància esborrada de la llista d'accés de %s."
@@ -4568,7 +4559,7 @@ msgstr "1 instància esborrada de la llista d'accés de %s."
msgid "Deleted 1 entry from %s autokick list."
msgstr "1 instància esborrada de la llista de kicks automàtics del canal %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "1 paraula esborrada de la llista de paraules malsonants de %s."
@@ -4591,7 +4582,7 @@ msgstr "1 instància esborrada de la llista de AKILLs."
msgid "Deleted info from %s."
msgstr "1 instància esborrada de la llista de AKILLs."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "1 instància esborrada de la llista AOP de %s."
@@ -4642,11 +4633,6 @@ msgstr ""
"database.\n"
"Limited to Services operators."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Delete the vhost for all nicks in a group"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4658,13 +4644,13 @@ msgstr ""
"that of the given nick.\n"
"Limited to Host Removers."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "La descripció de %s canviada a%s."
@@ -4679,7 +4665,7 @@ msgstr "La descripció de %s canviada a%s."
msgid "Description of %s unset."
msgstr "La descripció de %s canviada a%s."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "%s is enable"
@@ -4704,7 +4690,7 @@ msgstr ""
"\n"
"Reason may be required on certain networks."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Displayed all records (Count: %d)"
@@ -4822,12 +4808,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail address for %s changed to %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail address for %s unset."
@@ -4855,7 +4841,7 @@ msgstr ""
"to them. (However, no more than %d messages will be\n"
"sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"LOGONNEWS may only be used by Services Operators."
@@ -4877,7 +4863,7 @@ msgstr ""
"be sent to them. (However, no more than %d messages will\n"
"be sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"OPERNEWS may only be used by Services Operators."
@@ -4905,7 +4891,7 @@ msgstr " \t\tAdreça E-mail: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Emails Match %s to %s."
#: modules/fantasy.cpp:19
@@ -4916,11 +4902,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "%s is enable"
@@ -4955,14 +4941,14 @@ msgstr ""
"sorti del canal, i sigui restaurat la pròxima vegada que\n"
"el canal sigui creat."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -5064,8 +5050,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Sintàxi: %s canal SECUREOPS {ON | OFF}\n"
"\n"
@@ -5111,7 +5097,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5136,22 +5122,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Fi de la llista d'usuaris."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "fi de llista d'accés."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Fi de la lllista - %d/%d resultat(s) mostrat(s)."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "fi de llista d'accés."
@@ -5160,7 +5146,7 @@ msgstr "fi de llista d'accés."
msgid "End of autokick list"
msgstr "fi de llista d'accés."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Fi de la llista d'usuaris."
@@ -5193,7 +5179,7 @@ msgstr "Fi de la llista d'usuaris."
msgid "End of list - %d channels shown."
msgstr "Fi de la lllista - %d/%d resultat(s) mostrat(s)."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Fi de la lllista - %d/%d resultat(s) mostrat(s)."
@@ -5228,8 +5214,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Catala"
@@ -5286,44 +5272,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "Excepció per a %s (#%d) moguda a la posició %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception for %s has been updated to %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr "Expires in: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Exception for %s has been updated to %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Temps d'expiració per a %s canviat."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasia"
@@ -5352,16 +5343,16 @@ msgstr "La mascara %s ja esta present a la teva lllista d'accés."
msgid "Fingerprint %s is already in use."
msgstr "You are already in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Nivell d'accés per a %s en %s cambiada a %d."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "Lllista d'accés per %s:"
@@ -5451,7 +5442,7 @@ msgstr "El Fundador de %s cambiat a %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "La comanda GETPASS no esta disponible per l'us d'encriptació."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "El ghost amb el teu nick ha estat expulsat."
@@ -5460,14 +5451,14 @@ msgstr "El ghost amb el teu nick ha estat expulsat."
msgid "Give Operflags to a certain user"
msgstr " OLINE Give Operflags to a certain user"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Gives you owner status on channel"
@@ -5543,24 +5534,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "No utilitzis reversos en aquest canal!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "El bot %s ja existeix."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "El bot %s ja existeix."
@@ -5570,8 +5557,8 @@ msgstr "El bot %s ja existeix."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Per identificar-te amb la teva clau"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Si no canvies el teu nick en 20 segons, el canviare jo."
@@ -5584,12 +5571,12 @@ msgstr "Ignore list has been cleared."
msgid "Ignore list is empty."
msgstr "La llista ignore esta buida."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "Llista de bots:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Protecció de Voices"
@@ -5646,7 +5633,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5663,7 +5650,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Valor de umbral invàlid. Ha de ser un sencer vàlid més gran a 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5683,17 +5670,17 @@ msgstr " Italics kicker : %s"
msgid "Join a group"
msgstr " GROUP Ingresa en un grup"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Mode de missatge"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Peace option for %s is now ON."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Peace option for %s is now ON."
@@ -5712,7 +5699,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr " KICK Kickeja un usuari d'un canal"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5722,13 +5709,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Sintàxi: KICK #canal nick [raó]\n"
"\n"
@@ -5754,19 +5741,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [canal] [llista | NEW]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [canal] [llista | NEW]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK nickname"
@@ -5775,15 +5762,10 @@ msgstr "CHECK nickname"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [text|numero]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Llenguatge canviat a Català."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Sucessor de %s cambiat a %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5794,7 +5776,7 @@ msgstr "Ultim memo enviat a %s va ser cancel.lat."
msgid "Last quit message"
msgstr " Ùltim missatge quit: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr " Ultima vegada vist: %s"
@@ -5804,11 +5786,11 @@ msgstr " Ultima vegada vist: %s"
msgid "Last seen address"
msgstr "Ultima adreça vista: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr " Ultima vegada vist: %s"
@@ -5818,27 +5800,27 @@ msgstr " Ultima vegada vist: %s"
msgid "Last usermask"
msgstr " Ultima vegada vist: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Nivell per a %s en el canal %s cambiat a %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "El nivell ha d'estar entre %d i %d inclosos."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5854,7 +5836,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr " ALIST List channels you have access on"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5864,7 +5846,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST List loaded modules"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "Lllista de nicknames en el grup de %s:"
@@ -6125,18 +6107,18 @@ msgstr " MODLIST List loaded modules"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Lists information about the named registered channel"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Sintàxi: INFO canal\n"
"\n"
@@ -6220,7 +6202,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6259,12 +6245,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK Manté la llista d'AutoKick"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr "BOT Manté la llista de bots de la xarxa"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6272,7 +6258,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6290,7 +6276,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6302,7 +6288,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6358,7 +6344,7 @@ msgstr ""
"La comanda BADWORDS CLEAR neteja totes les instàncies\n"
"de la llista de paraules malsonants."
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr "BADWORDS Manté una llista de paraules malsonants"
@@ -6373,7 +6359,7 @@ msgstr ""
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Sintàxi: ACT canal text\n"
"\n"
@@ -6382,13 +6368,13 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr ""
"SAY Makes the bot say the given text on the given channel"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr ""
"SAY Makes the bot say the given text on the given channel"
@@ -6422,7 +6408,7 @@ msgstr ""
"opció GREET habilitada, sempre i quant tinguis \n"
"l'accés necessari."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "No pots establir la teva adreça e-mail en aquesta xarxa."
@@ -6442,12 +6428,12 @@ msgstr " IGNORE Modify the Services ignore list"
msgid "Manage your auto join list"
msgstr " AKICK Manté la llista d'AutoKick"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL Manipula la llista AKILL"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL Manipula la llista AKILL"
@@ -6457,20 +6443,20 @@ msgstr " AKILL Manipula la llista AKILL"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Manipulate the DefCon system"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Manipulate the topic of the specified channel"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6483,8 +6469,8 @@ msgstr "La mascara %s ja esta present a la teva lllista d'accés."
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "La mascara %s ja esta present a la teva lllista d'accés."
@@ -6516,7 +6502,7 @@ msgstr " Mode de lock: %s"
msgid "Memo %d has been deleted."
msgstr "Memo %d ha estat esborrat."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "La llista ignore esta buida."
@@ -6536,7 +6522,7 @@ msgstr "Límite de memos per a %s establert a %d."
msgid "Memo limit for %s set to 0."
msgstr "Límit de memos per a %s establert a 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo enviat a %s."
@@ -6551,7 +6537,7 @@ msgstr " Mode de lock: %s"
msgid "Message"
msgstr "GLOBAL missatge"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Mode de missatge"
@@ -6559,26 +6545,26 @@ msgstr "Mode de missatge"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "%s not found on ignore list."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr " Mode de lock: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr " Mode de lock: %s"
@@ -6587,11 +6573,6 @@ msgstr " Mode de lock: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6642,7 +6623,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6653,7 +6634,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP Modifica la llista d'usuaris AOP"
@@ -6663,7 +6644,7 @@ msgstr " AOP Modifica la llista d'usuaris AOP"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS Modifica la llista d'adreçes autoritzades"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS Modifica la llista d'usuaris privilegiats"
@@ -6673,7 +6654,7 @@ msgstr " ACCESS Modifica la llista d'usuaris privilegiats"
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Modifica la llista de límit de sessió"
@@ -6722,14 +6703,14 @@ msgstr "Module: %s Version: %s Author: %s loaded: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6742,19 +6723,19 @@ msgstr "Lllista d'accés per %s:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "Nickname %s ha estat expulsat."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "El nickname %s ja esta registrat!"
@@ -6769,7 +6750,6 @@ msgstr "El nickname %s ja esta registrat!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s is an illegal nickname and cannot be used."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6785,7 +6765,7 @@ msgstr "Nick %s is currently in use."
msgid "Nick %s is forbidden."
msgstr "El nick %s no esta sent utilitzat."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s is a services operator of type %s."
@@ -6810,12 +6790,12 @@ msgstr "Nickname %s registered."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s was truncated to %d characters."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s will expire."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s will not expire."
@@ -6880,17 +6860,17 @@ msgstr "El canal %s ja esta enregistrat!"
msgid "Nickname %s may not be registered."
msgstr "El canal %s no pot ser enregistrat."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "El nickname %s ja esta registrat sota el teu compte: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Nickname %s registered."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6899,7 +6879,7 @@ msgstr "Auto-op"
msgid "No bot"
msgstr "Sense bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "no expira"
@@ -6928,13 +6908,13 @@ msgstr "No hi ha notícies d'entrada per a esborrar!"
msgid "No matches for %s found."
msgstr "No Emails listed for %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "No existeixen instàncies coincidents a la llista AOP de %s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "No hi ha instàncies que concordin a la llista d'accés de %s ."
@@ -6946,25 +6926,25 @@ msgstr ""
"No existeixen instàncies que concordin a la llista de kicks automàtics en el "
"canal %s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr ""
"No existeixen paraules que concordin a la llista de paraules malsonants de "
"%s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr ""
"No existeixen instàncies similars a la llista d'excepcions al límit de "
"sessions."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "No existeixen instàncies coincidents a la llista AOP de %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "No existeixen instàncies similars a la llista de AKILLs."
@@ -6977,7 +6957,12 @@ msgstr "Cap memo pot ser cancelat."
msgid "No modules currently loaded matching that criteria."
msgstr "No modules currently loaded"
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* No new nick registrations"
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6997,12 +6982,7 @@ msgstr "No hi ha notícies a l'atzar per esborrar!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* No new nick registrations"
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -7011,8 +6991,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "Lllista d'accés per %s:"
@@ -7022,7 +7002,7 @@ msgstr "Lllista d'accés per %s:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Changed usermodes of %s."
@@ -7037,7 +7017,7 @@ msgstr "Mode no bot ara activat en el canal %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Mode no bot ara activat en el canal %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -7046,21 +7026,21 @@ msgstr ""
msgid "None"
msgstr "Cap"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -7068,18 +7048,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [texto|numero]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "La informació antiga es igual a la nova."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Esta en linea desde: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7103,12 +7080,12 @@ msgstr "Noticia de oper #%d no trobada!"
msgid "Oper news items:"
msgstr "notícies de oper:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "Nickname %s ha estat expulsat."
@@ -7123,17 +7100,17 @@ msgstr "An O:Line with the flags %s has been added for %s."
msgid "Operflags %s have been removed from %s."
msgstr "An O:Line with the flags %s has been added for %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7147,12 +7124,12 @@ msgstr "Protecció de Ops"
msgid "Options"
msgstr " Opcions : %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} servidor"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7169,12 +7146,12 @@ msgstr "Clau incorrecta."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "Sucessor de %s cambiat a %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "La clau de %s ha estat enviada."
@@ -7194,7 +7171,7 @@ msgstr "Clau incorrecta."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Pau"
@@ -7208,7 +7185,7 @@ msgstr "Peace option for %s is now ON."
msgid "Peace option for %s is now on."
msgstr "Peace option for %s is now ON."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7239,13 +7216,13 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Per favor espera %d segons i intenta un altre cop."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr ""
"Per favor espera %d segons abans d'utilizar la comanda SEND un altre cop."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr ""
@@ -7257,13 +7234,13 @@ msgid "Please wait %d seconds before using the GROUP command again."
msgstr ""
"Per favor espera %d segons abans d'utilitzar la comanda GROUP novament."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Per favor espera %d segons abans d'utilitzar la comanda REGISTER novament."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7276,7 +7253,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7306,7 +7283,7 @@ msgstr ""
" PRIVATE Prevent the nickname from appearing in a\n"
" /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE Prevent the nickname from expiring"
@@ -7315,17 +7292,17 @@ msgstr " NOEXPIRE Prevent the nickname from expiring"
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privat"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Mode privado del bot %s esta ara activat."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Mode privado del bot %s esta ara activat."
@@ -7350,36 +7327,36 @@ msgstr "Private option is now ON for %s."
msgid "Private option is now on for %s."
msgstr "Private option is now ON for %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Protecció"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Protection is now ON for %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Protection is now ON for %s, with a reduced delay."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Protection is now ON for %s, with no delay."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Protection is now ON for %s."
@@ -7396,7 +7373,7 @@ msgstr ""
"uses the entire and complete real ident@host for every nick,\n"
"then enforces the AKILL. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Protecció de Voices"
@@ -7442,20 +7419,20 @@ msgstr " READ Llegeix un o més memos"
msgid "Real name"
msgstr " Nom real : %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "Sucessor de %s desabilitat."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7465,33 +7442,33 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS Redefine el significat de nivells d'accés"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr " RELEASE Repren possesió del teu nick després de RECOVER"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s is enable"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7503,12 +7480,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Registra un nickname"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Registra un nickname"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr " Temps registrat: %s"
@@ -7567,7 +7544,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7620,7 +7597,7 @@ msgstr ""
"informació sobre aquesta característica, escriu /msg %s\n"
"HELP GROUP."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Ho sento, el registre de canals esta temporalment inhabilitat."
@@ -7630,12 +7607,12 @@ msgstr "Ho sento, el registre de canals esta temporalment inhabilitat."
msgid "Regulate the use of critical commands"
msgstr " PEACE Regula l'ús de comandes critiques"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Returns the owner status of the given nickname"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Delete the vhost of another user"
@@ -7684,46 +7661,46 @@ msgstr ""
" NOOP Temporalment elimina totes les linees O:\n"
" d'un servidor remotamente"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr " Mode de lock: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr " OP Gives Op status to a selected nick on a channel"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7739,14 +7716,14 @@ msgstr " Kicker per repetició : %s"
msgid "Request a vHost for your nick"
msgstr "There's no email address set for your nick."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Recarrega la configuració dels serveis"
@@ -7756,7 +7733,7 @@ msgstr " RELOAD Recarrega la configuració dels serveis"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Restringeix l'accés al canal"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "accés restringit"
@@ -7797,7 +7774,7 @@ msgstr ""
" GETPASS Recupera la clau per un nickname\n"
" (sols si encriptació esta deshabilitada)"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7813,8 +7790,17 @@ msgstr " GETKEY Returns the key of the given channel"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Returns the key of the given channel"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Syntax: GETEMAIL user@emailhost\n"
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards for either user or emailhost. Whenever\n"
+"this command is used, a message including the person who issued\n"
+"the command and the email it was used on will be logged."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7897,16 +7883,16 @@ msgstr " LOGOUT Reverses the effect of the IDENTIFY command"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} servidor"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Clau aceptada - Has estat reconegut."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Clau aceptada - Has estat reconegut."
@@ -7931,7 +7917,7 @@ msgstr ""
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Fundador Segur"
@@ -7946,7 +7932,7 @@ msgstr "Secure founder option for %s is now ON."
msgid "Secure founder option for %s is now on."
msgstr "Secure founder option for %s is now ON."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Ops Segurs"
@@ -7971,12 +7957,12 @@ msgstr "Secure option for %s is now ON."
msgid "Secure option for %s is now on."
msgstr "Secure option for %s is now ON."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Secure option is now ON for %s."
@@ -7986,11 +7972,11 @@ msgstr "Secure option is now ON for %s."
msgid "Secureops enforced on %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Segur"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7999,7 +7985,7 @@ msgstr ""
"Escriu /msg %s HELP opció per més informació\n"
"sobre una opció en particular."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -8064,7 +8050,7 @@ msgstr ""
"Syntax: STAFF memo-text\n"
"Sends all services staff a memo containing memo-text."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8139,14 +8125,14 @@ msgid "Server %s already exists."
msgstr "El bot %s ja existeix."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "Nickname %s ha estat expulsat."
@@ -8156,12 +8142,12 @@ msgstr "Nickname %s ha estat expulsat."
msgid "Server %s is already in zone %s."
msgstr "You are already in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s Esta actualment online."
@@ -8176,12 +8162,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "Ja no hi ha un bot assignat a %s."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8201,19 +8187,18 @@ msgstr "Servers found: %d"
msgid "Service"
msgstr "Servers found: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "El teu nick ha estat alliberat pels serveis."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s is a services operator of type %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr "This service is temporarly disabled, please try again later"
@@ -8268,7 +8253,7 @@ msgstr "Els serveis han estat configurats per no enviar email"
msgid "Services ignore list:"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8282,7 +8267,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Servers found: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8292,7 +8277,7 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8302,12 +8287,12 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services will now autoop %s in channels."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services will now reply to %s with messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services will now reply to %s with notices."
@@ -8326,7 +8311,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Límit de sessió per a %s establert a %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Límits de sessions no disponibles."
@@ -8372,7 +8357,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC Estableix la descripció del canal"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Estableix el display del teu grup amb serveis"
@@ -8382,14 +8367,14 @@ msgstr " DISPLAY Estableix el display del teu grup amb serveis"
msgid "Set the founder of a channel"
msgstr " FOUNDER Estableix el fundador d'un canal"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE Estableix el llenguatge amb el que els serveis\n"
" t'enviaran missatges"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Set the nickname password"
@@ -8765,7 +8750,7 @@ msgstr ""
"Estableix varies opcions per a nicknames. Opció pot ser\n"
"una de:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8783,7 +8768,7 @@ msgstr ""
"\n"
"limitat a administradors de serveis."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8798,7 +8783,7 @@ msgstr ""
"Set to ON to allow ChanServ to op the given nickname \n"
"automatically when joining channels."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8809,7 +8794,7 @@ msgstr ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8822,7 +8807,7 @@ msgstr ""
"Sets whether you will be opped automatically. Set to ON to \n"
"allow ChanServ to op you automatically when entering channels."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8889,11 +8874,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Signed kick option for %s is now ON."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Kicks Signats"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s actualment te molts memos i no pot rebre'n mes."
@@ -8903,54 +8888,47 @@ msgstr "%s actualment te molts memos i no pot rebre'n mes."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr ""
-"Ho sento, la llista de paraules malsonants per a canals esta temporalment "
-"inabilitada."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr ""
"Ho sento, l'establiment d'opcions per a bot esta temporalment inhabilitat"
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Ho sento, la modificació de bots esta temporalment inabilitada."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr ""
"Ho sento, l'establiment d'opcions per a bot esta temporalment inhabilitat"
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr ""
-"Ho sento, l'establiment d'opcions per a bot esta temporalment inhabilitat"
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Ho sento, la modificació de la llista AOP de canals esta\n"
"temporalment deshabilitada."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr ""
"Ho sento, la modificació d'accés a canals esta temporalment inabilitada."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr ""
"Ho sento, la modificació de kicks automàtics a canals esta temporalment "
"inabilitada."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr ""
+"Ho sento, la llista de paraules malsonants per a canals esta temporalment "
+"inabilitada."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr ""
@@ -8983,7 +8961,7 @@ msgstr "Ho sento, desenregistrament de nickname esta temporalment inhabilitat."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Ho sento, La agrupació de nicks esta temporalment inabilitada."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Ho sento, el registre de nicknames esta temporalment deshabilitat."
@@ -9005,13 +8983,8 @@ msgstr ""
"Ho sento, sols pots tenir %d instàncies a la teva lllista d'accés per "
"nickname."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -9025,7 +8998,7 @@ msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr ""
"Ho sento, sols pots tenir %d mascaras per a kicks automàtics a un canal."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Ho sento, sols pots tenir %d paraules malsonants en un canal."
@@ -9094,7 +9067,7 @@ msgstr "Sucessor de %s desabilitat."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "SuperAdmin setting not enabled in services.conf"
+msgstr "SuperAdmin setting not enabled in anope.conf"
#: modules/commands/ns_suspend.cpp:60
#, fuzzy
@@ -9316,7 +9289,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9391,7 +9364,7 @@ msgstr ""
"This opion is _NOT_ persistant, and should only be used when\n"
"needed, and set back to OFF when no longer needed."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9413,7 +9386,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Sintàxi: INVITE canal\n"
@@ -9431,7 +9404,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Sintàxi: UNBAN canal [nick]\n"
@@ -9490,7 +9463,7 @@ msgstr ""
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9501,7 +9474,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9510,7 +9483,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9527,10 +9500,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9538,14 +9511,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9560,7 +9533,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Sintàxi: HOP canal ADD nick\n"
@@ -9606,36 +9579,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "The IMMED option is not available on this network."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9683,7 +9656,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9694,18 +9667,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9713,7 +9686,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9727,7 +9700,6 @@ msgstr ""
"a cap persona."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9745,7 +9717,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9755,12 +9727,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "La llista de AKILLs ha estat netegada."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "La llista de AKILLs ha estat netegada."
@@ -9779,7 +9751,7 @@ msgstr "The E-mail address of %s will now be hidden from %s INFO displays."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "The E-mail address of %s will now be shown in %s INFO displays."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9810,11 +9782,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9875,12 +9847,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "El límit de memos per a %s no pot ser canviat."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9895,10 +9862,6 @@ msgstr "The Defcon Level is now at Level: %d"
msgid "The nick %s is now being changed to %s."
msgstr "The nick %s is now being changed to %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9922,12 +9885,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"The services access status of %s will now be shown in %s INFO displays."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Modifica la llista de límit de sessió"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9999,7 +9962,7 @@ msgstr "No hi ha notícies al azar."
msgid "There is no such configuration block %s."
msgstr " RELOAD Recarrega la configuració dels serveis"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "No hay notícies de oper."
@@ -10027,7 +9990,7 @@ msgstr "Aquest canal esta prohibit."
msgid "This channel may not be used."
msgstr "Aquest canal esta prohibit."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -10064,7 +10027,7 @@ msgstr ""
"CURRENT nick to be the vhost for all nicks in the same\n"
"group."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -10077,7 +10040,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -10111,8 +10074,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10210,7 +10173,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10224,7 +10187,7 @@ msgstr ""
"This command loads the module named FileName from the modules\n"
"directory."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10276,7 +10239,7 @@ msgstr ""
"This command loads the module named FileName from the modules\n"
"directory."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10292,12 +10255,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10358,7 +10321,7 @@ msgstr ""
msgid "Topic"
msgstr "Lock de tòpic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Lock de tòpic"
@@ -10373,7 +10336,7 @@ msgstr "Topic lock option for %s is now ON."
msgid "Topic lock option for %s is now on."
msgstr "Topic lock option for %s is now ON."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Retenció de tòpic"
@@ -10388,7 +10351,7 @@ msgstr "Topic retention option for %s is now ON."
msgid "Topic retention option for %s is now on."
msgstr "Topic retention option for %s is now ON."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10396,17 +10359,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Desactiva les majuscules!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE Activa o desactiva la seguretat de nickname"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE Activa o desactiva la seguretat de nickname"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL Activa o desactiva la protecció"
@@ -10445,7 +10409,7 @@ msgstr ""
"(D'altra banda, qualsevol persona que sapigue el teu nick podra comprobar\n"
"la teva informació utilitzant la comanda INFO.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10475,7 +10439,7 @@ msgstr " SECURE Activa o desactiva la seguretat de nickname"
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE Activa o desactiva la seguretat de nickname"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10506,7 +10470,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10537,7 +10501,7 @@ msgstr ""
"necessari. A mes, els administradors de la xarxa poden haber\n"
"deshabilitat aquesta opció."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10574,7 +10538,7 @@ msgstr ""
"on a specific option. The options will be set on the given\n"
"nickname. "
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10583,7 +10547,7 @@ msgstr ""
"Escriu /msg %s HELP opció per més informació\n"
"sobre una opció en particular."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10599,8 +10563,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Un-Load a module"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Unable to remove module %s"
@@ -10643,7 +10607,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr " Kicker per subrallats : %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Unknown SASET option %s."
@@ -10663,7 +10627,7 @@ msgstr "Opció %s desconeguda."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Comanda no coneguda %s. \"%s%s HELP\" per ajuda."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Caràcter de Mode %c desconegut i ignorat."
@@ -10691,8 +10655,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Sintàxi: DROP canal\n"
"\n"
@@ -10709,10 +10673,10 @@ msgstr " UNSUSPEND Unsuspend a given nick"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10762,31 +10726,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s changed your usermodes."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS Modifica la llista d'usuaris privilegiats"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "Has estat desbanegat de %s."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "vhost for %s removed."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Límite de memos per a %s establert a %d."
@@ -10839,13 +10803,13 @@ msgstr "vhost for group %s set to %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [canal] [llista | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10858,7 +10822,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "El Fundador de %s cambiat a %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10896,7 +10860,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10985,7 +10949,7 @@ msgstr ""
"L'opció RESET estableix el nombre màxim d'usuaris\n"
"al nombre d'usuaris actualment presents en la xarxa."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10994,7 +10958,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Ja ets membre del grup de %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "You are already identified."
@@ -11059,7 +11023,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -11084,13 +11048,22 @@ msgstr ""
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "You can not request a receipt when sending a memo to yourself."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "No pots fer GHOST a tu mateix!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "No hi ha instàncies que concordin a la llista d'accés de %s ."
@@ -11100,16 +11073,11 @@ msgstr "No hi ha instàncies que concordin a la llista d'accés de %s ."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Can't logout %s because he's a services operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "No pots establir la teva adreça e-mail en aquesta xarxa."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -11120,12 +11088,7 @@ msgstr "No pots establir el límite de memos per %s mes de %d."
msgid "You cannot set your memo limit higher than %d."
msgstr "No pots establir el teu límit de memos a mes de %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "No pots establir la teva adreça e-mail en aquesta xarxa."
@@ -11165,12 +11128,12 @@ msgstr "Tens 1 memo."
msgid "You currently have no memos."
msgstr "No tens memos."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11206,7 +11169,7 @@ msgstr "You have been invited to %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "El teu nick ha estat desconnectat."
@@ -11249,32 +11212,27 @@ msgstr ""
"Advertència: Has assolit el màxim numero de memos (%d). No podras rebre mes "
"memos fins que esborris alguns dels existents."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Delete the vhost for all nicks in a group"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "No pots establir la teva adreça e-mail en aquesta xarxa."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "No pots establir la teva adreça e-mail en aquesta xarxa."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "Can't logout %s because he's a services operator."
@@ -11319,26 +11277,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "Has de ser un operador de canal per registrar el canal."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
msgstr "Has de ser un operador de canal per registrar el canal."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "Has de ser un operador de canal per registrar el canal."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "Has de ser un operador de canal per registrar el canal."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11346,17 +11289,17 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr "You have to be connected longer than %d seconds to register your nick."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11370,33 +11313,15 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Seràs notificat quan els memos nous se t'enviin."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr "Seràs notificat per nous memos quant et conectis i quant se t'enviin."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr "Seràs notificat per nous memos quant et conectis i quant se t'enviin."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr "Seràs notificat per nous memos quant et conectis i quant se t'enviin."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Seràs notificat per memos nous quant et conectis."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Seràs notificat quan els memos nous se t'enviin."
@@ -11408,7 +11333,7 @@ msgstr "No et sera possible rebre més memos."
msgid "You will no longer be informed via email."
msgstr "You will no longer be informed via email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "No seràs notificat per memos nous."
@@ -11434,23 +11359,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "El bot %s ha estat esborrat."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "You are already identified."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "You are already identified."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "E-mail address for %s changed to %s."
@@ -11460,18 +11385,18 @@ msgstr "E-mail address for %s changed to %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Totes les linees O de %s han estat esborrades."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Totes les linees O de %s han estat esborrades."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "E-mail address for %s changed to %s."
@@ -11531,7 +11456,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Nickname %s registered."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "El teu nickname s'esta canviant a %s"
@@ -11540,43 +11465,42 @@ msgstr "El teu nickname s'esta canviant a %s"
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Your passcode has been re-sent to %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "La teva clau es %s - Recordala per un us futur."
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "El bot %s ha estat esborrat."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Your vhost of %s is now activated."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Your vhost of %s@%s is now activated."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -11626,7 +11550,7 @@ msgstr "[Notícies al Atzar - %s] %s"
msgid "[account] password"
msgstr "IDENTIFY clau"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #channel [nick]"
@@ -11684,8 +11608,8 @@ msgstr "INFO nick"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK nickname"
@@ -11707,7 +11631,7 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11715,22 +11639,22 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto-memo] The memo you sent to %s has been viewed."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto-memo] The memo you sent to %s has been viewed."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "Ultim memo enviat a %s va ser cancel.lat."
@@ -11835,12 +11759,12 @@ msgstr ""
msgid "seconds"
msgstr "%s commands:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Your vhost of %s is now activated."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "El bot %s ha estat esborrat."
@@ -11876,26 +11800,7 @@ msgstr "UNBAN canal [nick]"
msgid "{nick | channel}"
msgstr "CANCEL {nick | canal}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {nick | canal} text"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "Excepció per a %s (#%d) moguda a la posició %d."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "La informació antiga es igual a la nova."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Syntax: GETEMAIL user@emailhost\n"
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards for either user or emailhost. Whenever\n"
-#~ "this command is used, a message including the person who issued\n"
-#~ "the command and the email it was used on will be logged."
diff --git a/language/anope.de_DE.po b/language/anope.de_DE.po
index 04bc55e69..288a37eef 100644
--- a/language/anope.de_DE.po
+++ b/language/anope.de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2013-06-30 13:05+0100\n"
"Last-Translator: DukePyrolator <DukePyrolator@anope.org>\n"
"Language-Team: German\n"
@@ -28,17 +28,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "Die Registrierung Deines Nicknamens wurde gelöscht."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, c-format
msgid "%s added to %s %s list."
msgstr "%s wurde zur %s %s-Liste hinzugefügt."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s wurde zur Access-Liste von %s hinzugefügt mit Level %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s wurde zur Access-Liste von %s hinzugefügt mit Level %d."
@@ -48,7 +48,7 @@ msgstr "%s wurde zur Access-Liste von %s hinzugefügt mit Level %d."
msgid "%s added to %s autokick list."
msgstr "%s wurde der AutoKick-Liste von %s hinzugefügt."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s zur Bad Words-Liste von %s hinzugefügt."
@@ -63,17 +63,17 @@ msgstr "%s wurde zu %s' Access-Liste hinzugefügt."
msgid "%s added to %s's certificate list."
msgstr "%s wurde zu Deiner Zertifikat-Liste hinzugefügt."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s wurde zu Deiner Ignore-Liste hinzugefügt."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s wurde zur %s-Liste hinzugefügt."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s wurde zur AKILL-Liste hinzugefügt."
@@ -112,7 +112,7 @@ msgstr ""
"%s%s Befehl. Für weitergehende Informationen zu\n"
"einem bestimmten Befehl tippe %s%s %s Befehl"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -129,7 +129,7 @@ msgstr ""
"%s%s Befehl. Für weitergehende Informationen zu\n"
"einem bestimmten Befehl, tippe %s%s %s Befehl."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -145,7 +145,7 @@ msgstr ""
"%s%s Befehl. Für weitergehende Informationen zu\n"
"einem bestimmten Befehl, tippe %s%s %s Befehl."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -165,7 +165,7 @@ msgstr ""
"Informationen zu einem bestimmten Befehl, tippe:\n"
"%s%s HELP Befehl."
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s existiert bereits in der BadWord-Liste von %s."
@@ -186,7 +186,7 @@ msgstr "%s ist bereits in der EXCEPTION-Liste."
msgid "%s cannot be taken as times to ban."
msgstr "%s ist eine ungültige Ban-Zeit."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s hat Deine Usermodi zu %s geändert."
@@ -196,12 +196,12 @@ msgstr "%s hat Deine Usermodi zu %s geändert."
msgid "%s channel list:"
msgstr "%s Raum-Liste:"
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, c-format
msgid "%s deleted from %s %s list."
msgstr "%s wurde von der %s %s-Liste entfernt."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s wurde von der Access-Liste von %s entfernt."
@@ -211,7 +211,7 @@ msgstr "%s wurde von der Access-Liste von %s entfernt."
msgid "%s deleted from %s autokick list."
msgstr "%s wurde von der Autokick-Liste von %s entfernt."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s wurde aus der Bad Words-Liste von %s entfernt."
@@ -238,12 +238,12 @@ msgstr ""
msgid "%s deleted from the %s list."
msgstr "%s wurde von der %s Liste entfernt."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s wurde von der AKILL-Liste entfernt."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s wurde deaktiviert im Raum %s."
@@ -318,7 +318,7 @@ msgstr "%s ist bereits in %s! "
msgid "%s is already in %s."
msgstr "%s ist bereits in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s befindet sich bereits in Deiner Ignore-Liste."
@@ -328,7 +328,7 @@ msgstr "%s befindet sich bereits in Deiner Ignore-Liste."
msgid "%s is already suspended."
msgstr "%s ist bereits in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s ist kein registrierter Nick bzw. Chatraum."
@@ -358,7 +358,7 @@ msgstr "%s wurde deaktiviert im Raum %s."
msgid "%s is not in %s."
msgstr "%s ist bereits in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "Der Nickname %s wurde nicht in Deiner Ignore-Liste gefunden."
@@ -392,12 +392,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s wurde der AutoKick-Liste von %s hinzugefügt."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, c-format
msgid "%s not found on %s %s list."
msgstr "%s wurde nicht auf der %s %s-Liste gefunden."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s wurde nicht auf der Access-Liste von %s gefunden."
@@ -407,7 +407,7 @@ msgstr "%s wurde nicht auf der Access-Liste von %s gefunden."
msgid "%s not found on %s autokick list."
msgstr "%s wurde nicht auf der AutoKick-Liste von %s gefunden."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s nicht in der Bad Words-Liste von %s gefunden."
@@ -446,17 +446,17 @@ msgstr ""
msgid "%s not found on the %s list."
msgstr "%s wurde nicht auf der %s-Liste gefunden."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s wurde nicht auf der AKILL-Liste gefunden."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "%s wurde von der Zugriffsliste von %s entfernt."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s wurde von Deiner Ignore-Liste entfernt."
@@ -488,19 +488,19 @@ msgstr ""
"Tippe %s%s HELP %s für weitere Informationen\n"
"zu einem bestimmten Befehl."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr "ADD Nick User Host Realname"
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr " CHANGE Botnick Neuer-Botnick [User [Hostmaske [Realname]]]"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL Nickname."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -515,6 +515,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -563,7 +566,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -581,17 +584,17 @@ msgstr "[auto-memo] Das Memo das Du an %s gesendet hast wurde angesehen."
msgid "[target] [password]"
msgstr "Ziel Passwort"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr "Adresse"
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
msgid "botname {ON|OFF}"
msgstr "Botname {ON|OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
msgid "channel"
@@ -627,7 +630,7 @@ msgstr "Channel Nick"
msgid "channel nick [reason]"
msgstr "Channel Nick [Grund]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr "Channel Ziel [was]"
@@ -635,7 +638,7 @@ msgstr "Channel Ziel [was]"
msgid "channel text"
msgstr "Channel Text"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "Channel Text"
@@ -649,12 +652,12 @@ msgstr "Channel User Grund"
msgid "channel what"
msgstr "Channel [was]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "Channel ADD Nachricht"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr "Channel ADD Maske Level"
@@ -662,7 +665,7 @@ msgstr "Channel ADD Maske Level"
msgid "channel ADD message"
msgstr "Channel ADD Nachricht"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr "channel ADD Wort [SINGLE | START | END]"
@@ -670,18 +673,18 @@ msgstr "channel ADD Wort [SINGLE | START | END]"
msgid "channel ADD {nick | mask} [reason]"
msgstr "Channel ADD {Nick | Maske} [Grund]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "Channel [Topic]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
msgid "channel CLEAR"
msgstr "Channel CLEAR"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "Channel [was]"
@@ -695,7 +698,7 @@ msgstr "Channel CLEAR"
msgid "channel DEL num"
msgstr "Channel DEL Nummer"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
msgid "channel DEL {mask | entry-num | list}"
msgstr "Channel DEL {Maske | Nummer | Liste }"
@@ -703,7 +706,7 @@ msgstr "Channel DEL {Maske | Nummer | Liste }"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "Channel DEL {Nickname | Maske | Nummer | Liste}"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
msgid "channel DEL {word | entry-num | list}"
msgstr "Channel DEL {Wort | Nummer | Liste}"
@@ -711,7 +714,7 @@ msgstr "Channel DEL {Wort | Nummer | Liste}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr "Channel LIST"
@@ -719,37 +722,46 @@ msgstr "Channel LIST"
msgid "channel LIST [mask | entry-num | list]"
msgstr "Channel LIST [Maske | Nummer | Liste]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
msgid "channel LIST [mask | list]"
msgstr "Channel LIST [Maske | Liste]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "Channel LOCK {ADD|DEL|LIST} [Was]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
msgid "channel RESET"
msgstr "Channel RESET"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
msgid "channel SET modes"
msgstr "Channel SET Modi"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "Channel [Topic]"
+
#: modules/commands/cs_akick.cpp:426
msgid "channel VIEW [mask | entry-num | list]"
msgstr "Channel VIEW [Maske | Nummer | Liste]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
msgid "channel VIEW [mask | list]"
msgstr "Channel VIEW [Maske | Liste}"
@@ -757,7 +769,7 @@ msgstr "Channel VIEW [Maske | Liste}"
msgid "channel [description]"
msgstr "Channel [Beschreibung]"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
msgid "channel [nick]"
msgstr "Channel [Nick]"
@@ -765,7 +777,7 @@ msgstr "Channel [Nick]"
msgid "channel [parameters]"
msgstr "Channel [Parameter]"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "Channel [Nick]"
@@ -779,23 +791,13 @@ msgstr "Channel [+Bandauer [Grund]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "Channel [+Bandauer [Grund]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "Channel ADD Maske Level"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "Channel [Topic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "Channel CLEAR"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
msgid "channel {ON|OFF}"
msgstr "Channel {ON | OFF}"
@@ -822,7 +824,7 @@ msgstr "Channel Option {ON|OFF} [Einstellungen]"
msgid "channel {ON|OFF} [ttb]"
msgstr "Channel {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -845,24 +847,24 @@ msgstr "Channel {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr "Sprache"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
msgid "memo-text"
msgstr "Memo-Text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
msgid "message"
msgstr "Nachricht"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr "Modulname"
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr "Neues Display"
@@ -871,8 +873,9 @@ msgid "new-password"
msgstr "Neues Passwort"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
msgid "nick"
msgstr "Nickname"
@@ -898,17 +901,17 @@ msgstr "Nickname Hostmaske"
msgid "nick newnick"
msgstr "Nickname Neuer-Nickname"
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "Channel Nick [Grund]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
msgid "nickname"
msgstr "Nickname"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr "Nickname Mail-Adresse"
@@ -917,7 +920,7 @@ msgstr "Nickname Mail-Adresse"
msgid "nickname email"
msgstr "Nickname Nachricht"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr "Nickname Sprache"
@@ -925,11 +928,11 @@ msgstr "Nickname Sprache"
msgid "nickname message"
msgstr "Nickname Nachricht"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr "Nickname Display"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "Nickname Neues-Passwort"
@@ -937,7 +940,7 @@ msgstr "Nickname Neues-Passwort"
msgid "nickname [parameter]"
msgstr "Nickname [Parameter]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "Nickname Neues-Passwort"
@@ -952,14 +955,14 @@ msgstr "Nickname [+Zeit] Grund"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
msgid "nickname {ON | OFF}"
msgstr "Nickname {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "Nickname {ON | QUICK | IMMED | OFF}"
@@ -996,11 +999,11 @@ msgstr "Passcode"
msgid "password"
msgstr "Passwort"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
msgid "password [email]"
msgstr "Passwort [eMail]"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
msgid "password email"
msgstr "Passwort eMail"
@@ -1016,7 +1019,7 @@ msgstr "Muster [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "Servername [Grund]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr "Channel Modi"
@@ -1024,7 +1027,7 @@ msgstr "Channel Modi"
msgid "user [reason]"
msgstr "Nickname [Grund]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, c-format
msgid ""
" \n"
@@ -1041,7 +1044,7 @@ msgstr ""
"Missbrauch von %s wird geahndet und resultiert mindestens im\n"
"Verlust Deiner registrierten Nicknamen."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1084,7 +1087,7 @@ msgstr ""
"werden, auch wenn es die Standard-Zeit ist. Die Standard-\n"
"Auslaufzeit für einen AKILL kann man unter STATS AKILL finden.\n"
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1124,7 +1127,7 @@ msgstr ""
"werden, auch wenn es die Standard-Zeit ist. Die Standard-\n"
"Auslaufzeit für einen AKILL kann man unter STATS AKILL finden.\n"
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1235,7 +1238,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1256,7 +1259,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1269,7 +1272,7 @@ msgstr ""
"zu müssen. Zusätzlich können sie die Zugriffsliste eines\n"
"jeden Nicknamen ansehen und bearbeiten."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1281,7 +1284,7 @@ msgstr ""
"DROPPEN (löschen), Zugriffslisten oder Channel-Einstellungen\n"
"ansehen oder verändern."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1290,7 +1293,23 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, fuzzy, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+" \n"
+"Die QOP Befehle sind auf den Gründer des Raumes\n"
+"beschränkt. (ausser SECUREOPS wurde deaktiviert).\n"
+"Aber jeder Benutzer in der QOP-Liste darf den\n"
+"QOP LIST Befehl benutzen.\n"
+" \n"
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1345,7 +1364,7 @@ msgstr ""
"/msg %s HELP SET XOP für Infos über den Wechsel vom xOP und\n"
"vom Access System."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1369,7 +1388,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1425,7 +1444,7 @@ msgstr ""
"/msg %s HELP SET XOP für Infos über den Wechsel vom xOP und\n"
"vom Access System."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1481,7 +1500,7 @@ msgstr ""
"/msg %s HELP SET XOP für Infos über den Wechsel vom xOP und\n"
"vom Access System."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1541,9 +1560,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
" \n"
"Durch diese Option kann einem Channel explizit kein Bot \n"
@@ -1551,7 +1570,7 @@ msgstr ""
"Option gewählt wird, bereits ein Bot zugewiesen \n"
"sein, so verfällt die Zuweisung."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1570,7 +1589,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr " %s ist mit diesem Oper-Block online."
@@ -1585,7 +1604,7 @@ msgstr " Befehl %s auf %s ist mit %s verknüpft."
msgid " Providing service: %s"
msgstr " Unterstützter Dienst: %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr " Dieser Operator wurde in der Konfigurationsdatei eingestellt."
@@ -1599,7 +1618,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr " aber %s ist auf mysteriöse Weise verschwunden."
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1611,7 +1630,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr "Einen Server \"jupitern\""
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1630,17 +1649,17 @@ msgstr "%A, %d.%m.%Y, %H:%M:%S %Z"
msgid "%c is an unknown status mode."
msgstr "%c ist ein unbekannter Status Modus."
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c ist im %s nicht gelockt."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s wurde von %s entsperrt."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Alle Zugriffsrechte von %s wurden nach %s kopiert."
@@ -1665,8 +1684,8 @@ msgstr "%d Nicknamen in der Gruppe."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr "%lu Nicks sind in der Datenbank und belegen %.2Lf kB des Speichers."
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, c-format
msgid "%s %s list is empty."
msgstr "Die %s %s-Liste ist leer."
@@ -1758,9 +1777,9 @@ msgstr "%1$s (%2$s) hat vor %4$s (%5$s) den IRC verlassen (%3$s)."
msgid "%s (minimum %d/%d%%)"
msgstr "%s (Minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "Die Zugriffsliste von %s ist leer."
@@ -1770,7 +1789,7 @@ msgstr "Die Zugriffsliste von %s ist leer."
msgid "%s added to %s's auto join list."
msgstr "%s wurde Deiner Auto-Join-Liste hinzugefügt."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s existiert bereits."
@@ -1781,7 +1800,7 @@ msgstr "%s existiert bereits."
msgid "%s autokick list is empty."
msgstr "Die Autokick-Liste von %s ist leer."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "Die Bad Words-Liste von %s ist leer."
@@ -1791,8 +1810,8 @@ msgstr "Die Bad Words-Liste von %s ist leer."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s kann nicht gleichzeitig Gründer und Nachfolger im Raum %s sein."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Befehle von %s:"
@@ -1892,7 +1911,7 @@ msgstr "%s ist ein Services Dienst."
msgid "%s is a network service."
msgstr "%s ist ein Services Dienst."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s wird bereits von %s getroffen."
@@ -1907,7 +1926,7 @@ msgstr "%s befindet sich bereits in Deiner AutoJoin-Liste."
msgid "%s is an unconfirmed nickname."
msgstr "Der Nickname %s ist noch nicht bestätigt."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1933,7 +1952,7 @@ msgstr "%s ist ausgeschaltet"
msgid "%s is enabled"
msgstr "%s ist eingeschaltet"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s ist keine gültige E-Mail Adresse."
@@ -1978,7 +1997,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s wurde deaktiviert im Raum %s."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, c-format
msgid "%s list for %s"
msgstr "%s Liste von %s:"
@@ -1988,7 +2007,7 @@ msgstr "%s Liste von %s:"
msgid "%s list is empty."
msgstr "Die %s-Liste ist leer."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%c%c%s wurde in %s gelockt."
@@ -2042,7 +2061,7 @@ msgstr ""
"%s wird dich beim Einloggen oder bei der Rückkehr aus /AWAY über "
"eingegangene Memos informieren."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) wurde zur der Bot-Liste hinzugefügt."
@@ -2096,12 +2115,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "Deaktiviert"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2167,7 +2186,7 @@ msgstr ". %s ist noch online."
msgid "<unknown>"
msgstr "<unbekannt>"
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2180,13 +2199,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Ein Massen-Memo wurde an alle regsitrierten Benutzer gesendet."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2227,7 +2246,7 @@ msgstr "Ziel Passwort"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr "ADDL [+Zeit] Maske Limit Grund"
@@ -2246,11 +2265,11 @@ msgstr "ADD [Benutzer] Maske"
msgid "ADD [nickname] [fingerprint]"
msgstr "Nickname Sprache"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+Zeit] Maske Grund"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+Zeit] Maske:Grund"
@@ -2259,15 +2278,15 @@ msgstr "ADD [+Zeit] Maske:Grund"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL} [+Zeit] Was [Grund]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2280,8 +2299,8 @@ msgstr "AKICK ENFORCE für %s erledigt. %d User betroffen."
msgid "AKILL all users on a specific channel"
msgstr "AKILL alle User des angegebenen Channels"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "Die AKILL-Liste ist leer."
@@ -2313,17 +2332,17 @@ msgstr "Das Level darf nur zwischen %d und %d liegen."
msgid "Access level must be non-zero."
msgstr "Zugriffs-Level muss grösser als 0 sein."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Zugriffslevel für Channel %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Zugriffslevel für %s wurden auf Standardwerte zurückgesetzt."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, c-format
msgid "Access list for %s:"
msgstr "Zugriffs-Liste von %s:"
@@ -2337,23 +2356,15 @@ msgstr ""
"Um Zugriff auf diesen Befehl zu haben benötigst Du die Berechtigung %s in "
"Deinem Oper Type."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Aktiviert Sicherheits-funktionen"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr "Schaltet den beantragten vHost für einen Nick frei."
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2375,7 +2386,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2412,13 +2423,7 @@ msgstr "Uplink Server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2439,7 +2444,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Alle O:lines von %s wurden wiederhergestellt."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Alle Autokick Einträge von %s wurden nach %s kopiert."
@@ -2449,16 +2454,11 @@ msgstr "Alle Autokick Einträge von %s wurden nach %s kopiert."
msgid "All available commands for %s:"
msgstr "Verfügbare Befehle für %s:"
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Alle badword Einträge von %s wurden nach %s kopiert."
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Alle Autokick Einträge von %s wurden nach %s kopiert."
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Alle Logon-News wurden entfernt."
@@ -2468,12 +2468,12 @@ msgstr "Alle Logon-News wurden entfernt."
msgid "All memos for channel %s have been deleted."
msgstr "Alle Memos für den Channel %s wurden gelöscht."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2496,7 +2496,7 @@ msgstr "Alle O:Lines von %s wurden temporär entfernt."
msgid "All random news items deleted."
msgstr "Alle randomnews Einträge wurden gelöscht."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Alle Einstellungen von %s wurden nach %s kopiert."
@@ -2508,12 +2508,12 @@ msgstr "Alle Benutzermodi von %s wurden synchronisiert."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Alle vHosts in der Gruppe %s wurden auf %s gesetzt."
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Alle vHosts in der Gruppe %s wurden auf %s@%s gesetzt."
#: src/access.cpp:41
@@ -2645,7 +2645,7 @@ msgstr ""
"Ermöglicht Administratoren eine Nachricht an alle User auf\n"
"dem Netzwerk zu senden. Die Nachricht wird von %s gesendet."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2657,7 +2657,7 @@ msgstr ""
"Raumes zu verändern. Der Paramater hat das gleiche Format\n"
"wie der normale /MODE Befehl."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2667,7 +2667,7 @@ msgstr ""
"Benutzers zu verändern. Der Paramater hat das gleiche Format\n"
"wie der normale /MODE Befehl."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2678,13 +2678,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2746,7 +2746,7 @@ msgstr ""
"\n"
"Ignores werden nicht bei IRC Operatoren erzwungen."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2794,7 +2794,7 @@ msgstr ""
"werden, auch wenn es die Standard-Zeit ist. Die Standard-\n"
"Auslaufzeit für einen AKILL kann man unter STATS AKILL finden.\n"
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
@@ -2806,7 +2806,7 @@ msgstr ""
"Wenn der Realname eines Benutzers mit einer SNLINE Maske\n"
"übereinstimmt, werden die Services seine IRC Sitzung beenden.\n"
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
@@ -2814,15 +2814,13 @@ msgid ""
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
"Erlaubt Services Operatoren die SNLINE Liste zu bearbeiten.\n"
"Wenn der Realname eines Benutzers mit einer SNLINE Maske\n"
"übereinstimmt, werden die Services seine IRC Sitzung beenden.\n"
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2869,7 +2867,7 @@ msgstr ""
"Siehe die Hilfe zu EXCEPTION um weitere Informationen\n"
"über das Einschränken von Verbindungen zu erhalten."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2877,12 +2875,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -2912,7 +2909,7 @@ msgstr ""
"\n"
"Verfügbare Optionen:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2930,7 +2927,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2943,7 +2940,7 @@ msgstr ""
"(Queries), ansonsten werden die Antworten als Notices\n"
"geschickt (Standard)."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2956,7 +2953,7 @@ msgstr ""
"(Queries), ansonsten werden Dir die Antworten als Notices\n"
"geschickt (Standard)."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3031,13 +3028,13 @@ msgstr ""
"Parameter ein Botnick ist, werden Informationen wie \n"
"Erstellungsdatum oder Anzahl der Channels angezeigt."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
msgid "Approve the requested vHost of a user"
msgstr "Genehmigt den beantragten vHost eines Users"
@@ -3046,14 +3043,10 @@ msgstr "Genehmigt den beantragten vHost eines Users"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s ist ein services operator vom Typ %s."
-#: modules/commands/bs_assign.cpp:19
-msgid "Assigns a bot to a channel"
-msgstr "Weist einem Channel einen Bot zu"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3062,16 +3055,20 @@ msgstr ""
"Channel-spezifischen Einstellungen des Bots angepasst \n"
"werden."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+msgid "Assigns a bot to a channel"
+msgstr "Weist einem Channel einen Bot zu"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "Weist einem Channel einen Bot zu"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr "Stellt eine Begrüssungsmeldung für Deinen Nicknamen ein."
@@ -3080,12 +3077,12 @@ msgstr "Stellt eine Begrüssungsmeldung für Deinen Nicknamen ein."
msgid "Associate a greet message with your nickname"
msgstr "Stellt eine Begrüssungsmeldung für Deinen Nicknamen ein."
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr "Verbindet eine eMail-Adresse mit Deinem Nicknamen"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Verbindet eine eMail-Adresse mit Deinem Nicknamen"
@@ -3094,11 +3091,11 @@ msgstr "Verbindet eine eMail-Adresse mit Deinem Nicknamen"
msgid "Associate oper info with a nick or channel"
msgstr "Weist einem Channel einen Bot zu"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Verbindet die angegebene eMail-Adresse mit Deinem Nicknamen."
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3109,7 +3106,7 @@ msgstr ""
"Informationen über Deinen Nicknamen mit dem INFO \n"
"Befehl anfordert."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3138,17 +3135,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, c-format
msgid "Available commands for %s:"
msgstr "Verfügbare Befehle für %s:"
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Verfügbare Befehle für %s:"
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr "Verfügbare Rechte für %s:"
@@ -3162,20 +3154,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr "Bad words kicker"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "Badword Liste von %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Die Bad Words-Liste ist jetzt leer."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "%s wurde aus %s gebannt. Der Ban wird in %s automatisch entfernt."
@@ -3194,7 +3186,7 @@ msgstr "Bann-Typ für den Channel %s ist jetzt #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Bannt den angegebenen Nicknamen aus einen Channel"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3219,7 +3211,7 @@ msgstr "%c%c ist im %s nicht gelockt."
msgid "Bolds kicker"
msgstr "Bolds kicker"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Bot %s existiert bereits."
@@ -3234,12 +3226,12 @@ msgstr "Bot %s existiert bereits."
msgid "Bot %s has been assigned to %s."
msgstr "Bot %s wurde dem Channel %s zugewiesen."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot %s wurde geändert auf %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot %s wurde gelöscht."
@@ -3269,44 +3261,44 @@ msgstr "Bot wird keine Ops kicken im %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot wird keine Voices kicken im %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Bot ist nicht im Channel %s."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "Bot %s wurde gelöscht."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr ""
"Die Services werden %s jetzt nicht mehr automatisch Op-Status geben in den "
"Channels."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot Hosts dürfen nur %d Zeichen lang sein."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot Hosts dürfen nur gültige Zeichen enthalten."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot Idents dürfen nur %d Zeichen enthalten."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot Idents dürfen nur gültige Zeichen enthalten."
@@ -3324,12 +3316,12 @@ msgstr "Bot-Liste:"
msgid "Bot nick"
msgstr "Bot Nick"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot Idents dürfen nur %d Zeichen enthalten."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot Nicknamen dürfen nur gültige Zeichen enthalten."
@@ -3422,8 +3414,8 @@ msgid "Bot won't kick for repeats anymore."
msgstr ""
"Der Bot ignoriert jetzt User die sich wiederholen und wird nicht kicken."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3458,12 +3450,12 @@ msgstr ""
"oder Channel gesendet hast, vorrausgesetzt sie ist noch nicht\n"
"gelesen worden."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Bot wird Ops kicken im %s."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr ""
"Die Services können gerade keine Mail verschicken, bitte versuche es später "
@@ -3535,21 +3527,21 @@ msgstr ""
msgid "Change channel modes"
msgstr "Ändert die Raum Modi"
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Ändert die Methode, wie die Services mit Dir kommunizieren"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "Ändert die Raum Modi"
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Benutzermodi von %s auf %s geändert."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3563,7 +3555,7 @@ msgstr ""
"des einzelnen Nicks, er wird nur als \"Ursprung\" der \n"
"Gruppe in der Liste aufgeführt."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3585,7 +3577,7 @@ msgstr ""
"Ändert den Gründer (Founder) eines Channels. Der neue\n"
"Nickname muss registriert sein."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3599,7 +3591,7 @@ msgstr ""
"Die Sprache muss von der folgenden Liste der unter-\n"
"stützten Sprachen ausgewählt werden: "
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3613,13 +3605,13 @@ msgstr ""
"Die Sprache muss von der folgenden Liste der unter-\n"
"stützten Sprachen ausgewählt werden: "
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
"Ändert das Passwort, mit dem sich der Besitzer des\n"
"Nicknamen identifiziert."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3643,7 +3635,7 @@ msgstr ""
"(max %d), wird der Channel gelöscht.\n"
"Der Nickname des Vertreters muss registriert sein."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "Channel"
@@ -3723,12 +3715,12 @@ msgstr "Der Raum %s wird nach einer bestimmten Zeit ablaufen."
msgid "Channel %s will not expire."
msgstr "Der Raum %s wird nicht mehr ablaufen."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Die %2$s-Liste von %1$s wurde geleert."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Die Access-Liste von %s wurde geleert."
@@ -3738,7 +3730,7 @@ msgstr "Die Access-Liste von %s wurde geleert."
msgid "Channel %s akick list has been cleared."
msgstr "Die Autokick-Liste von %s wurde geleert."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Der Raum %s hat keine gesperrten Modi."
@@ -3762,8 +3754,8 @@ msgstr "Raum-Liste:"
msgid "Channel stats for %s on %s:"
msgstr "Statistiken für %s im Raum %s:"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s wurde nicht auf der Access-Liste von %s gefunden."
@@ -3828,7 +3820,7 @@ msgstr "Überprüft ob Deine letzte gesendete Memo vom Empänger gelesen wurde"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Überprüft ob Deine letzte gesendete Memo an einen Benutzer gelesen\n"
"wurde. Der CHECK Befehl funktioniert nicht mit Räumen."
@@ -3924,7 +3916,7 @@ msgstr "Konfiguriert den Kicker"
msgid "Configures reverses kicker"
msgstr "Konfiguriert den Kicker"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "Konfiguriert die Bot-Optionen"
@@ -3939,7 +3931,7 @@ msgstr "Konfiguriert den Kicker"
msgid "Confirm a passcode"
msgstr "Bestätigt einen Authentifizierungs Code"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
msgid "Control modes and mode locks on a channel"
msgstr "Regelt Modi und gesperrte Modi eines Raumes"
@@ -3948,47 +3940,47 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "Kopiert alle Einstellungen von einem Raum zu einem anderen."
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
msgid "Created"
msgstr "Erstellt"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr "Erstellt"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Aktuelle %s-Liste:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Aktuelle %s-Liste:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Aktuelle Liste für eingeschränkte Verbindungen:"
@@ -4042,12 +4034,12 @@ msgstr "Nickname Sprache"
msgid "DEL [nickname] mask"
msgstr "DEL [Benutzer] Maske"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [Maske] {Nummer | Liste | id}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [Maske] {Nummer | Liste | id}"
@@ -4066,19 +4058,19 @@ msgstr "DEL {Nummer | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL} Eintrag"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} Server"
@@ -4094,7 +4086,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4219,16 +4211,20 @@ msgstr "Oper News bearbeiten"
msgid "Delete a memo or memos"
msgstr "Löschen einer oder mehrerer Memos"
+#: modules/commands/hs_del.cpp:59
+msgid "Delete the vhost for all nicks in a group"
+msgstr "Löscht den vHost aller Nicknamen in einer Gruppe"
+
#: modules/commands/hs_del.cpp:19
msgid "Delete the vhost of another user"
msgstr "Löscht den vHost eines anderen Benutzers"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "%d Einträge wurden aus der %s %s-Liste entfernt."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "%d Einträge wurden aus der Access-Liste von %s entfernt."
@@ -4238,7 +4234,7 @@ msgstr "%d Einträge wurden aus der Access-Liste von %s entfernt."
msgid "Deleted %d entries from %s autokick list."
msgstr "%d Einträge wurden aus der AutoKick-Liste von %s entfernt."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "%d Einträge wurden aus der Bad Words-Liste von %s entfernt."
@@ -4260,7 +4256,7 @@ msgstr "%d Einträge wurden aus der %s-Liste entfernt."
msgid "Deleted %d entries from the AKILL list."
msgstr "Es wurden %d Einträge aus der AKILL-Liste entfernt."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "1 Eintrag wurde aus der Access-Liste von %s entfernt."
@@ -4270,7 +4266,7 @@ msgstr "1 Eintrag wurde aus der Access-Liste von %s entfernt."
msgid "Deleted 1 entry from %s autokick list."
msgstr "1 Eintrag der AutoKick-Liste von %s entfernt."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "1 Eintrag wurde aus der Bad Words-Liste von %s entfernt."
@@ -4295,7 +4291,7 @@ msgstr "Es wurde 1 Eintrag aus der AKILL-Liste entfernt."
msgid "Deleted info from %s."
msgstr "Es wurde 1 Eintrag aus der %s Liste entfernt."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Ein Eintrag wurde aus der %s %s-Liste entfernt."
@@ -4339,11 +4335,6 @@ msgid ""
"database."
msgstr "Löscht den vHost des angegebenen Nicknamens."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr "Löscht den vHost aller Nicknamen in einer Gruppe"
-
#: modules/commands/hs_del.cpp:93
msgid ""
"Deletes the vhost for all nicks in the same group as\n"
@@ -4352,13 +4343,13 @@ msgstr ""
"Löscht den vHost aller Nicknamen aus der gleichen Gruppe \n"
"des angegeben Nicknamens."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "Die Beschreibung von %s wurde entfernt."
@@ -4373,7 +4364,7 @@ msgstr "Beschreibung von %s wurde geändert zu %s."
msgid "Description of %s unset."
msgstr "Die Beschreibung von %s wurde entfernt."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
msgid "Disabled"
msgstr "Deaktiviert"
@@ -4396,7 +4387,7 @@ msgstr ""
"\n"
"Ein Grund kann auf manchen Netzwerke notwendig sein."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Liste alle Einträge. (Count: %d)"
@@ -4506,12 +4497,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail Adresse für %s wurde auf %s geändert."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail Adresse %s wurde entfernt."
@@ -4535,7 +4526,7 @@ msgstr ""
"angezeigt. (Es werden jedoch nur max. %d angezeigt, um ein\n"
"Flooding des Users zu verhindern. Wenn mehr News\n"
"existieren, werden nur die neuesten angezeigt.)\n"
-"NewsCount kann in der services.conf eingestellt werden.\n"
+"NewsCount kann in der anope.conf eingestellt werden.\n"
"\n"
"Diese Funktion ist beschränkt auf Services Operatoren."
@@ -4554,7 +4545,7 @@ msgstr ""
"(Es werden jedoch nur max. %d Nachrichten angezeigt, um ein\n"
"Flooding des Users zu verhindern. Wenn mehr News\n"
"existieren, werden nur die neüsten angezeigt.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"Diese Funktion ist beschränkt auf Services Operatoren."
@@ -4577,7 +4568,7 @@ msgstr "E-mail-Adresse"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Passende Emails %s bis %s."
#: modules/fantasy.cpp:19
@@ -4588,11 +4579,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
msgid "Enabled"
msgstr "Aktiviert"
@@ -4622,14 +4613,14 @@ msgstr ""
"wiederhergestellt sobald jemand wieder in den Raum \n"
"kommt."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4716,11 +4707,10 @@ msgstr ""
"durch den Zugriffslevel bzw. QOP hat."
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Ändert die Secure-Ops Option für einen Channel.\n"
"Wird diese Option eingeschaltet, können Nicknamen, \n"
@@ -4762,7 +4752,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -4787,21 +4777,21 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Ende der User-Liste."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
msgid "End of access list"
msgstr "Ende der Zugangsliste."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Ende der Zugangsliste - %d/%d Treffer angezeigt."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Ende der Zugangsliste."
@@ -4809,7 +4799,7 @@ msgstr "Ende der Zugangsliste."
msgid "End of autokick list"
msgstr "Ende der Autokick-liste."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Ende der Badword-Liste."
@@ -4840,7 +4830,7 @@ msgstr "Ende der FORBID-Liste."
msgid "End of list - %d channels shown."
msgstr "Ende der Liste - %d/%d Treffer angezeigt."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Ende der Liste - %d/%d Treffer angezeigt."
@@ -4875,8 +4865,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Deutsch"
@@ -4933,43 +4923,48 @@ msgstr "Fehler! Der Vhost ist zu lang, er darf maximal %d Zeichen lang sein."
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "Die Ausnahme für %s (#%d) wurde auf die %d Position verschoben."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Ausnahme für %s ist zu %d aktualisiert worden."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
msgid "Expires"
msgstr "Läuft ab"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Ablaufzeit und Grund wurden für %s aktualisiert."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "Ablaufzeit von %s geändert."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasy-Modus"
@@ -4998,16 +4993,16 @@ msgstr "%s ist bereits auf der Zertifikat-Liste."
msgid "Fingerprint %s is already in use."
msgstr "%s ist bereits in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Zugriffs-Level für %s in %s wurde auf +%s geändert."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Flags-Liste von %s:"
@@ -5090,7 +5085,7 @@ msgstr "Neuer Gründer %s ist jetzt %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "GETPASS nicht verfügbar, da die Verschlüsselung aktiviert ist."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Ghost mit Deinem Nicknamen wurde entfernt."
@@ -5098,14 +5093,14 @@ msgstr "Ghost mit Deinem Nicknamen wurde entfernt."
msgid "Give Operflags to a certain user"
msgstr "Einem User \"Operflags\" setzen"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Gibt Dir Gründer Status in einem Chatraum"
@@ -5180,24 +5175,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Nicht invertiert schreiben!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "%s existiert bereits."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "Bot %s existiert bereits."
@@ -5206,8 +5197,8 @@ msgstr "Bot %s existiert bereits."
msgid "Identify yourself with your password"
msgstr "Melde dich mit deinem Passwort an"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr ""
@@ -5222,11 +5213,11 @@ msgstr "Die Ignore-Liste wurde geleert."
msgid "Ignore list is empty."
msgstr "Ignore-Liste ist leer."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
msgid "Ignore list:"
msgstr "Ignore Liste:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Voice-Schutz"
@@ -5281,7 +5272,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5300,7 +5291,7 @@ msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr ""
"Ungültiger Wert. Es muss eine gültige grade Zahl sein, die grösser als 1 ist."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5317,17 +5308,17 @@ msgstr "Italics kicker : %s"
msgid "Join a group"
msgstr "Verknüpfe deinen Nicknamen"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Nachrichten-Modus"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Peace Option für %s ist jetzt ON."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Peace Option für %s ist jetzt ON."
@@ -5345,7 +5336,7 @@ msgstr "Key für Chatrauml %s ist %s."
msgid "Kick a user from a channel"
msgstr "Kickt einen Benutzer aus einem Chatraum."
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5355,13 +5346,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr "Kickt den angegebenen Nicknamen aus einen Channel"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Syntax: KICK Channel Nickname [Grund]\n"
"\n"
@@ -5387,17 +5378,17 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
msgid "LIST [mask | list | id]"
msgstr "LIST [Channel | Liste | Nummer]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr "LIST [Channel | [Liste]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "[Nickname]"
@@ -5406,15 +5397,10 @@ msgstr "[Nickname]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [Text|Nummer]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Sprache wurde geändert zu Deutsch."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Vertreter von %s wurde geändert zu %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5424,7 +5410,7 @@ msgstr "Die letzte Memo an %s wurde widerrufen."
msgid "Last quit message"
msgstr "Letzte Quit-Nachricht:"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
msgid "Last seen"
msgstr "Letztes Mal gesehen:"
@@ -5432,11 +5418,11 @@ msgstr "Letztes Mal gesehen:"
msgid "Last seen address"
msgstr "Letzte gesehene Hostmaske: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr "Letztes Mal gesehen:"
@@ -5446,27 +5432,27 @@ msgstr "Letztes Mal gesehen:"
msgid "Last usermask"
msgstr "Letztes Mal gesehen:"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Der Level für %s für den Channel %s wurde geändert auf %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level für %s in Chatrauml %s zu \"founder only\" geändert."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Der Level kann nur zwischen %d und einschliesslich %d liegen."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5479,7 +5465,7 @@ msgstr "Listet alle registrieten Nicknamen des angegebenen Musters"
msgid "List channels you have access on"
msgstr "Listet Chaträume zu denen Du Zugang hast"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5488,7 +5474,7 @@ msgstr ""
msgid "List loaded modules"
msgstr "Listet die geladenen Module auf"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr "Liste der Einträge die mit %s übereinstimmen:"
@@ -5736,19 +5722,17 @@ msgid "Lists currently loaded modules."
msgstr "Listet alle geladenen Module auf"
#: modules/commands/cs_info.cpp:19
-#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr "Zeigt Informationen über den angegebenen Channel"
#: modules/commands/cs_info.cpp:76
-#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Zeigt Informationen über einen registrierten Channel,\n"
"seinen Gründer, das Datum der Registrierung, die\n"
@@ -5828,7 +5812,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5867,12 +5855,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK Die Autokick-Liste bearbeiten"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr " BOT Verwaltung von Bots"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -5880,7 +5868,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -5898,7 +5886,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -5910,7 +5898,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -5965,7 +5953,7 @@ msgstr ""
"Der BADWORDS CLEAR Befehl löscht alle Einträge aus der\n"
"Bad-Word-Liste."
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr " BADWORDS Verwaltet die Bad-Word-Liste"
@@ -5979,7 +5967,7 @@ msgstr " ACT Veranlaßt den Bot ein \"/me\" Befehl ausführen"
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Syntax: ACT Channel Text\n"
"\n"
@@ -5987,12 +5975,12 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr " SAY Veranlaßt ein Bot ein Text in einen Channel zu sagen"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr " SAY Veranlaßt ein Bot ein Text in einen Channel zu sagen"
#: modules/commands/greet.cpp:157
@@ -6027,7 +6015,7 @@ msgstr ""
"Du hast den nötigen Zugriffslevel in der Access-Liste\n"
"des Channels. \t"
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "Du kannst in diesem Netzwerk Deine eMail-Adresse nicht entfernen."
@@ -6047,12 +6035,12 @@ msgstr " IGNORE Die \"Services Ignore Liste\" bearbeiten"
msgid "Manage your auto join list"
msgstr " AKICK Die Autokick-Liste bearbeiten"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL Die AutoKill-Liste bearbeiten"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL Die AutoKill-Liste bearbeiten"
@@ -6062,20 +6050,20 @@ msgstr " AKILL Die AutoKill-Liste bearbeiten"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Ändert das DefCon System"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Ändert den Topic des angegebenen Channels"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6089,8 +6077,8 @@ msgstr "Diese Hostmaske %s ist bereits auf der Access-Liste."
msgid "Mask must be in the form user@host."
msgstr "Eine vHost muss eine gültige HostMaske besitzen."
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "Diese Hostmaske %s ist bereits auf der Access-Liste."
@@ -6122,7 +6110,7 @@ msgstr " Mode lock: %s"
msgid "Memo %d has been deleted."
msgstr "Memo %d wurde gelöscht."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Deine Ignore-Liste ist leer."
@@ -6144,7 +6132,7 @@ msgstr ""
"Memo-Limit von %s wurde auf 0 gesetzt, kein Memo-Empfang für ihn mehr "
"möglich."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo wurde an %s versandt."
@@ -6159,7 +6147,7 @@ msgstr " Mode lock: %s"
msgid "Message"
msgstr "Nachricht"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Nachrichten-Modus"
@@ -6167,26 +6155,26 @@ msgstr "Nachrichten-Modus"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Der Nickname %s wurde nicht in Deiner Ignore-Liste gefunden."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr " Mode lock: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr " Mode lock: %s"
@@ -6195,11 +6183,6 @@ msgstr " Mode lock: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6251,7 +6234,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6262,7 +6245,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Die \"Services Ignore Liste\" bearbeiten"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP Verwaltet die AOP-Liste von einen Channel"
@@ -6272,7 +6255,7 @@ msgstr " AOP Verwaltet die AOP-Liste von einen Channel"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS Liste der autorisierten Adressen"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr ""
@@ -6284,7 +6267,7 @@ msgstr ""
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Die \"Services Ignore Liste\" bearbeiten"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr ""
@@ -6335,14 +6318,14 @@ msgstr "Module: %s Version: %s Autor: %s geladen: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6355,19 +6338,19 @@ msgstr "Badword Liste von %s:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "Nickname"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "Der Nickname %s wurde aus der Datenbank entfernt."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "Dieser Nickname %s ist bereits registriert!"
@@ -6383,7 +6366,6 @@ msgid "Nick %s is an illegal nickname and cannot be used."
msgstr ""
"Der Nickname %s ist ein illegaler Nickname und kann nicht benutzt werden."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6399,7 +6381,7 @@ msgstr "Der Nickname %s wird derzeit benutzt."
msgid "Nick %s is forbidden."
msgstr "Der Nickname %s ist nicht gesperrt."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s ist ein services operator vom Typ %s."
@@ -6424,12 +6406,12 @@ msgstr "Der Nickname %s wurde erfolgreich registriert."
msgid "Nick %s was truncated to %d characters."
msgstr "Dein Nickname %s wurde auf %d Zeichen gekürzt."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nickname %s wird wieder verfallen."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nickname %s wird nicht mehr verfallen."
@@ -6494,17 +6476,17 @@ msgstr "Der Channel %s ist bereits registriert!"
msgid "Nickname %s may not be registered."
msgstr "Der Channel %s kann nicht registriert werden."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Dein Nickname %s ist unter Deinem Host registriert worden: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Der Nickname %s wurde erfolgreich registriert."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6513,7 +6495,7 @@ msgstr "Auto-op"
msgid "No bot"
msgstr "Kein Bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "läuft nicht aus"
@@ -6542,13 +6524,13 @@ msgstr "Keine zu löschenden Einträge in der Logon News-Liste gefunden."
msgid "No matches for %s found."
msgstr "Keine eingetragenen Emails für %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "Keine passenden Einträge in der %s AOP-Liste."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr ""
@@ -6559,23 +6541,23 @@ msgstr ""
msgid "No matching entries on %s autokick list."
msgstr "Keine entsprechenden Einträge auf der AutoKick-Liste von %s gefunden."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Keine entsprechenden Einträge zu %s in der Bad Words-Liste gefunden."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr ""
"Keine entsprechenden Einträge in der Liste der \n"
"Verbindungseinschränkungen."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Keine passenden Einträge in der %s AOP-Liste."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Keine entsprechenden Einträge auf der AKILL-Liste."
@@ -6588,7 +6570,12 @@ msgstr "Kein Memo konnte widerrufen werden."
msgid "No modules currently loaded matching that criteria."
msgstr "Derzeit keine Module geladen"
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Keine neuen Nicknamen-Registrierungen"
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6608,12 +6595,7 @@ msgstr "Keine randomnews Einträge zu löschen!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Keine neuen Nicknamen-Registrierungen"
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6622,8 +6604,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "Access-Liste von %s:"
@@ -6633,7 +6615,7 @@ msgstr "Access-Liste von %s:"
msgid "No such info \"%s\" on %s."
msgstr "%s wurde nach %s eingeladen."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Usermodi von %s geändert."
@@ -6648,7 +6630,7 @@ msgstr "No-Bot-Mode ist jetzt ON im Channel %s."
msgid "No-bot mode is now on on channel %s."
msgstr "No-Bot-Mode ist jetzt ON im Channel %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6657,21 +6639,21 @@ msgstr ""
msgid "None"
msgstr "Keine"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -6679,18 +6661,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [Text|Nummer]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Die alten Informationen stimmen mit den neuen überein."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Ist online von: %s"
-#: modules/commands/os_oper.cpp:139
-#, fuzzy, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr " Dieser Operator wurde in der Konfigurationsdatei eingestellt."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -6714,12 +6693,12 @@ msgstr "Oper-News-Eintrag #%d nicht gefunden!"
msgid "Oper news items:"
msgstr "Oper News Einträge:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "Der Nickname %s wurde aus der Datenbank entfernt."
@@ -6734,17 +6713,17 @@ msgstr "Operflags %s wurden für %s hinzugefügt. "
msgid "Operflags %s have been removed from %s."
msgstr "Operflags %s wurden für %s hinzugefügt. "
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -6758,12 +6737,12 @@ msgstr "Op-Schutz"
msgid "Options"
msgstr " Options : %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} Server"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -6780,12 +6759,12 @@ msgstr "Falsches Passwort."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "Vertreter von %s wurde geändert zu %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "Das Passwort von %s wurde per eMail verschickt."
@@ -6805,7 +6784,7 @@ msgstr "Falsches Passwort."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Frieden"
@@ -6819,7 +6798,7 @@ msgstr "Peace Option für %s ist jetzt ON."
msgid "Peace option for %s is now on."
msgstr "Peace Option für %s ist jetzt ON."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -6850,12 +6829,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Bitte warte noch %d Sekunden und versuche es dann erneut."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Bitte warte %d Sekunden bis Du den SEND Befehl wieder benutzen kannst."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Bitte warte %d Sekunden bis du den SEND Befehl wieder benutzen kannst."
@@ -6865,13 +6844,13 @@ msgstr "Bitte warte %d Sekunden bis du den SEND Befehl wieder benutzen kannst."
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Bitte warte %d Sekunden, bevor der GROUP Befehl wieder funktioniert."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Bitte warte %d Sekunden, bevor der REGISTER Befehl wieder funktioniert."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -6884,7 +6863,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -6916,7 +6895,7 @@ msgstr ""
" PRIVATE Verhindert, dass der Nickname im Befehl\n"
" /msg %s LIST auftaucht"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr ""
@@ -6927,17 +6906,17 @@ msgstr ""
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privat"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Private-Mode des Bots im %s ist jetzt ON."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Private-Mode des Bots im %s ist jetzt ON."
@@ -6962,36 +6941,36 @@ msgstr "Der Privat-Modus (PRIVATE) ist für %s jetzt aktiviert (ON)."
msgid "Private option is now on for %s."
msgstr "Der Privat-Modus (PRIVATE) ist für %s jetzt aktiviert (ON)."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Kill-Schutz"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Schutz des Nicknamens %s ist jetzt aktiviert (ON)."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Schutz des Nicknamens %s mit verkürzter Verzögerung aktiviert (ON)."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Schutz des Nicknamens %s ohne Verzögerung aktiviert (ON)."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Schutz des Nicknamens %s ist jetzt aktiviert (ON)."
@@ -7008,7 +6987,7 @@ msgstr ""
"Es werden die Einträge und komplette reale ident@host für jeden \n"
"Nickname benutzt, dann wird der AKILL durchgeführt. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Voice-Schutz"
@@ -7054,20 +7033,20 @@ msgstr " READ Lesen einer oder mehrerer Memos"
msgid "Real name"
msgstr " Echter Name: %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "%s wurde für %s entfernt."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7077,37 +7056,37 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr ""
" LEVELS Die Einstellungen verschiedener\n"
" Zugriffslevel neu definieren"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr ""
" RELEASE Hebt die Nickname-Sperre auf nach der \n"
" verwendung des RECOVER Befehls"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s ist eingeschaltet"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7119,12 +7098,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Registriert einen Nicknamen"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Registriert einen Nicknamen"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr " Registriert seit: %s"
@@ -7183,7 +7162,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7244,7 +7223,7 @@ msgstr ""
"Channel-Privilegien bekommen. Für weitere Informationen\n"
"über diese Funktion tippe /msg %s HELP GROUP."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Die Registrierung von Channels ist derzeit deaktiviert."
@@ -7254,12 +7233,12 @@ msgstr "Die Registrierung von Channels ist derzeit deaktiviert."
msgid "Regulate the use of critical commands"
msgstr " PEACE Regulate the use of critical commands"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Zeigt den Status des angegebenen Nicknamens an"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Löscht den vHost eines Users"
@@ -7307,46 +7286,46 @@ msgstr ""
msgid "Remove all operators from a server remotely"
msgstr " NOOP Alle O:Lines temporär deaktivieren"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr " Mode lock: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Gibt dem angegebenen Nicknamen Op-Status in einem Raum"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr "Kickt den angegebenen Nicknamen aus einen Channel"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7362,14 +7341,14 @@ msgstr " Repeat kicker : %s"
msgid "Request a vHost for your nick"
msgstr "Du hast keine zulässige Email Adresse gesetzt."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Die Konfigurationsdatei neu einlesen"
@@ -7379,7 +7358,7 @@ msgstr " RELOAD Die Konfigurationsdatei neu einlesen"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Eingeschränkter Zugriff auf den Channel"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Eingeschränkter Zugang"
@@ -7421,7 +7400,7 @@ msgstr ""
" Datenbank auslesen (nur wenn keine\n"
" Verschlüsselung aktiv ist)"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7437,8 +7416,17 @@ msgstr " GETKEY Gibt den Channel-Schlüßel wieder"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Gibt den Channel-Schlüßel wieder"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Syntax: GETEMAIL user@emailhost\n"
+"Gibt die passenden Nicknamen auf, welche die gegebene eMail benutzen. \n"
+"Beachte, dass Du keine wildcards für den User oder emailhost\n"
+"verwenden kannst. Immer, wenn dieser Befehl benutzt wird, wird\n"
+"eine Nachricht mit dem Nickname der Person mitgeloggt."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7523,16 +7511,16 @@ msgstr " LOGOUT Macht das IDENTIFY Befehl rückgängig"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} Server"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Passwort akzeptiert - Du bist jetzt angemeldet."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Passwort akzeptiert - Du bist jetzt angemeldet."
@@ -7555,7 +7543,7 @@ msgstr " RESTART Datenbanken speichern und Services neustarten"
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Sicher Founder"
@@ -7570,7 +7558,7 @@ msgstr "Secure Founder Option für %s ist jetzt ON."
msgid "Secure founder option for %s is now on."
msgstr "Secure Founder Option für %s ist jetzt ON."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Sicher Ops"
@@ -7595,12 +7583,12 @@ msgstr "Secure Option für %s ist jetzt ON."
msgid "Secure option for %s is now on."
msgstr "Secure Option für %s ist jetzt ON."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Sicherheitsfunktion (SECURE) ist für %s jetzt aktiviert (ON)."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Sicherheitsfunktion (SECURE) ist für %s jetzt aktiviert (ON)."
@@ -7610,11 +7598,11 @@ msgstr "Sicherheitsfunktion (SECURE) ist für %s jetzt aktiviert (ON)."
msgid "Secureops enforced on %s."
msgstr "Sicherheitsfunktion (SECURE) ist für %s jetzt aktiviert (ON)."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Sicherheits Modus"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7623,7 +7611,7 @@ msgstr ""
"Tippe %s%s HELP %s für weitere Informationen\n"
"zu einem bestimmten Befehl."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7692,7 +7680,7 @@ msgstr ""
"Sendet allen Usern mit Zugriff auf die Services eine Nachricht mit\n"
"dem Memo-Text."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -7771,14 +7759,14 @@ msgid "Server %s already exists."
msgstr "%s existiert bereits."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (wird nicht auslaufen)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "Der Nickname %s wurde aus der Datenbank entfernt."
@@ -7788,12 +7776,12 @@ msgstr "Der Nickname %s wurde aus der Datenbank entfernt."
msgid "Server %s is already in zone %s."
msgstr "%s ist bereits in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s ist derzeit online."
@@ -7808,12 +7796,12 @@ msgstr " %s (wird nicht auslaufen)"
msgid "Server %s is not linked to the network."
msgstr "Der Bot von %s wurde entfernt."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (wird nicht auslaufen)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -7833,19 +7821,18 @@ msgstr "Server gefunden: %d"
msgid "Service"
msgstr "Server gefunden: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Die Services haben den Nicknamen wieder verfügbar gemacht."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s ist ein services operator vom Typ %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr ""
@@ -7901,7 +7888,7 @@ msgstr "Der Service emails zu versenden wurde deaktiviert."
msgid "Services ignore list:"
msgstr " IGNORE Die \"Services Ignore Liste\" bearbeiten"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -7915,7 +7902,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Server gefunden: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr ""
@@ -7929,7 +7916,7 @@ msgstr ""
"Die Services werden %s jetzt nicht mehr automatisch Op-Status geben in den "
"Channels."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr ""
@@ -7942,12 +7929,12 @@ msgid "Services will now automatically give modes to users in %s."
msgstr ""
"Die Services werden %s jetzt automatisch Op-Status geben in den Channels."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Die Services werden jetzt %s mit messages antworten."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Die Services werden jetzt %s mit notices antworten."
@@ -7966,7 +7953,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Verbindungslimit für %s geändert auf %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Eingeschränkte Verbindungen sind deaktiviert."
@@ -8016,7 +8003,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC Ändert die Channel-Beschreibung"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Ändert den \"Ursprung\" Deiner Gruppe"
@@ -8026,14 +8013,14 @@ msgstr " DISPLAY Ändert den \"Ursprung\" Deiner Gruppe"
msgid "Set the founder of a channel"
msgstr " FOUNDER Stellt den Gründer des Channels ein"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE Stellt die Sprache ein, in der Dir die \n"
" Services antworten sollen."
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Setzt das Passwort eines Nicknamens"
@@ -8416,7 +8403,7 @@ msgstr ""
"Stellt verschiedene Optionen zu Deinem Nicknamen ein.\n"
"Option kann eines der folgenden Werte sein:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8433,7 +8420,7 @@ msgstr ""
"auf ON gestellt, wird der Channel bei Nichtnutzung\n"
"nicht auslaufen."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8449,7 +8436,7 @@ msgstr ""
"angegebenen Nicknamen automatisch Op-Status zu geben,\n"
"wenn der Nick die Channels betritt."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8461,7 +8448,7 @@ msgstr ""
"verfällt. Wird NOEXPIRE auf ON gesetzt verfällt\n"
"der Nickname nie."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8475,7 +8462,7 @@ msgstr ""
"erlaubt es ChanServ Dir automatisch Op-Status zu geben,\n"
"wenn Du die Channels betrittst."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8547,11 +8534,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Signierte kicks Option für %s ist jetzt ON."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Signierte kicks"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s hat zu viele Memos gespeichert und kann keine weiteren empfangen."
@@ -8561,44 +8548,38 @@ msgstr "%s hat zu viele Memos gespeichert und kann keine weiteren empfangen."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Das Ändern der Bad Words-Liste ist derzeit deaktiviert."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Die SET-Optionen sind derzeit deaktiviert."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Das Verändern von Bot-Einstellungen ist derzeit deaktiviert."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Die SET-Optionen sind derzeit deaktiviert."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Die SET-Optionen sind derzeit deaktiviert."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Die Channel AOP-Liste kann derzeit nicht geändert werden."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Das Ändern der Channel-Access-Liste wurde zwischenzeitig deaktiviert."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Das Bearbeiten der AutoKick-Liste wurde zwischenzeitlich deaktiviert."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Das Ändern der Bad Words-Liste ist derzeit deaktiviert."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Das Entfernen von Channel-Registrierungen ist derzeit deaktiviert."
@@ -8628,7 +8609,7 @@ msgstr "Das Entfernen von Nicknamen ist derzeit deaktiviert."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Das Gruppieren von Nicknamen ist derzeit deaktiviert."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Das Registrieren von Nicknamen ist derzeit deaktiviert."
@@ -8647,13 +8628,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Du kannst nur %d Einträge auf der Access-Liste speichern."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Die Liste der Begrüßungsnachrichten für %s ist voll."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8665,7 +8641,7 @@ msgstr "Die Access-Liste ist auf %d Einträge beschränkt."
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Du kannst nur max. %d Einträge auf der AutoKick-Liste haben."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Du kannst nur %d Einträge in der Bad Words-Liste eines Channels haben."
@@ -8732,7 +8708,7 @@ msgstr "Der Eintrag des Vertreters für %s wurde entfernt."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "SuperAdmin muss in der services.conf eingeschaltet werden."
+msgstr "SuperAdmin muss in der anope.conf eingeschaltet werden."
#: modules/commands/ns_suspend.cpp:60
#, fuzzy
@@ -8958,7 +8934,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9037,7 +9013,7 @@ msgstr ""
"werden, wenn er wirklich gebraucht wird. Danach sollte er\n"
"sofort wieder ausgeschaltet werden."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9061,7 +9037,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Syntax: INVITE Channel\n"
@@ -9080,7 +9056,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Syntax: UNBAN Channel [nick]\n"
@@ -9128,7 +9104,7 @@ msgstr " Datenbanken speichern und Services beenden"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9139,7 +9115,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9148,7 +9124,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9165,10 +9141,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9176,14 +9152,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9198,7 +9174,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Syntax: HOP Channel ADD Nickname\n"
@@ -9237,36 +9213,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "Die IMMED Option ist in diesem Netzwerk nicht verfügbar."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9315,7 +9291,7 @@ msgstr ""
"Für eine vollständige Liste der Funktionen für die Levels gesetzt werden "
"können: HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9326,18 +9302,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9345,7 +9321,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9362,7 +9338,6 @@ msgstr ""
" \n"
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9380,7 +9355,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9390,12 +9365,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Die Liste der Begrüßungsnachrichten für %s ist voll."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "Die AKILL-Liste wurde geleert."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "Die AKILL-Liste wurde geleert."
@@ -9414,7 +9389,7 @@ msgstr "Die Emailadresse %s wird jetzt bei %s INFO Abrufen versteckt."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "Die Emailadresse %s wird jetzt bei %s INFO Abrufen angezeigt."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9445,11 +9420,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Die Liste der Begrüßungsnachrichten für %s ist voll."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9517,12 +9492,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "Du hast keine Berechtigung das Memo-Limit für %s zu ändern."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Die Liste der Begrüßungsnachrichten für %s ist voll."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9537,10 +9507,6 @@ msgstr "Die neue Anzeige ist jetzt %s"
msgid "The nick %s is now being changed to %s."
msgstr "Der Nickname %s wird jetzt zu %s geändert."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9566,11 +9532,11 @@ msgstr ""
"Die Services-Zugriffsberechtigungen von %s werden jetzt bei %s INFO Abrufen "
"angezeigt."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
msgid "The session exception list is empty."
msgstr "Die Liste der Verbindungsausnahmen ist leer."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9644,7 +9610,7 @@ msgstr "Keine randomnews vorhanden."
msgid "There is no such configuration block %s."
msgstr "Zur Zeit gibt es keine Log Informationen für %s."
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Es gibt keine Oper-News."
@@ -9672,7 +9638,7 @@ msgstr "Dieser Channel kann nicht benutzt werden."
msgid "This channel may not be used."
msgstr "Dieser Channel kann nicht benutzt werden."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9708,7 +9674,7 @@ msgstr ""
"Dieser Befehl erlaubt es Usern, den vHost ihres aktuellen\n"
"Nicknamens, zum vHost der gesamten Gruppe zu setzen."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9721,7 +9687,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -9755,8 +9721,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -9858,7 +9824,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9872,7 +9838,7 @@ msgstr ""
"Dieser Befehl lädt das benannte Module aus dem \n"
"modules - Verzeichnis."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -9925,7 +9891,7 @@ msgstr ""
"Dieser Befehl lädt das benannte Module aus dem \n"
"modules - Verzeichnis."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -9941,12 +9907,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Dieser Nickname ist zur Zeit gesperrt, Grund: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "Dieser Nickname wurde von %s wiederhergestellt."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10007,7 +9973,7 @@ msgstr ""
msgid "Topic"
msgstr "Topic-Sperre"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Topic-Sperre"
@@ -10022,7 +9988,7 @@ msgstr "Topic-Sperre Option für %s ist jetzt deaktiviert (OFF)."
msgid "Topic lock option for %s is now on."
msgstr "Topic-Sperre Option für %s ist jetzt ON."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Topic-Wiederherstellung"
@@ -10037,7 +10003,7 @@ msgstr "Die Topic-Beibehaltung für %s ist jetzt deaktiviert (OFF)."
msgid "Topic retention option for %s is now on."
msgstr "Die Topic-Beibehaltung für %s ist jetzt aktiviert (ON)."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10045,21 +10011,22 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Schalte Caps-Lock aus!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr ""
" SECURE Aktiviert/Deaktiviert den Sicherheitsmodus\n"
" für Deinen Nicknamen"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr ""
" SECURE Aktiviert/Deaktiviert den Sicherheitsmodus\n"
" für Deinen Nicknamen"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL Stellt Kill-Schutz an oder aus."
@@ -10104,7 +10071,7 @@ msgstr ""
"dem INFO Befehl Informationen über Deinen Nicknamen \n"
"abrufen, unabhängig vom Privat-Modus.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10140,7 +10107,7 @@ msgstr ""
" SECURE Aktiviert/Deaktiviert den Sicherheitsmodus\n"
" für Deinen Nicknamen"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10173,7 +10140,7 @@ msgstr ""
"Ausserdem ist es möglich, dass die Netz-Admins\n"
"diese Option deaktiviert haben."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10206,7 +10173,7 @@ msgstr ""
"Ausserdem ist es möglich, dass die Netz-Admins\n"
"diese Option deaktiviert haben."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10247,7 +10214,7 @@ msgstr ""
"\n"
"Die Befehle sind nur für Services Admins verfügbar."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10256,7 +10223,7 @@ msgstr ""
"Tippe /msg %s HELP Option für weitere Informationen\n"
"zu einem bestimmten Befehl."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10274,8 +10241,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Entfernt ein Modul"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Kann Modul %s nicht entfernen"
@@ -10320,7 +10287,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr " Underlines kicker : %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Ubekannte SASET option %s."
@@ -10340,7 +10307,7 @@ msgstr "Unbekannte Option %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Unbekannter Befehl %s. \"%s%s HELP\" für Hilfe."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Unbekanntes Mode-Zeichen: %c wurde ignoriert."
@@ -10368,8 +10335,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Syntax: DROP Channel\n"
"\n"
@@ -10390,10 +10357,10 @@ msgstr " UNSUSPEND Unsuspend den angegebenen Nicknamen"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10443,33 +10410,33 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "Ändert die Raum Modi"
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr ""
" ACCESS Die Liste der priviligierten User\n"
" bearbeiten"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "Dein Ban in %s wurde entfernt."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "vHost für %s wurde entfernt."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Memo-Limit von %s wurde auf %d gesetzt."
@@ -10521,13 +10488,13 @@ msgstr "Der vHost für die Gruppe %s wurde gesetzt auf %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [Channel] [Liste | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10540,7 +10507,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "Founder von %s wurde geändert zu %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Vhost"
msgstr "vHost"
@@ -10578,7 +10545,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10675,7 +10642,7 @@ msgstr ""
"gesetzt, unter anderem die max. Anzahl gleichzeitig\n"
"verbundenen User."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10684,7 +10651,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Du bist bereits Mitglied der Gruppe %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Du bist bereits angemeldet."
@@ -10726,8 +10693,7 @@ msgstr "Du bist jetzt ein IRC Operator."
#: modules/commands/ns_resetpass.cpp:108
msgid "You are now identified for your nick. Change your password now."
-msgstr ""
-"Du bist jetzt für Deinen Nick angemeldet. Bitte ändere jetzt das Passwort."
+msgstr "Du bist jetzt für Deinen Nick angemeldet. Bitte ändere jetzt das Passwort."
#: modules/commands/ns_group.cpp:50
#, c-format
@@ -10748,7 +10714,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10775,13 +10741,25 @@ msgstr ""
"Das Erhalten von Empfangsbestätigungen ist nur beim Senden\n"
"einer Memo an andere User möglich."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, c-format
+msgid "You can not set the %c flag."
+msgstr "Du kannst das %c flag nicht setzen."
+
+#: modules/commands/bs_assign.cpp:124
+#, fuzzy
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr ""
+"Du kannst die Zuweisung eines Bots nicht entfernen während im channel "
+"\"persist\" gesetzt ist."
+
+#: modules/commands/ns_recover.cpp:143
#, c-format
msgid "You can't %s yourself!"
msgstr "Du kannst %s nicht auf Dich selbst anwenden!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr ""
@@ -10794,16 +10772,11 @@ msgstr ""
"Ausloggen von %s nicht möglich, da es sich um einen Services Administrator "
"handelt."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, c-format
msgid "You cannot %s on this network."
msgstr "Du kannst in diesem Netzwerk nicht %s ."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "Du kannst das %c flag nicht setzen."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10814,14 +10787,7 @@ msgstr "Du kannst das Memo-Limit für %s nicht höher als %d setzen."
msgid "You cannot set your memo limit higher than %d."
msgstr "Du kannst Dein Memo-Limit nicht höher als %d setzen."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr ""
-"Du kannst die Zuweisung eines Bots nicht entfernen während im channel "
-"\"persist\" gesetzt ist."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Du kannst in diesem Netzwerk Deine eMail-Adresse nicht entfernen."
@@ -10861,12 +10827,12 @@ msgstr "Du hast derzeit eine Nachricht."
msgid "You currently have no memos."
msgstr "Du hast keine Memos."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -10904,7 +10870,7 @@ msgstr "Du wurdest zu %seingeladen."
msgid "You have been invited to %s."
msgstr "Du wurdest zu %seingeladen."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "Du bist als %seingeloggt."
@@ -10945,35 +10911,30 @@ msgstr ""
"keine weiteren Nachrichten empfangen, bis Du einige Deiner jetzigen Memos "
"gelöscht hast."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Du wurdest zu %seingeladen."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr "Es befinden sich zu viele Nicks in der Gruppe von %s."
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
msgid "You may not change the e-mail of other Services Operators."
msgstr ""
"Du kannst in diesem Netzwerk die eMail-Adresse anderer \"Servive Operaotors"
"\" nicht ändern."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr ""
"Du kannst in diesem Netzwerk die eMail-Adresse anderer \"Servive Operaotors"
"\" nicht ändern."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr ""
@@ -11030,31 +10991,12 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "Du musst Channel-Operator sein um diesen Channel zu registrieren."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "Du musst dich anmelden um diesen Befehl zu nutzen."
-
#: modules/commands/cs_register.cpp:37
msgid "You must confirm your account before you can register a channel."
msgstr ""
"Du musst Deinen Account bestätigen bevor Du einen Chatraum registrieren "
"kannst."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr ""
-"Du musst Deinen Account bestätigen bevor Du einen Chatraum registrieren "
-"kannst."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr ""
-"Du musst Deinen Account bestätigen bevor Du einen Chatraum registrieren "
-"kannst."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11062,21 +11004,21 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"Du musst länger als %d Sekunden verbunden sein, um einen Nicknamen zu "
"registrieren."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
"Bevor Du diesen Befehl benutzen kannst musst Du dem Chatraum erst einen Bot "
"zuordnen."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11090,39 +11032,17 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "Du musst dich anmelden um diesen Befehl zu nutzen."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Du wirst bei neuen Memos benachrichtigt, wenn sie eintreffen."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Du wirst bei neuen Memos benachrichtigt, wenn Du dich identifizierst bzw "
-"wenn sie eintreffen."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Du wirst bei neuen Memos benachrichtigt, wenn Du dich identifizierst bzw "
"wenn sie eintreffen."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Du wirst bei neuen Memos benachrichtigt, wenn Du dich identifizierst bzw "
-"wenn sie eintreffen."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Du wirst bei neuen Memos benachrichtigt, wenn Du dich identifizierst."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Du wirst bei neuen Memos benachrichtigt, wenn sie eintreffen."
@@ -11134,7 +11054,7 @@ msgstr "Du wirst ab sofort keine Memos mehr empfangen können."
msgid "You will no longer be informed via email."
msgstr "Du wirst nicht länger per Email über neue Memos benachrichtigt."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Du wirst bei neuen Memos nicht benachrichtigt."
@@ -11166,22 +11086,22 @@ msgstr ""
"Dein IRCd unterstützt keine vIdent's.\n"
"Sollte dies falsch sein bitte melde einen Bug."
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Dein Account %s wurde erfolgreich angelegt."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
msgid "Your account is already confirmed."
msgstr "Dein Account ist bereits bestätigt."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Wenn Dein Account nicht bestätigt wird, wird er in %s auslaufen."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Deine eMail-Adresse wurde auf %s geändert."
@@ -11191,18 +11111,18 @@ msgstr "Deine eMail-Adresse wurde auf %s geändert."
msgid "Your email address is not allowed, choose a different one."
msgstr "Deine eMail-Adresse %s wurde bestätigt.#"
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Deine eMail-Adresse %s wurde bestätigt.#"
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, c-format
msgid "Your email has been updated to %s"
msgstr "Deine eMail Adresse wurde auf %s geändert."
@@ -11262,7 +11182,7 @@ msgstr ""
msgid "Your nick isn't registered."
msgstr "Dein Nick ist nicht registriert."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Dein Nickname wurde geändert in %s"
@@ -11271,19 +11191,18 @@ msgstr "Dein Nickname wurde geändert in %s"
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Dein Passcode wurde noch einmal an %s geschickt."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Dein Passwort ist %s - behalte es für spätere Benutzung."
#: include/language.h:77
-#, fuzzy, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
"Dein Passwort ist zu lang, bitte versuche es mit einem kürzeren Passwort."
@@ -11291,23 +11210,23 @@ msgstr ""
msgid "Your password reset request has expired."
msgstr "Deine Anfrage für die Zurücksetzung des Passworts ist abgelaufen."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
msgid "Your vHost has been requested."
msgstr "Dein vHost wurde beantragt"
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Dein vHost (%s) ist jetzt aktiviert."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Dein vHost (%s@%s) ist jetzt aktiviert."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
#, fuzzy
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Dein vHost wurde entfernt und das normale cloaking wiederhergestellt."
@@ -11356,7 +11275,7 @@ msgstr "[Random News - %s] %s"
msgid "[account] password"
msgstr "[Account] Passwort"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
msgid "[channel [nick]]"
msgstr "Chatraum [nick]"
@@ -11410,8 +11329,8 @@ msgstr "Nickname"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
msgid "[nickname]"
msgstr "[Nickname]"
@@ -11431,7 +11350,7 @@ msgstr "[+Zeit] {Channel} [Grund]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11439,20 +11358,20 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[Auto Memo] Dein beantragter vHost wurde akzeptiert."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[Auto Memo] Dein beantragert vHost wurde abgelehnt."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[Auto Memo] Dein beantragter vHost wurde abgelehnt. Grund: %s"
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[Auto Memo] %2$s hat den vHost %1$s beantragt."
@@ -11554,12 +11473,12 @@ msgstr "Sekunde"
msgid "seconds"
msgstr "Sekunden"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "vHost für %s ist jetzt aktiviert."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "vHost für %s wurde abgelehnt."
@@ -11594,40 +11513,6 @@ msgstr "Channel Nick"
msgid "{nick | channel}"
msgstr "{Nickname | Channel}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
msgid "{nick | channel} memo-text"
msgstr "{Nickname | Channel} Memo-text"
-
-#, fuzzy
-#~ msgid ""
-#~ " \n"
-#~ "The %s commands are limited to founders\n"
-#~ "(unless SECUREOPS is off). However, any user on the\n"
-#~ "VOP list or above may use the %s LIST command.\n"
-#~ " \n"
-#~ msgstr ""
-#~ " \n"
-#~ "Die QOP Befehle sind auf den Gründer des Raumes\n"
-#~ "beschränkt. (ausser SECUREOPS wurde deaktiviert).\n"
-#~ "Aber jeder Benutzer in der QOP-Liste darf den\n"
-#~ "QOP LIST Befehl benutzen.\n"
-#~ " \n"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "Die Ausnahme für %s (#%d) wurde auf die %d Position verschoben."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Die alten Informationen stimmen mit den neuen überein."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Syntax: GETEMAIL user@emailhost\n"
-#~ "Gibt die passenden Nicknamen auf, welche die gegebene eMail benutzen. \n"
-#~ "Beachte, dass Du keine wildcards für den User oder emailhost\n"
-#~ "verwenden kannst. Immer, wenn dieser Befehl benutzt wird, wird\n"
-#~ "eine Nachricht mit dem Nickname der Person mitgeloggt."
diff --git a/language/anope.el_GR.po b/language/anope.el_GR.po
index bed05d629..1afa99c9b 100644
--- a/language/anope.el_GR.po
+++ b/language/anope.el_GR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 20:34-0400\n"
"Last-Translator: VisioN <vision@myirc.us>\n"
"Language-Team: Greek\n"
@@ -27,17 +27,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "Το ψευδώνυμό σου σβήστηκε επιτυχώς από την υπηÏεσία."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "#%s# Ï€Ïοσθέθηκε στην λίστα AKILL."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "Ο/η #%s# Ï€Ïοσθέθηκε στο access list του %s με επίπεδο Ï€Ïόσβασης #%d#."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "Ο/η #%s# Ï€Ïοσθέθηκε στο access list του %s με επίπεδο Ï€Ïόσβασης #%d#."
@@ -47,7 +47,7 @@ msgstr "Ο/η #%s# Ï€Ïοσθέθηκε στο access list του %s με επί
msgid "%s added to %s autokick list."
msgstr "Ο/η #%s# Ï€Ïοσθέθηκε επιτυχώς στην autokick λίστα του %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "#%s# Ï€Ïοσθέθηκε στην λίστα των κακών λέξεων του %s."
@@ -62,17 +62,17 @@ msgstr "#%s# έγινε Ï€Ïοσθήκη στην λίστα Ï€Ïόσβασής
msgid "%s added to %s's certificate list."
msgstr "#%s# έγινε Ï€Ïοσθήκη στην λίστα Ï€Ïόσβασής σου."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "#%s# έγινε Ï€Ïοσθήκη στην λίστα αγνόησης σου."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "#%s# Ï€Ïοσθέθηκε στην λίστα AKILL."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "#%s# Ï€Ïοσθέθηκε στην λίστα AKILL."
@@ -108,7 +108,7 @@ msgstr ""
"εντολές γÏάψτε #/msg %s HELP #command##. \n"
" "
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -125,7 +125,7 @@ msgstr ""
"Για πεÏισσότεÏες πληÏοφοÏίες σε μια συγκεκÏιμένη εντολή,γÏάψτε\n"
"#/msg %s HELP ^_command^_#."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -141,7 +141,7 @@ msgstr ""
"Για πεÏισσότεÏες πληÏοφοÏίες σε μια συγκεκÏιμένη εντολή,γÏάψτε\n"
"#/msg %s HELP ^_command^_#."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -162,7 +162,7 @@ msgstr ""
"συγκεκÏιμένη εντολή, πληκτÏολογήστε #/msg %s HELP #εντολή##.\n"
" "
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "Το #%s# υπάÏχει ήδη στη λίστα κακών λέξεων του %s"
@@ -183,7 +183,7 @@ msgstr "#%s# already exists on the EXCEPTION list."
msgid "%s cannot be taken as times to ban."
msgstr "#%s# δεν μποÏεί να πάÏει τόσο χÏόνο Ï„o ban."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "Ο/η #%s# άλλαξε τα usermodes σας."
@@ -193,12 +193,12 @@ msgstr "Ο/η #%s# άλλαξε τα usermodes σας."
msgid "%s channel list:"
msgstr "Τέλος λίστας καναλιοÏ."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "Ο/η #%s# διαγÏάφηκε επιτυχώς από την AOP λίστα του %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "#%s# διαγÏάφηκε από το access list του %s."
@@ -208,7 +208,7 @@ msgstr "#%s# διαγÏάφηκε από το access list του %s."
msgid "%s deleted from %s autokick list."
msgstr "Ο/η #%s# διαγÏάφτηκε από την autokick list του %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "#%s# διαγÏάφτηκε από την λίστα των κακών λέξεων απο το %s."
@@ -233,12 +233,12 @@ msgstr "#%s# διαγÏάφηκε από την λίστα session-limit excepti
msgid "%s deleted from the %s list."
msgstr "Ο/η #%s# διαγÏάφηκε επιτυχώς από την AOP λίστα του %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "#%s# διαγÏάφηκε από την λίστα AKILL."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "Τα #%s# απενεÏγοποιήθηκαν στο κανάλι %s."
@@ -312,7 +312,7 @@ msgstr "Είστε ήδη στο κανάλι #%s#! "
msgid "%s is already in %s."
msgstr "Είστε ήδη στο κανάλι #%s#! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "#%s# είναι ήδη στη λίστα αγνόησης σου"
@@ -322,7 +322,7 @@ msgstr "#%s# είναι ήδη στη λίστα αγνόησης σου"
msgid "%s is already suspended."
msgstr "Είστε ήδη στο κανάλι #%s#! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "#%s# δεν είναι σωστό bot ή κατοχυÏωμένο κανάλι."
@@ -352,7 +352,7 @@ msgstr "Τα #%s# απενεÏγοποιήθηκαν στο κανάλι %s."
msgid "%s is not in %s."
msgstr "Είστε ήδη στο κανάλι #%s#! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "Ο/η #%s# δεν βÏέθηκε στη λίστα αγνόησης σου."
@@ -384,12 +384,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "Ο/η #%s# Ï€Ïοσθέθηκε επιτυχώς στην autokick λίστα του %s."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "Ο/η #%s# δεν βÏέθηκε η θέση στην AOP λίστα του %s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "Ο/η #%s# δεν βÏέθηκε στην access list του %s"
@@ -399,7 +399,7 @@ msgstr "Ο/η #%s# δεν βÏέθηκε στην access list του %s"
msgid "%s not found on %s autokick list."
msgstr "O #%s# δεν βÏέθηκε στην autokick list του %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "#%s# δεν βÏέθηκε στη λίστα των κακών λέξεων του %s."
@@ -436,17 +436,17 @@ msgstr "#%s# δεν βÏέθηκε στην λίστα session-limit exception."
msgid "%s not found on the %s list."
msgstr "Ο/η #%s# δεν βÏέθηκε η θέση στην AOP λίστα του %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "#%s# δεν βÏέθηκε στην λίστα AKILL."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "#%s# διαγÏάφηκε από το access list του %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "#%s# διαγÏάφτηκε από την λίστα Ï€Ïόσβασής σου."
@@ -476,19 +476,19 @@ msgstr "#%s# θα αγνοείται για πάντα."
msgid "%s%s HELP %s for more information."
msgstr "’γνωστη εντολή #%s#. \"/msg %s HELP\" για βοήθεια."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL #<nick>#."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -503,6 +503,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -562,7 +565,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -581,18 +584,18 @@ msgstr "#[auto-memo]# Το memo που στείλατε στο %s έχει διÎ
msgid "[target] [password]"
msgstr "^_στόχος^_ ^_κωδικό^_"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET #nickname# AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
msgid "channel"
@@ -631,7 +634,7 @@ msgstr "UNBAN #κανάλι# [#nick#]"
msgid "channel nick [reason]"
msgstr "BAN ##channel# #nick# [#reason#]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr ""
@@ -639,7 +642,7 @@ msgstr ""
msgid "channel text"
msgstr "ACT #κανάλι# #κείμενο#"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT #κανάλι# #κείμενο#"
@@ -653,12 +656,12 @@ msgstr "KICK #channel# #user# #reason#"
msgid "channel what"
msgstr "ACT #κανάλι# #κείμενο#"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "ACT #κανάλι# #κείμενο#"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -667,7 +670,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "ACT #κανάλι# #κείμενο#"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -675,18 +678,18 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr ""
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC #κανάλι# [#topic#]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
msgid "channel CLEAR"
msgstr ""
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC #κανάλι# [#topic#]"
@@ -701,7 +704,7 @@ msgstr "DROP #channel#"
msgid "channel DEL num"
msgstr "UNBAN #κανάλι# [#nick#]"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
msgid "channel DEL {mask | entry-num | list}"
msgstr ""
@@ -709,7 +712,7 @@ msgstr ""
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr ""
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
msgid "channel DEL {word | entry-num | list}"
msgstr ""
@@ -717,7 +720,7 @@ msgstr ""
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr ""
@@ -725,38 +728,47 @@ msgstr ""
msgid "channel LIST [mask | entry-num | list]"
msgstr ""
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
msgid "channel LIST [mask | list]"
msgstr ""
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
#
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP #channel# {ADD|DEL|LIST|CLEAR} [#nick# | #entry-list#]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
msgid "channel RESET"
msgstr ""
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
msgid "channel SET modes"
msgstr ""
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC #κανάλι# [#topic#]"
+
#: modules/commands/cs_akick.cpp:426
msgid "channel VIEW [mask | entry-num | list]"
msgstr ""
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
msgid "channel VIEW [mask | list]"
msgstr ""
@@ -765,7 +777,7 @@ msgstr ""
msgid "channel [description]"
msgstr "Αλλάζει την πεÏιγÏαφή του καναλιοÏ"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
msgid "channel [nick]"
msgstr "UNBAN #κανάλι# [#nick#]"
@@ -773,7 +785,7 @@ msgstr "UNBAN #κανάλι# [#nick#]"
msgid "channel [parameters]"
msgstr ""
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN #κανάλι# [#nick#]"
@@ -788,23 +800,13 @@ msgstr "BAN ##channel# #nick# [#reason#]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN ##channel# #nick# [#reason#]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN ##channel# #nick# [#reason#]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC #κανάλι# [#topic#]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "SET #channel# XOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET #channel# XOP {ON | OFF}"
@@ -835,7 +837,7 @@ msgstr "KICK #channel# #option# {#ON|OFF#} [#settings#]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET #channel# XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -858,24 +860,24 @@ msgstr "SET #channel# XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr ""
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
msgid "memo-text"
msgstr "STAFF #memo-text#"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
msgid "message"
msgstr ""
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -884,8 +886,9 @@ msgid "new-password"
msgstr ""
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
msgid "nick"
msgstr ""
@@ -911,17 +914,17 @@ msgstr "SET #<nick># #<hostmask>#."
msgid "nick newnick"
msgstr ""
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN ##channel# #nick# [#reason#]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
msgid "nickname"
msgstr "CHECK #nickname#"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr ""
@@ -930,7 +933,7 @@ msgstr ""
msgid "nickname email"
msgstr "DEL #<nick>#."
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr ""
@@ -938,12 +941,12 @@ msgstr ""
msgid "nickname message"
msgstr ""
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr ""
#
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "Ρυθμίζει τον κωδικό του ψευδονÏμου."
@@ -952,7 +955,7 @@ msgid "nickname [parameter]"
msgstr ""
#
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "Ρυθμίζει τον κωδικό του ψευδονÏμου."
@@ -967,14 +970,14 @@ msgstr "SUSPEND nickname reason"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
msgid "nickname {ON | OFF}"
msgstr "SASET #nickname# AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET #nickname# KILL {ON | QUICK | IMMED | OFF}"
@@ -1015,12 +1018,12 @@ msgid "password"
msgstr "LOGIN #password#"
#
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
msgid "password [email]"
msgstr "^_κωδικό^_ ^_email^_"
#
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
msgid "password email"
msgstr "^_κωδικό^_ ^_email^_"
@@ -1037,7 +1040,7 @@ msgstr "LIST #pattern# [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE #servername# [#reason#]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr ""
@@ -1045,7 +1048,7 @@ msgstr ""
msgid "user [reason]"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, c-format
msgid ""
" \n"
@@ -1064,7 +1067,7 @@ msgstr ""
"σε απώλεια των ανάλογων ψευδωνÏμων."
#
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1135,7 +1138,7 @@ msgstr ""
" "
#
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1202,7 +1205,7 @@ msgstr ""
"Μόνο για τους #Services operators#.\t\n"
" "
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1317,7 +1320,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1338,7 +1341,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1351,7 +1354,7 @@ msgstr ""
"μποÏοÏν να\n"
"δουν την λίστα access για κάθε ψευδώνυμο (#/msg %s ACCESS LIST #nick##)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1365,7 +1368,7 @@ msgstr ""
"εντολή αναγνώÏισης μέσω κωδικοÏ, μποÏοÏν να δοÏν την access, AKICK,\n"
"και τα level οποιουδήποτε καναλιοÏ."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1374,7 +1377,23 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, fuzzy, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+" \n"
+"Οι εντολές #QOP# πεÏιοÏίζονται στους\n"
+"ιδιοκτήτες (εκτώς αν το SECUREOPS είναι απενεÏγοποιημένο).\n"
+"ΠαÏόλα αυτά όλοι στην λίστα #QOP# μποÏοÏν να χÏησιμοποιήσουν την εντολή #QOP "
+"LIST#\n"
+" \n"
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1414,7 +1433,7 @@ msgstr ""
"Η εντολή #BADWORDS CLEAR# διαγÏάφει όλες τις καταχωÏήσεις της λίστας\n"
"των απαγοÏευμένων λέξεων."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1438,7 +1457,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1479,7 +1498,7 @@ msgstr ""
"Η εντολή #BADWORDS CLEAR# διαγÏάφει όλες τις καταχωÏήσεις της λίστας\n"
"των απαγοÏευμένων λέξεων."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1520,7 +1539,7 @@ msgstr ""
"Η εντολή #BADWORDS CLEAR# διαγÏάφει όλες τις καταχωÏήσεις της λίστας\n"
"των απαγοÏευμένων λέξεων."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1565,9 +1584,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"ΣÏνταξη: #SET #κανάλι# NOBOT {#ON|OFF#}#\n"
"\n"
@@ -1577,7 +1596,7 @@ msgstr ""
"\n"
"Μόνο για τους #Services Operators#."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1599,7 +1618,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1614,7 +1633,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr ""
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1628,7 +1647,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1641,7 +1660,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr "\"Jupiter\" έναν server"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1660,17 +1679,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%c δεν έχει κλειδωθεί στο %s."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Τα modes %c%c%s ξεκλειδώθηκαν από το %s"
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Όλες οι καταχωÏίσεις Ï€Ïόσβασης από το #%s# έχουν μεταφεÏθεί στο #%s#"
@@ -1695,8 +1714,8 @@ msgstr "%d ψευδώνυμα μέσα στο group."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, c-format
msgid "%s %s list is empty."
msgstr "Η %s %s λίστα είναι άδεια."
@@ -1789,9 +1808,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr " Κεφαλαία γÏάμματα με kick : %s (ελάχιστο %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "Η λίστα του %s access list είναι άδεια."
@@ -1801,7 +1820,7 @@ msgstr "Η λίστα του %s access list είναι άδεια."
msgid "%s added to %s's auto join list."
msgstr "Το #%s# Ï€Ïοσθέθηκε επιτυχώς στην autojoin λίστα σας."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "Το Bot #%s# υπάÏχει ήδη."
@@ -1812,7 +1831,7 @@ msgstr "Το Bot #%s# υπάÏχει ήδη."
msgid "%s autokick list is empty."
msgstr "H autokick list του %s είναι άδεια."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "Η λίοστα των κακών λέξεων του %s είναι άδεια."
@@ -1823,8 +1842,8 @@ msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr ""
"%s δεν μποÏεί να είναι successor στο κανάλι %s γιατί είναι founder σε αυτό."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Οι εντολές του %s είναι::"
@@ -1924,7 +1943,7 @@ msgstr "%s είναι ήση μέσα στο δίκτυο."
msgid "%s is a network service."
msgstr "%s είναι ήση μέσα στο δίκτυο."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "#%s# έχει ήδη καλυφθεί από τον %s."
@@ -1940,7 +1959,7 @@ msgstr "#%s# είναι ήδη στη λίστα αγνόησης σου"
msgid "%s is an unconfirmed nickname."
msgstr "Αυτό το ψευδώνυμο δεν είναι επιβεβαιωμένο."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1964,7 +1983,7 @@ msgstr "%s έχει απενεÏγοποιηθεί."
msgid "%s is enabled"
msgstr "%s έχει απενεÏγοποιηθεί."
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "#%s# δεν είναι σωστός Ï„Ïπος ban"
@@ -2009,7 +2028,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "Τα #%s# απενεÏγοποιήθηκαν στο κανάλι %s."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
@@ -2019,7 +2038,7 @@ msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
msgid "%s list is empty."
msgstr "Η %s %s λίστα είναι άδεια."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%c%c%s κλειδώθηκε στο %s"
@@ -2074,7 +2093,7 @@ msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr ""
"%s όταν θα κάνεις log on ή θα επανέÏχεσαι από away θα λαμβάνεις τα μηνÏματα."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) Ï€Ïοσθέθηκε στη λίστα του bot."
@@ -2130,12 +2149,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s ενεÏγοποιήθηκε."
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2202,7 +2221,7 @@ msgstr "Ο %s είναι για την ÏŽÏα off."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2215,13 +2234,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Ένα massmemo στάλθηκε σε όλους τους εγγεγÏαμμένους χÏήστες"
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2261,7 +2280,7 @@ msgstr "^_στόχος^_ ^_κωδικό^_"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr ""
@@ -2281,11 +2300,11 @@ msgstr "DEL #<nick>#."
msgid "ADD [nickname] [fingerprint]"
msgstr "Ρυθμίζει τον κωδικό του ψευδονÏμου."
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
msgid "ADD [+expiry] mask reason"
msgstr ""
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr ""
@@ -2293,15 +2312,15 @@ msgstr ""
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr ""
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2316,8 +2335,8 @@ msgstr ""
msgid "AKILL all users on a specific channel"
msgstr "Κάνει AKILL σε όλους τους χÏήστες σε ενα συγκεκÏιμένο κανάλι"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "Η λίστα AKILL είναι άδεια."
@@ -2350,17 +2369,17 @@ msgstr "Ο βαθμός Ï€Ïέπει να είναι Î¼ÎµÏ„Î±Î¾Ï %d και %d."
msgid "Access level must be non-zero."
msgstr "Η Access level δεν Ï€Ïέπει να είναι ποτέ στο μηδέν."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Ο βαθμός access για το κανάλι %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Ο βαθμός Access για το #%s# σβήστηκε στο αÏχικό."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
@@ -2374,23 +2393,15 @@ msgstr ""
"Η Ï€Ïόσβαση σε αυτή την εντολή χÏειάζεται την άδεια #%s# να υπάÏχει στο "
"opertype σας."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "ΕνεÏγοποίηση των στοιχείων ασφάλειας του %s."
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2414,7 +2425,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2451,13 +2462,7 @@ msgstr "Uplink server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2483,7 +2488,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Όλες οι O:lines του #%s# έχουν σβηστεί."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Όλες οι καταχωÏίσεις akick από το #%s# έχουν μεταφεÏθεί στο #%s#"
@@ -2493,16 +2498,11 @@ msgstr "Όλες οι καταχωÏίσεις akick από το #%s# έχουν
msgid "All available commands for %s:"
msgstr "Δεν υπάÏχει διαθέσιμη βοήθεια για #%s#."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Όλες οι καταχωÏίσεις badword από το #%s# έχουν μεταφεÏθεί στο #%s#"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Όλες οι καταχωÏίσεις akick από το #%s# έχουν μεταφεÏθεί στο #%s#"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Όλοι οι κανονισμοί ή οι πληÏοφοÏίες διαγÏάφηκαν."
@@ -2512,12 +2512,12 @@ msgstr "Όλοι οι κανονισμοί ή οι πληÏοφοÏίες δια
msgid "All memos for channel %s have been deleted."
msgstr "Όλα τα memos από το κανάλι %s έχουν διαγÏαφεί."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2540,7 +2540,7 @@ msgstr "Όλες οι O:lines του #%s# έχουν απομακÏυνθεί."
msgid "All random news items deleted."
msgstr "Όλα τα μηνÏματα διαγÏάφηκαν."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Όλες οι Ïυθμίσεις από το #%s# έχουν μεταφεÏθεί στο #%s#"
@@ -2552,12 +2552,12 @@ msgstr "Όλα τα memos από το κανάλι %s έχουν διαγÏαφÎ
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Όλες οι vhosts στο #%s# μεταφέÏθηκαν στο #%s#"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Όλες οι vhosts στο group #%s# έγιναν #%s#@#%s#"
#: src/access.cpp:41
@@ -2694,7 +2694,7 @@ msgstr ""
"δικτÏου. Το μήνυμα θα στέλνεται από το ψευδώνυμο υπηÏεσίας #%s#."
#
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2710,7 +2710,7 @@ msgstr ""
"Μόνο για τους #Services operators#."
#
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2723,7 +2723,7 @@ msgstr ""
" \n"
"Μόνο για τους #Services operators#."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2734,13 +2734,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2810,7 +2810,7 @@ msgstr ""
"Οι IRC Operators δεν γίνονται ignore."
#
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2885,7 +2885,7 @@ msgstr ""
"Μόνο για τους #Services operators#.\t\n"
" "
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2893,19 +2893,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2955,7 +2953,7 @@ msgstr ""
" \n"
"Μόνο για τους #Επικεφαλείς ΥπηÏεσιών#."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2963,12 +2961,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3003,7 +3000,7 @@ msgstr ""
"\n"
"Διαθέσιμες επιλογές:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3029,7 +3026,7 @@ msgstr ""
"χάνονται αν η Anope γίνει RESTART/SHUT DOWN/RELOADExample:\n"
" #CONFIG MODIFY nickserv forcemail no# \n"
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3042,7 +3039,7 @@ msgstr ""
"με το χÏήστη. Με τη παÏάμετÏο #MSG#, τα Services θα χÏησιμοποιοÏν μηνÏματα,\n"
"αλλιώς θα χÏησιμοποιοÏν notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3056,7 +3053,7 @@ msgstr ""
"χÏησιμοποιοÏν μηνÏματα, διαφοÏετικά θα χÏησιμοποιοÏν παÏατηÏήσεις \n"
"(notices). "
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
#, fuzzy
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
@@ -3145,14 +3142,14 @@ msgstr ""
"θα δεις πληÏοφοÏίες σχετικά με το bot.\n"
" "
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
#
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
msgid "Approve the requested vHost of a user"
msgstr "ΔιαγÏάφει τη vhost ενός χÏήστη."
@@ -3161,15 +3158,10 @@ msgstr "ΔιαγÏάφει τη vhost ενός χÏήστη."
msgid "As a Services Operator, you may drop any nick."
msgstr "%s είναι services operator Ï„Î¿Ï Ï„Ïπου %s."
-#
-#: modules/commands/bs_assign.cpp:19
-msgid "Assigns a bot to a channel"
-msgstr "Ζητάτε από το bot να έÏθει στο κανάλι σας"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3180,17 +3172,22 @@ msgstr ""
" "
#
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+msgid "Assigns a bot to a channel"
+msgstr "Ζητάτε από το bot να έÏθει στο κανάλι σας"
+
+#
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "Ζητάτε από το bot να έÏθει στο κανάλι σας"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
#
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr "Συσχετίζει ένα μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î¼Îµ το ψευδώνυμό σας"
@@ -3201,13 +3198,13 @@ msgid "Associate a greet message with your nickname"
msgstr "Συσχετίζει ένα μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î¼Îµ το ψευδώνυμό σας"
#
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr "Συσχετίζει μία διεÏθυνση e-mail με το ψευδώνυμό σας"
#
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Συσχετίζει μία διεÏθυνση e-mail με το ψευδώνυμό σας"
@@ -3218,11 +3215,11 @@ msgid "Associate oper info with a nick or channel"
msgstr "Ζητάτε από το bot να έÏθει στο κανάλι σας"
#
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Συσχετίζει μία διεÏθυνση e-mail με το ψευδώνυμό σας"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3235,7 +3232,7 @@ msgstr ""
"πληÏοφοÏίες\n"
"στο κανάλι με την εντολή #INFO#."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3264,18 +3261,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, c-format
msgid "Available commands for %s:"
msgstr ""
-#
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Λίστα με διαθέσιμα bots"
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3290,20 +3281,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr " Κακές λέξεις ώστε να κάνει kick : %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Η λίστα των κακών λέξεων είναι άδεια."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr " %s (δεν λήγει ποτέ)"
@@ -3323,7 +3314,7 @@ msgstr "Ban Ï„Ïπος του ÎºÎ±Î½Î±Î»Î¹Î¿Ï %s είναι τώÏα #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Κάνει ban ένα συγκεκÏιμένο ψευδόνυμο σε ένα κανάλι"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3352,7 +3343,7 @@ msgstr "%c δεν έχει κλειδωθεί στο %s."
msgid "Bolds kicker"
msgstr " Έντονη χαÏακτήÏες με kick : %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Το Bot #%s# υπάÏχει ήδη."
@@ -3367,12 +3358,12 @@ msgstr " %s (δεν λήγει ποτέ)"
msgid "Bot %s has been assigned to %s."
msgstr "Το Bot #%s# θα μπει στο %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot #%s# άλλαξε σε %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot #%s# διαγÏάφηκε."
@@ -3402,42 +3393,42 @@ msgstr "Το Bot #δεν θα κάνει kick τουε ops# του καναλιÎ
msgid "Bot won't kick voices on channel %s."
msgstr "Το Bot #δεν θα κάνει kick τους voices# του ÎºÎ±Î½Î±Î»Î¹Î¿Ï %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Κανένα Bot έχει επιλογή #ON# στο κανάλι %s."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "Bot #%s# διαγÏάφηκε."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα κανάλια."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Οι Hosts των Bots μποÏοÏν να πεÏιέχουν μόνο %d χαÏακτήÏες."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Οι hosts των bots μποÏοÏν να πεÏιέχουν μόνο έγκυÏους χαÏακτήÏες."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Οι idents των bots μποÏοÏν να πεÏιέχουν μόνο %d χαÏακτήÏες."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Οι Idents των bots μποÏοÏν να πεÏιέχουν μόνο έγκυÏους χαÏακτήÏες."
@@ -3455,12 +3446,12 @@ msgstr "Bot λίστα:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Οι idents των bots μποÏοÏν να πεÏιέχουν μόνο %d χαÏακτήÏες."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Τα ψευδόνυμα των bots μποÏοÏν να πεÏιέχουν μόνο έγκυÏους χαÏακτήÏες."
@@ -3555,8 +3546,8 @@ msgstr "Το Bot δεν θα κάνει kick #για επαναλήψεις# Ï€Î
msgid "Bot won't kick for repeats anymore."
msgstr "Το Bot δεν θα κάνει kick #για επαναλήψεις# πλέον."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3595,12 +3586,12 @@ msgstr ""
"να\n"
"μην έγινε."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Το Bot #θα κάνει kick τους ops# του ÎºÎ±Î½Î±Î»Î¹Î¿Ï %s."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr ""
"Δεν μποÏεί να σταλεί στη διεÏθυνση το μήνυμα για την ÏŽÏα; παÏακαλώ "
@@ -3699,22 +3690,22 @@ msgid "Change channel modes"
msgstr "Ο/η #%s# άλλαξε τα usermodes σας."
#
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Αλλάζει την μέθοδο επικοινωνίας με τις υπηÏεσίες"
#
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "Ο/η #%s# άλλαξε τα usermodes σας."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Τα usermodes του #%s# άλλαξαν."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3725,7 +3716,7 @@ msgstr ""
"Βλέπεις στη λίστα το ψευδώνυμο σου σε ποια ομάδα είναι των \n"
"υπηÏεσιών. Στη λίστα Ï€Ïέπει να είναι το ψευδώνυμο που είναι στην ομάδα."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3747,7 +3738,7 @@ msgstr ""
"κατοχυÏωμένο."
#
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3763,7 +3754,7 @@ msgstr ""
"υποστηÏιζόμενων γλωσσών:"
#
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3778,7 +3769,7 @@ msgstr ""
"Το #νοÏμεÏο# Ï€Ïέπει να είναι ένα από τα επόμενα που υπάÏχουν στην λίστα\n"
"υποστηÏιζόμενων γλωσσών:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
"ΣÏνταξη: #SET PASSWORD #νέος-κωδικός##\n"
@@ -3786,7 +3777,7 @@ msgstr ""
"Αλλάζει τον κωδικό που χÏησιμοποιείς για την εντολή αναγνώÏισης του κάτοχου\n"
"ψευδώνυμου."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3813,7 +3804,7 @@ msgstr ""
"αν δηλ έχει (%d), το κανάλι θα σβηστεί,σαν να μην είχε οÏιστεί\n"
"successor. Το νέο ψευδώνυμο θα Ï€Ïέπει να είναι κατοχυÏωμένο."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP #channel#"
@@ -3893,12 +3884,12 @@ msgstr "Το κανάλι %s #θα# λήξει."
msgid "Channel %s will not expire."
msgstr "Το κανάλι %s #δεν θα# λήξει."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Η λίστα του %s %s ÎºÎ±Î½Î±Î»Î¹Î¿Ï Î­Ï‡ÎµÎ¹ σβηστεί."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Η λίστα access του %s ÎºÎ±Î½Î±Î»Î¹Î¿Ï Î­Ï‡ÎµÎ¹ σβηστεί."
@@ -3908,7 +3899,7 @@ msgstr "Η λίστα access του %s ÎºÎ±Î½Î±Î»Î¹Î¿Ï Î­Ï‡ÎµÎ¹ σβηστεί.
msgid "Channel %s akick list has been cleared."
msgstr "Η λίστα akick του %s ÎºÎ±Î½Î±Î»Î¹Î¿Ï Î­Ï‡ÎµÎ¹ σβηστεί."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Το κανάλι %s δεν έχει πια mode locks."
@@ -3936,8 +3927,8 @@ msgstr ""
"Κανάλια στα οποία ο/η #%s# έχει access:\n"
" Num Channel Level Description "
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "Ο/η #%s# δεν βÏέθηκε στην access list του %s"
@@ -4007,7 +3998,7 @@ msgstr "Ελένχει αν το τελευταίο memo σε ένα ψευδόÎ
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Syntax: #CHECK #nick##\n"
"\n"
@@ -4118,7 +4109,7 @@ msgid "Configures reverses kicker"
msgstr "Ρυθμίζει τα kickers"
#
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "Αλλάζετε τις επιλογές του bot"
@@ -4136,7 +4127,7 @@ msgid "Confirm a passcode"
msgstr "Κάνει confirm με ένα κωδικό"
#
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
msgid "Control modes and mode locks on a channel"
msgstr "ΚαθαÏίζει τα modes από το κανάλι"
@@ -4145,12 +4136,12 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
#, fuzzy
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Syntax: #CLONE #channel# #target# [all | access | akick | badwords]#\n"
@@ -4160,40 +4151,40 @@ msgstr ""
"Ï€Ïόσβαση επιπέδου ιδÏητή και στα δÏο κανάλια."
#
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "ΑντιγÏάφει όλες τις Ïυθμίσεις από ένα κανάλι σε ένα άλλο."
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr " ΔημιουÏγήθηκε : %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr " ΔημιουÏγήθηκε : %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Η έως τώÏα AKILL λίστα είναι:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Η έως τώÏα AKILL λίστα είναι:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Η έως τώÏα λίστα Session Limit Exception είναι οι εξής:"
@@ -4249,12 +4240,12 @@ msgstr "Ρυθμίζει τον κωδικό του ψευδονÏμου."
msgid "DEL [nickname] mask"
msgstr "DEL #<nick>#."
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
msgid "DEL {mask | entry-num | list | id}"
msgstr ""
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
msgid "DEL {mask | entry-num | list}"
msgstr ""
@@ -4271,19 +4262,19 @@ msgstr ""
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} #server#"
@@ -4297,7 +4288,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4434,16 +4425,21 @@ msgid "Delete a memo or memos"
msgstr "ΔιαγÏάφει ένα ή πολλά μηνÏματα"
#
+#: modules/commands/hs_del.cpp:59
+msgid "Delete the vhost for all nicks in a group"
+msgstr "ΔιαγÏάφει τη vhost από όλα τα nicks σε ένα group"
+
+#
#: modules/commands/hs_del.cpp:19
msgid "Delete the vhost of another user"
msgstr "ΔιαγÏάφει τη vhost ενός χÏήστη."
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "ΔιαγÏάφηκαν %d θέσεις από την AOP λίστα του %s %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "ΔιαγÏάφηκαν %d θέσεις από %s access list."
@@ -4453,7 +4449,7 @@ msgstr "ΔιαγÏάφηκαν %d θέσεις από %s access list."
msgid "Deleted %d entries from %s autokick list."
msgstr "ΔιαγÏάφηκαν %d θέσεις από την autokick list %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "ΔιαγÏάφηκαν %d θέσεις από το %s ,τη λίστα των κακών λέξεων."
@@ -4473,7 +4469,7 @@ msgstr "ΔιαγÏάφηκαν %d θέσεις από την AOP λίστα το
msgid "Deleted %d entries from the AKILL list."
msgstr "ΔιαγÏάφηκαν %d θέσεις από την λίστα AKILL."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "ΔιαγÏάφει 1 θέση από %s access list."
@@ -4483,7 +4479,7 @@ msgstr "ΔιαγÏάφει 1 θέση από %s access list."
msgid "Deleted 1 entry from %s autokick list."
msgstr "ΔιαγÏάφτηκε 1 θέση από την autokick list %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "ΔιαγÏάφηκε 1 θέση από του %s λίστα κακών λέξεων."
@@ -4506,7 +4502,7 @@ msgstr "ΔιαγÏάφηκε 1 θέση από την λίστα AKILL."
msgid "Deleted info from %s."
msgstr "ΔιαγÏάφηκε 1 θέση από την λίστα AKILL."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "ΔιαγÏάφηκε 1 θέση από την AOP λίστα του %s %s."
@@ -4554,12 +4550,6 @@ msgstr ""
"ΔιαγÏάφει από την βάση δεδωμένων μια vhost από ένα Nick"
#
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr "ΔιαγÏάφει τη vhost από όλα τα nicks σε ένα group"
-
-#
#: modules/commands/hs_del.cpp:93
msgid ""
"Deletes the vhost for all nicks in the same group as\n"
@@ -4568,13 +4558,13 @@ msgstr ""
"Syntax: #DELALL# #<nick>#.\n"
"ΔιαγÏάφει όλες τις vhosts από το group του ονόματος που δώσατε."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "ΠεÏιγÏαφή του %s άλλαξε σε #%s#."
@@ -4589,7 +4579,7 @@ msgstr "ΠεÏιγÏαφή του %s άλλαξε σε #%s#."
msgid "Description of %s unset."
msgstr "ΠεÏιγÏαφή του %s άλλαξε σε #%s#."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
msgid "Disabled"
msgstr "%s ενεÏγοποιήθηκε."
@@ -4614,7 +4604,7 @@ msgstr ""
"Σε οÏισμένα δίκτυα μποÏεί να απαιτείται λόγος (reason) κατά τη χÏήση της "
"εντολής."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Εμφανίστηκαν όλα τα records (ΑÏιθμός: #%d#)"
@@ -4738,12 +4728,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "Η διεÏθυνση email για το #%s# άλλαξε σε #%s#."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "Η διεÏθυνση email για το #%s# διαγÏάφηκε."
@@ -4771,7 +4761,7 @@ msgstr ""
"(ΠαÏόλα αυτά, δεν θα του στέλνονται παÏαπάνω από #%d# μηνÏματα\n"
"για να αποφευχθεί το flood του χÏήστη. Αν υπάÏχουν\n"
"πεÏισσότεÏα μηνÏματα, θα φαίνονται τα πιο Ï€Ïόσφατα.)\n"
-"Το NewsCount μποÏεί να Ïυθμιστεί στο services.conf.\n"
+"Το NewsCount μποÏεί να Ïυθμιστεί στο anope.conf.\n"
"\n"
"Η εντολή LOGONNEWS μποÏεί να χÏησιμοποιηθεί μόνο από IRC Operators."
@@ -4794,7 +4784,7 @@ msgstr ""
"μηνÏματα\n"
"για να αποφευχθεί flood στον χÏήστη. Αν υπάÏχουν \n"
"πεÏισσότεÏα μηνÏματα, θα φαίνονται τα πιο Ï€Ïόσφατα.)\n"
-"Το NewsCount μποÏεί να Ïυθμιστεί στο services.conf.\n"
+"Το NewsCount μποÏεί να Ïυθμιστεί στο anope.conf.\n"
" \n"
"Το OPERNEWS μποÏεί να χÏησιμοποιηθεί μόνο από Services Operators."
@@ -4822,7 +4812,7 @@ msgstr " ΔιεÏθυνση E-mail: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Τα emails ταιÏιάζουν το #%s# στο #%s#."
#: modules/fantasy.cpp:19
@@ -4833,11 +4823,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
msgid "Enabled"
msgstr "%s ενεÏγοποιήθηκε."
@@ -4868,14 +4858,14 @@ msgstr ""
"θα υπενθυμίζεται από τον %s μετά τον τελευταίο χÏήστη που θα φÏγει από\n"
"το κανάλι, και θα αποθηκεÏεται για την επόμενη φοÏά."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4974,11 +4964,10 @@ msgstr ""
" "
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"ΣÏνταξη: #%s #κανάλι# SECUREOPS {ON | OFF}#\n"
"\n"
@@ -5021,7 +5010,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5042,22 +5031,22 @@ msgstr ""
"και το (απ)ενεÏγοποιήσετε για οποιδήποτε λόγο (ακόμη και με MLOCK\n"
"η ÏÏθμιση persist θα επιÏÏεαστεί αντίστοιχα.\n"
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Τελος της λίστας Ï€Ïοσβασης."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "Τελος της λίστας Ï€Ïοσβασης."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Τέλος της λίστας - %d/%d βÏέθηκαν και εμφανίστηκαν."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Τελος της λίστας Ï€Ïοσβασης."
@@ -5066,7 +5055,7 @@ msgstr "Τελος της λίστας Ï€Ïοσβασης."
msgid "End of autokick list"
msgstr "Τελος της λίστας Ï€Ïοσβασης."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Τέλος λίστας χÏηστών."
@@ -5097,7 +5086,7 @@ msgstr "Τέλος λίστας χÏηστών."
msgid "End of list - %d channels shown."
msgstr "Τέλος της λίστας - %d/%d βÏέθηκαν και εμφανίστηκαν."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Τέλος της λίστας - %d/%d βÏέθηκαν και εμφανίστηκαν."
@@ -5132,8 +5121,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Ελληνικά"
@@ -5188,17 +5177,16 @@ msgid ""
msgstr ""
#: modules/commands/ns_cert.cpp:325
-#, fuzzy
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
@@ -5216,32 +5204,37 @@ msgstr ""
" #CERT LIST#\n"
" Εμφανίζει την λίστα certificate."
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "Exception για #%s# (#%d) μετακινήθηκε στη θέση #%d#."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception για #%s# άλλαξε σε %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr "Λίγει στις: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Exception για #%s# άλλαξε σε %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Το χÏονικό ÏŒÏιο του/ης #%s# άλλαξε"
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Φαντασία"
@@ -5271,16 +5264,16 @@ msgstr "Η μάσκα #%s# είναι ήδη μέσα στην λίστα Ï€ÏÏŒ
msgid "Fingerprint %s is already in use."
msgstr "Είστε ήδη στο κανάλι #%s#! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Η vhost για τον #%s# έγινε #%s#."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
@@ -5373,7 +5366,7 @@ msgid "GETPASS command unavailable because encryption is in use."
msgstr ""
"Η GETPASS εντολή δεν είναι διαθέσιμη γιατί χÏησιμοποιείται η κωδικοποίηση."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Το ψευδώνυμο σου έγινε kill μέσω ghost εντολής."
@@ -5382,7 +5375,7 @@ msgstr "Το ψευδώνυμο σου έγινε kill μέσω ghost εντολ
msgid "Give Operflags to a certain user"
msgstr "Δίνει Ï€Ïόσβαση IRC Operator σε κάποιο χÏήστη"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -5390,7 +5383,7 @@ msgid ""
msgstr ""
#
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Σας δίνει Ï€Ïόσβαση διαχειÏιστή στο κανάλι"
@@ -5467,24 +5460,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Μην χÏησιμοποιείς reverses μέσα στο κανάλι!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "Το Bot #%s# υπάÏχει ήδη."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr " %s (δεν λήγει ποτέ)"
@@ -5494,8 +5483,8 @@ msgstr " %s (δεν λήγει ποτέ)"
msgid "Identify yourself with your password"
msgstr "Σας αναγνωÏίζει με τη χÏήση κωδικοÏ"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr ""
@@ -5511,11 +5500,11 @@ msgid "Ignore list is empty."
msgstr "Η λίστα ignore των υπηÏεσιών είναι άδεια."
#
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
msgid "Ignore list:"
msgstr "Bot λίστα:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "ΠÏοστασία στους Voices"
@@ -5571,7 +5560,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr "Μη έγγυÏο passcode"
@@ -5588,7 +5577,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Λάθος threshold value. ΠÏέπει να είναι μεγαλÏτεÏο από το 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5609,17 +5598,17 @@ msgstr " Πλάγια γÏάμματα kicker : %s"
msgid "Join a group"
msgstr " GROUP Μπένετε σε ομάδα ψευδώνυμου"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Επιλογή μηνÏματος"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Η Peace επιλογή για το %s #ΑΠΕÎΕΡΓΟΠΟΙΉΘΗΚΕ#."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Η Peace επιλογή για το %s #ΕÎΕΡΓΟΠΟΙΉΘΗΚΕ#."
@@ -5638,7 +5627,7 @@ msgstr "Key for channel #%s# is #%s#."
msgid "Kick a user from a channel"
msgstr "ΑπομακÏÏνει το χÏήστη από το κανάλι"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5649,13 +5638,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr "Κάνει kick ένα ψευδόνυμο από ένα κανάλι."
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"ΣÏνταξη: #KICK ##κανάλι# #ψευδώνυμο# [#λόγος#]#\n"
"\n"
@@ -5682,17 +5671,17 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
msgid "LIST [mask | list | id]"
msgstr ""
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr ""
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK #nickname#"
@@ -5701,15 +5690,10 @@ msgstr "CHECK #nickname#"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [#πεÏιεχόμενο#|#νοÏμεÏο#]#"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Η γλώσσα άλλαξε σε #Ελληνικά#."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Ο Successor του %s άλλαξε και πήγε στον #%s#."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5720,7 +5704,7 @@ msgstr "Το τελευταίο μήνυμα που πήγαινε για τον
msgid "Last quit message"
msgstr "Τελευταίο αποχαιÏετιστήÏιο μήνυμα: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr " Τελευταία φοÏά που ήταν στο δίκτυο: %s"
@@ -5730,11 +5714,11 @@ msgstr " Τελευταία φοÏά που ήταν στο δίκτυο: %s"
msgid "Last seen address"
msgstr "Τελευταία διεÏθυνση: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr " Τελευταία φοÏά που ήταν στο δίκτυο: %s"
@@ -5744,27 +5728,27 @@ msgstr " Τελευταία φοÏά που ήταν στο δίκτυο: %s"
msgid "Last usermask"
msgstr " Τελευταία φοÏά που ήταν στο δίκτυο: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Ο βαθμός για τον #%s# στο κανάλι %s άλλξε σε #%d#."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Το Level για %s στο κανάλι %s άλλαξε σε founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Ο βαθμός Ï€Ïέπει να είναι Î¼ÎµÏ„Î±Î¾Ï %d και %d."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5779,7 +5763,7 @@ msgstr "Εμφανίζει όλα τα κατωχηÏωμένα ψευδόνυμ
msgid "List channels you have access on"
msgstr "Εμφανίζει όλα τα κανάλια στα οποία έχετε Ï€Ïόσβαση."
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5789,7 +5773,7 @@ msgstr ""
msgid "List loaded modules"
msgstr "Εμφανίζει όλα τα φοÏτωμένα Modules."
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr ""
@@ -6037,19 +6021,18 @@ msgstr "Εμφανίζει όλα τα φοÏτωμένα Modules."
#
#: modules/commands/cs_info.cpp:19
-#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr "Εμφανίζει πληÏοφοÏίες για ένα κατωχυÏωμένο κανάλι"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"ΣÏνταξη: #INFO #κανάλι##\n"
"\n"
@@ -6147,7 +6130,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, fuzzy, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6201,11 +6188,11 @@ msgid "Maintain the AutoKick list"
msgstr "ΣυντηÏεί τη λίστα αυτόματης απόÏÏιψης"
#
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
msgid "Maintains network bot list"
msgstr "Αλλάζει την λίστα των bot του δικτÏου"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6213,7 +6200,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6231,7 +6218,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6243,7 +6230,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6296,7 +6283,7 @@ msgstr ""
"badword."
#
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr "Αλλάζετε την λίστα κακών λέξεων"
@@ -6307,10 +6294,9 @@ msgid "Makes the bot do the equivalent of a \"/me\" command"
msgstr "Κάνει το bot να εκτελέσει μια εντολή \"/me\" "
#: modules/commands/bs_control.cpp:127
-#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"ΣÏνταξη: #ACT #κανάλι# #μήνυμα##\n"
"\n"
@@ -6319,14 +6305,12 @@ msgstr ""
#
#: modules/commands/bs_control.cpp:19
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr "Κάνει το bot να πεί ένα κείμενο σε ένα κανάλι"
#
#: modules/commands/bs_control.cpp:69
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr "Κάνει το bot να πεί ένα κείμενο σε ένα κανάλι"
#: modules/commands/greet.cpp:157
@@ -6359,7 +6343,7 @@ msgstr ""
"η επιλογή GREET θα είναι ενεÏγοποιημένη, και με την Ï€Ïουπόθεση οτι θα έχεις\n"
"και την κατάλληλη access σε αυτό. "
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr ""
@@ -6382,13 +6366,13 @@ msgid "Manage your auto join list"
msgstr "ΣυντηÏεί τη λίστα αυτόματης εισόδου"
#
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr "ΠÏοσθέτει ip κλπ στην λίστα AKILL"
#
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "ΠÏοσθέτει ip κλπ στην λίστα AKILL"
@@ -6398,19 +6382,19 @@ msgid "Manipulate the DefCon system"
msgstr "ΔιαχειÏίζεται το σÏστημα DefCon"
#
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
msgid "Manipulate the topic of the specified channel"
msgstr "Αλλάζει το topic σε ένα κανάλι."
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6423,8 +6407,8 @@ msgstr "Η μάσκα #%s# είναι ήδη μέσα στην λίστα Ï€ÏÏŒ
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "Η μάσκα #%s# είναι ήδη μέσα στην λίστα Ï€Ïόσβασης."
@@ -6455,7 +6439,7 @@ msgid "Memo %d has been deleted."
msgstr "Μήνυμα %d διαγÏάφηκε."
#
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Η λίστα σας ανεπιθÏμητων memo είναι άδεια."
@@ -6475,7 +6459,7 @@ msgstr "Το ÏŒÏιο μηνυμάτων για τον %s άλλαξε σε #%d#
msgid "Memo limit for %s set to 0."
msgstr "Το ÏŒÏιο μηνυμάτων για τον %s άλλαξε σε #0#."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Το μήνυμα στάλθηκε στον #%s#."
@@ -6490,7 +6474,7 @@ msgstr " Επιλογές κλειδώματος: %s"
msgid "Message"
msgstr "Επιλογή μηνÏματος"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Επιλογή μηνÏματος"
@@ -6498,26 +6482,26 @@ msgstr "Επιλογή μηνÏματος"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Ο/η #%s# δεν βÏέθηκε στη λίστα αγνόησης σου."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr " Επιλογές κλειδώματος: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, c-format
msgid "Mode locks for %s:"
msgstr " Επιλογές κλειδώματος: %s"
@@ -6526,11 +6510,6 @@ msgstr " Επιλογές κλειδώματος: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6582,7 +6561,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6594,7 +6573,7 @@ msgid "Modify the Services ignore list"
msgstr "ΤÏοποποιεί την Services Ignore List"
#
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr "Αλλάζει την λίστα των AOP χÏηστών"
@@ -6605,7 +6584,7 @@ msgid "Modify the list of authorized addresses"
msgstr "Αλλάζει τη λίστα των εξουσιοδοτημένων διευθÏνσεων"
#
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
msgid "Modify the list of privileged users"
msgstr "Αλλάζει τη λίστα των εξουσιοδοτημένων χÏηστών"
@@ -6616,7 +6595,7 @@ msgid "Modify the nickname client certificate list"
msgstr "ΤÏοποποιεί την Services Ignore List"
#
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
msgid "Modify the session-limit exception list"
msgstr "Αλλάζεις την λίστα του session-limit exception"
@@ -6664,14 +6643,14 @@ msgstr "Module: #%s# Έκδωση: #%s# ΣυγγÏαφέας: #%s# φοÏτώθÎ
msgid "Module: %s [%s] [%s]"
msgstr "Module: #%s# [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6684,18 +6663,18 @@ msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
msgid "Nick"
msgstr ""
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, c-format
msgid "Nick %s has been confirmed."
msgstr "Το ψευδώνυμο #%s# σβήστηκε επιτυχώς από την υπηÏεσία."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, c-format
msgid "Nick %s is already an operator."
msgstr "Το κανάλι #%s# είναι ήδη κατοχυÏωμένο!"
@@ -6710,7 +6689,6 @@ msgstr "Αυτό το ψευδώνυμο #%s# είναι ήδη κατοχυÏω
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Το Nick #%s# είναι παÏάνομο και δεν μποÏεί να χÏησιμοποιηθεί."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6726,7 +6704,7 @@ msgstr "Το Nick #%s# δεν χÏησιμοποιείται αυτή τη στÎ
msgid "Nick %s is forbidden."
msgstr "Το ψευδώνυμο #%s# δεν κÏατείται.."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s είναι services operator Ï„Î¿Ï Ï„Ïπου %s."
@@ -6751,12 +6729,12 @@ msgstr "Το Nickname %s κατωχυÏώθηκε."
msgid "Nick %s was truncated to %d characters."
msgstr "Το Nick #%s# πεÏικόπηκε σε %d χαÏακτήÏες."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Το Nick %s #θα# λήξει."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Το Nick %s #δεν θα# λήξει."
@@ -6821,17 +6799,17 @@ msgstr "Το κανάλι #%s# είναι ήδη κατοχυÏωμένο!"
msgid "Nickname %s may not be registered."
msgstr "Το κανάλι #%s# δεν μποÏεί να κατοχυÏωθεί."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Αυτό το ψευδώνυμο #%s# κατοχυÏώθηκε υπό την διεÏθυνσή σου: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, c-format
msgid "Nickname %s registered."
msgstr "Το κανάλι #%s# δεν μποÏεί να κατοχυÏωθεί."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6841,7 +6819,7 @@ msgid "No bot"
msgstr "Κανένα bot"
#
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
msgid "No expire"
msgstr "δεν λήγει ποτέ"
@@ -6869,13 +6847,13 @@ msgstr "Κανένας Κανονισμός ή πληÏοφοÏία για να
msgid "No matches for %s found."
msgstr "Δεν υπάÏχει κανένα email για το #%s#."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, c-format
msgid "No matching entries on %s %s list."
msgstr "Δεν βÏέθηκαν θέσεις στην AOP λίστα του %s %s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Δεν βÏέθηκαν θέσεις στου %s στην access list."
@@ -6885,21 +6863,21 @@ msgstr "Δεν βÏέθηκαν θέσεις στου %s στην access list."
msgid "No matching entries on %s autokick list."
msgstr "Δεν βÏέθηκαν θέσεις στην autokick list του %s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Δεν βÏέθηκαν οι θέσεις στην λίστα των κακών λέξεων του %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "Δεν βÏέθηκαν θέσεις στην λίστα session-limit exception."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Δεν βÏέθηκαν θέσεις στην AOP λίστα του %s %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Δεν βÏέθηκαν θέσεις στην λίστα AKILL."
@@ -6912,7 +6890,12 @@ msgstr "Κανένα μήνυμα δεν ακυÏώθηκε."
msgid "No modules currently loaded matching that criteria."
msgstr "Κανένα module δεν είναι φοÏτωμένο"
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Δεν επιτÏέπονται οι κατοχυÏώσεις ψευδονÏμου."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6932,12 +6915,7 @@ msgstr "Δεν βÏέθηκαν μηνÏματα για να διαγÏαφοÏÎ
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Δεν επιτÏέπονται οι κατοχυÏώσεις ψευδονÏμου."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6946,8 +6924,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
@@ -6957,7 +6935,7 @@ msgstr "Λίστα Ï€Ïόσβασης για #%s#:"
msgid "No such info \"%s\" on %s."
msgstr "Ο/η #%s# Ï€Ïοσκαλέσθηκε στο κανλάλι #%s#."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Τα usermodes του #%s# άλλαξαν."
@@ -6972,7 +6950,7 @@ msgstr "Κανένα Bot έχει επιλογή #ON# στο κανάλι %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Κανένα Bot έχει επιλογή #ON# στο κανάλι %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6981,21 +6959,21 @@ msgstr ""
msgid "None"
msgstr "Κανένα"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -7003,18 +6981,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [#πεÏιεχόμενο#|#νοÏμεÏο#]#\t"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Οι παλιές πληÏοφοÏίες είναι ίδιες με τις καινοÏÏγιες."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Είναι συνδεδεμένος από: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7038,12 +7013,12 @@ msgstr "Η θέση #%s στην λίστα δεν βÏέθηκε!"
msgid "Oper news items:"
msgstr "Îέα των Opers:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, c-format
msgid "Oper type %s has not been configured."
msgstr "Το ψευδώνυμο #%s# σβήστηκε επιτυχώς από την υπηÏεσία."
@@ -7058,17 +7033,17 @@ msgstr "μια O:Line με τα flags #%s# Ï€Ïοστέθηκε για τον #%
msgid "Operflags %s have been removed from %s."
msgstr "μια O:Line με τα flags #%s# Ï€Ïοστέθηκε για τον #%s#."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7082,12 +7057,12 @@ msgstr "ΠÏοστασία στους Ops"
msgid "Options"
msgstr " Επιλογές : %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} #server#"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7104,12 +7079,12 @@ msgstr "Λάθος κωδικός."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, c-format
msgid "Password for %s changed to %s."
msgstr "Ο Successor του %s άλλαξε και πήγε στον #%s#."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "Ο κωδικός για τον %s είναι #%s#."
@@ -7129,7 +7104,7 @@ msgstr "Λάθος κωδικός."
msgid "Password reset email for %s has been sent."
msgstr "Αλλαγή ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î³Î¹Î± το ψευδόνυμο #%s# στάλθηκε."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "ΕιÏηνικό"
@@ -7143,7 +7118,7 @@ msgstr "Η Peace επιλογή για το %s #ΑΠΕÎΕΡΓΟΠΟΙΉΘΗΚÎ
msgid "Peace option for %s is now on."
msgstr "Η Peace επιλογή για το %s #ΕÎΕΡΓΟΠΟΙΉΘΗΚΕ#."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7174,13 +7149,13 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "ΠαÏακαλώ πεÏίμενε #%d# δευτεÏόλεπτα και ξαναπÏοσπάθησε."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr ""
"ΠαÏακαλώ πεÏίμενε %d δευτεÏόλεπτα Ï€Ïιν χÏησιμοποιήσεις την εντολή SEND ξανά."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr ""
@@ -7193,14 +7168,14 @@ msgstr ""
"ΠαÏακαλώ πεÏίμενε %d δευτεÏόλεπτα και μετά ξαναχÏησιμοποίησε την εντολή "
"ομαδοποίησης."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"ΠαÏακαλώ πεÏίμενε %d δευτεÏόλεπτα και μετά ξαναχÏησιμοποίησε την εντολή "
"κατοχÏÏωσης ξανά."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7213,7 +7188,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7243,7 +7218,7 @@ msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Κάντε ένα nick να μή φαίνεται στην εντολή #/msg %s LIST#"
#
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
msgid "Prevent the nickname from expiring"
msgstr "Κάντε ένα nickname να μη λήγει ποτέ."
@@ -7251,17 +7226,17 @@ msgstr "Κάντε ένα nickname να μη λήγει ποτέ."
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Μυστικότητα"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, c-format
msgid "Private mode of bot %s is now off."
msgstr "Μυστικότητα επιλογής του bot %s είναι τώÏα #ON#."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, c-format
msgid "Private mode of bot %s is now on."
msgstr "Μυστικότητα επιλογής του bot %s είναι τώÏα #ON#."
@@ -7286,37 +7261,37 @@ msgstr "Η Private επιλογή #απενεÏγοποιηθηκε# για το
msgid "Private option is now on for %s."
msgstr "Η Private επιλογή #ενεÏγοποιηθηκε# για τον #%s#."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "ΠÏοστασία"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, c-format
msgid "Protection is now off for %s."
msgstr "Η Ï€Ïοστασία #απενεÏγοποιήθηκε# για το #%s#."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr ""
"Η Ï€Ïοστασία #ενεÏγοποιήθηκε# για το #%s#. , με μια μειωμένη καθυστέÏηση"
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Η Ï€Ïοστασία #ενεÏγοποιήθηκε# για το #%s#. ,με καθόλου καθυστέÏηση"
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, c-format
msgid "Protection is now on for %s."
msgstr "Η Ï€Ïοστασία #ενεÏγοποιήθηκε# για το #%s#."
@@ -7333,7 +7308,7 @@ msgstr ""
"uses the entire and complete real ident@host for every nick,\n"
"then enforces the AKILL. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "ΠÏοστασία στους Voices"
@@ -7378,20 +7353,20 @@ msgstr "Διαβάζει ένα ή πολλά μηνÏματα"
msgid "Real name"
msgstr " ΠÏαγματικό όνομα : %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "Ο Successor του #%s# δεν έχει οÏιστεί."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7402,33 +7377,33 @@ msgid ""
msgstr ""
#
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
msgid "Redefine the meanings of access levels"
msgstr "ΕπανακαθοÏίζει το νόημα των επιπέδων Ï€Ïόσβασης"
#
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr "Ανάκτηση της κατακÏάτησης του ψευδωνÏμου,μετά από RECOVER"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s έχει απενεÏγοποιηθεί."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7441,11 +7416,11 @@ msgid "Register a channel"
msgstr "ΚατοχυÏώνει ένα ψευδώνυμο"
#
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
msgid "Register a nickname"
msgstr "ΚατοχυÏώνει ένα ψευδώνυμο"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr " Κατάσταση κατοχÏÏωσης με την ημεÏομηνία: %s"
@@ -7502,7 +7477,7 @@ msgstr ""
"να έχετε Ï€Ïώτα κατωχυÏωμένο ψευδόνυμο. Αν δεν έχετε,\n"
"#/msg %s HELP# για πληÏοφοÏίες."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7554,7 +7529,7 @@ msgstr ""
"δικαιωμάτων στα κανάλια. Για πεÏισσότεÏες πληÏοφοÏίες για αυτή \n"
"τη μελλοντική εντολή, γÏάψε #/msg %s HELP GROUP#.\n"
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Συγνώμη, η υπηÏεσία κατοχÏÏωσεις καναλιών δεν λειτουÏγεί για την ÏŽÏα."
@@ -7565,12 +7540,12 @@ msgid "Regulate the use of critical commands"
msgstr "Îα ελλατώνει την χÏήση \"βίαιων\" εντολών"
#
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
msgid "Reject the requested vHost for the given nick."
msgstr "ΕπιστÏέφει τον ιδιοκτήτη του εν λόγω καναλιοÏ."
#
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
msgid "Reject the requested vHost of a user"
msgstr "ΔιαγÏάφει τη vhost ενός χÏήστη."
@@ -7616,22 +7591,22 @@ msgstr "ΑφαιÏεί όλα τα bans που εμποδίζουν έναν χÏ
msgid "Remove all operators from a server remotely"
msgstr "ΑφαιÏεί Ï€ÏοσωÏινά και εξ αποστάσεως όλες τις O:lines από τον server"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr " Επιλογές κλειδώματος: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7639,25 +7614,25 @@ msgid ""
msgstr ""
#
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Κάνει έναν χÏήστη διαχειÏιστή ÎºÎ±Î½Î±Î»Î¹Î¿Ï "
#
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr "Κάνει kick ένα ψευδόνυμο από ένα κανάλι."
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7672,15 +7647,15 @@ msgstr " Επανάληψη με kick : %s"
msgid "Request a vHost for your nick"
msgstr "Δεν υπάÏχει email που να συνδέεται με το nick σας."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
#
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr "ΞαναφοÏτώνει το services' configuration αÏχείο"
@@ -7690,7 +7665,7 @@ msgstr "ΞαναφοÏτώνει το services' configuration αÏχείο"
msgid "Restrict access to the channel"
msgstr "ΑπαγόÏευση εισόδου στο κανάλι αν δεν έχεις access εκεί"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Μόνο όσοι έχουν Access"
@@ -7728,7 +7703,7 @@ msgstr ""
"Εμφανίζει τον κωδικό για το συγκεκÏιμένο ψευδώνυμο\n"
"(μόνο αν η κωδικοποίηση είναι ανενεÏγή)"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7742,11 +7717,21 @@ msgstr "ΕπιστÏέφει το κλειδί για το εν λόγω κανÎ
msgid "Returns the key of the given channel."
msgstr "ΕπιστÏέφει το κλειδί για το εν λόγω κανάλι."
-#
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr "ΕπιστÏέφει το κλειδί για το εν λόγω κανάλι."
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Syntax: #GETEMAIL #user@emailhost##\n"
+"Εμφανίζει τη λίστα με τα ψευδόνυμα που χÏησιμοποιοÏν ένα email. #ΠÏοσοχή#:\n"
+"Δεν μποÏείτε να χÏησιμοποιείσετε wildcards για το nick ή το emailhost. "
+"Όποτε\n"
+"χÏησιμοποιείται αυτή η εντολή, ένα μήνυμα με το όνομα του ατόμου που τη "
+"χÏησιμοποίησε\n"
+"και το email που έψαξε, θα καταγÏάφεται."
#
#: modules/commands/ns_status.cpp:19
@@ -7832,18 +7817,18 @@ msgstr "ΑντιστÏέφει την εντολή IDENTIFY."
msgid "SET server"
msgstr ""
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
#
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Ο κωδικός έγινε δεκτός - τώÏα είσαι αναγνωÏισμένος."
#
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Ο κωδικός έγινε δεκτός - τώÏα είσαι αναγνωÏισμένος."
@@ -7866,7 +7851,7 @@ msgstr "Σώζει τις βάσεις δεδομένων και επανεκκÎ
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Ασφάλεια στον ΚαναλάÏχη"
@@ -7881,7 +7866,7 @@ msgstr "H Secure founder επιλογή για το %s #ΑΠΕÎΕΡΓΟΠΟΙΗ
msgid "Secure founder option for %s is now on."
msgstr "H Secure founder επιλογή για το %s #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ#."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Μόνο αυτοί που έχουν access θα παίÏνουν op από opers"
@@ -7906,12 +7891,12 @@ msgstr "H Secure option επιλογή για το %s #ΑΠΕÎΕΡΓΟΠΟΙΗÎ
msgid "Secure option for %s is now on."
msgstr "H Secure option επιλογή για το %s #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ#."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, c-format
msgid "Secure option is now off for %s."
msgstr "Η επιλογή Secure option #ΑΠΕÎΕΡΓΟΠΟΙΗΘΗΚΕ# για τον #%s#."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, c-format
msgid "Secure option is now on for %s."
msgstr "Η επιλογή Secure option #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ# για τον #%s#."
@@ -7921,18 +7906,18 @@ msgstr "Η επιλογή Secure option #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ# για Ï„
msgid "Secureops enforced on %s."
msgstr "Η επιλογή Secure option #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ# για τον #%s#."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Ασφάλεια"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
"about the access list."
msgstr "’γνωστη εντολή #%s#. \"/msg %s HELP\" για βοήθεια."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7996,7 +7981,7 @@ msgstr ""
"Στέλνει σε όλο το services staff ένα memo που πεÏιέχει #memo-text#."
#
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
msgid ""
"Sends the named nick or channel a memo containing\n"
"memo-text. When sending to a nickname, the recipient will\n"
@@ -8069,14 +8054,14 @@ msgid "Server %s already exists."
msgstr "Το Bot #%s# υπάÏχει ήδη."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, c-format
msgid "Server %s does not exist."
msgstr " %s (δεν λήγει ποτέ)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "Το ψευδώνυμο #%s# σβήστηκε επιτυχώς από την υπηÏεσία."
@@ -8086,12 +8071,12 @@ msgstr "Το ψευδώνυμο #%s# σβήστηκε επιτυχώς από τ
msgid "Server %s is already in zone %s."
msgstr "Είστε ήδη στο κανάλι #%s#! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Το Module #%s# είναι ήδη φοÏτωμένο."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "Ο %s είναι για την ÏŽÏα off."
@@ -8106,12 +8091,12 @@ msgstr " %s (δεν λήγει ποτέ)"
msgid "Server %s is not linked to the network."
msgstr "Δεν υπάÏχει bot που να είναι στο %s τώÏα πια."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (δεν λήγει ποτέ)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8131,19 +8116,18 @@ msgstr "Î’Ïέθηκαν οι servers: %d"
msgid "Service"
msgstr "Τα services είναι ενεÏγά για %s"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Οι υπηÏεσίες απελευθέÏωααν το ψευδώνυμό σου."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s είναι services operator Ï„Î¿Ï Ï„Ïπου %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr "Τα services είναι σε Defcon mode, ΠαÏακαλώ δοκιμάστε αÏγότεÏα"
@@ -8199,7 +8183,7 @@ msgid "Services ignore list:"
msgstr "ΤÏοποποιεί την Services Ignore List"
#
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
"correctly?"
@@ -8212,7 +8196,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Τα services είναι ενεÏγά για %s"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα κανάλια."
@@ -8222,7 +8206,7 @@ msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα κανάλια."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα κανάλια."
@@ -8232,12 +8216,12 @@ msgstr "Τα services δεν θα δίνουν πια autoop στον %s στα
msgid "Services will now automatically give modes to users in %s."
msgstr "Τα services θα δίνουν autoop στον %s στα κανάλια."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Τα services δεν θα απαντοÏν πια στον #%s# με #μυνήματα#."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Τα services θα απαντοÏν πια στον #%s# με #notices#."
@@ -8256,7 +8240,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Session limit για τον #%s# Ïυθμίστηκε σε #%d#."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Η Session limiting εντολή είναι απενεÏγοποιημένη."
@@ -8301,7 +8285,7 @@ msgid "Set the channel description"
msgstr "Αλλάζει την πεÏιγÏαφή του καναλιοÏ"
#
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
msgid "Set the display of your group in Services"
msgstr "Αλλάζει την λίστα των ομάδων"
@@ -8311,14 +8295,14 @@ msgid "Set the founder of a channel"
msgstr "Αλλάζει τον founder του καναλιοÏ"
#
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
msgid "Set the language Services will use when messaging you"
msgstr ""
"Αλλάζει τη γλώσσα που χÏησιμοποιοÏν οι\n"
" υπηÏεσίες όταν τις χÏησιμοποιείτε"
#
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
msgid "Set the nickname password"
msgstr "Ρυθμίζει τον κωδικό του ψευδονÏμου."
@@ -8684,7 +8668,7 @@ msgstr ""
"\n"
"Αλλάζει διάφοÏες επιλογές του ψευδωνÏμου. Η #επιλογή# μποÏεί να είναι:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8703,7 +8687,7 @@ msgstr ""
"Μόνο οι #Services Operators# μποÏοÏν να το κάνουν."
#
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8718,7 +8702,7 @@ msgstr ""
"Με επιλογή #ON# ο ChanServ θα δίνει Op στον χÏήστη \n"
"αυτόματα όταν μπαίνει στα κανάλια."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8728,7 +8712,7 @@ msgstr ""
"Ρυθμίζει αν ένα ψευδόνυμο θα λήγει. Με τη παÏάμετÏο\n"
"#ON# το nickname δεν θα λήγει."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8741,7 +8725,7 @@ msgstr ""
"Ελένχει αν θα γίνεστε OP αυτόματα. Πατήστε ON για να \n"
"επιτÏέψετε στον ChanServ να σας δίνει αυτόματο op στα κανάλια."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8815,11 +8799,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Η επιλογή Signed kick για το %s #ΕÎΕΡΓΟΠΟΙΗΘΗΚΕ#."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Δηλωμένα kicks"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s έχεις πολλά μηνÏματα και δεν μποÏείς να λάβεις άλλα."
@@ -8829,45 +8813,39 @@ msgstr "%s έχεις πολλά μηνÏματα και δεν μποÏείς Î
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Συγνώμη, η υπηÏεσία bad words είναι απενεÏγοποιημένη."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Συγνώμη, η υπηÏεσία bot είναι απενεÏγοποιημένη."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Συγνώμη, η υπηÏεσία για το bot είναι απενεÏγοποιημένη."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Συγνώμη, η εντολή setting είναι απενεÏγοποιημένη."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Συγνώμη, η εντολή setting είναι απενεÏγοποιημένη."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Συγνώμη, η υπηÏεσία για την εντολή AOP του ÎºÎ±Î½Î±Î»Î¹Î¿Ï %s είναι εκτός "
"λειτουÏγίας."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Συγνώμη, η υπηÏεσία για την εντολή access είναι εκτός λειτουÏγίας."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Συγνώμη, η υπηÏεσία για την εντολή akick είναι εκτός λειτουÏγίας."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Συγνώμη, η υπηÏεσία bad words είναι απενεÏγοποιημένη."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Συγνώμη, η υπηÏεσία διαγÏαφής καναλιών είναι απενεÏγοποιημένη."
@@ -8898,7 +8876,7 @@ msgid "Sorry, nickname grouping is temporarily disabled."
msgstr ""
"Συγνώμη, η ομαδοποίηση του ÏˆÎµÏ…Î´ÏŽÎ½Ï…Î¼Î¿Ï ÏƒÎ¿Ï… είναι για την ÏŽÏα απενεÏγοποιημένη."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Συγνώμη, η κατοχÏÏωση ψευδώνυμου είναι για την ÏŽÏα απενεÏγοποιημένη."
@@ -8917,13 +8895,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Συγνώμη, μποÏείς μόνο να έχεις %d Ï€Ïόσβαση σε κατάταξη του ψευδώνυμου."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Το μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î³Î¹Î± τον #%s# αφεÏέθηκε."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8935,7 +8908,7 @@ msgstr "Συγνώμη, μποÏείς μόνο να έχεις %d access στο
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Συγνώμη, μποÏείς μόνο να έχεις %d autokick μάσκα στο κανάλι."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, fuzzy, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Συγνώμη, μποÏείς μόνο να έχεις %d %s access στο κανάλι."
@@ -9002,7 +8975,7 @@ msgstr "Ο Successor του #%s# δεν έχει οÏιστεί."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "H ÏÏθμιση SuperAdmin δεν έχει ενεÏγοποιηθεί στο services.conf"
+msgstr "H ÏÏθμιση SuperAdmin δεν έχει ενεÏγοποιηθεί στο anope.conf"
#
#: modules/commands/ns_suspend.cpp:60
@@ -9226,7 +9199,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9300,7 +9273,7 @@ msgstr ""
"Αυτή η επιλογή δεν είναι μόνιμη και Ï€Ïέπει να χÏησιμοποιείται μόνο\n"
"όταν χÏειάζεται, και να γίνεται OFF όταν δεν χÏειάζεται."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9323,7 +9296,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"ΣÏνταξη: #INVITE #κανάλι##\n"
@@ -9342,7 +9315,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"ΣÏνταξη: #UNBAN #κανάλι# [#nick#]#\n"
@@ -9397,7 +9370,7 @@ msgstr "ΤεÏματίζει τα Services αποθηκεÏοντας τις αÎ
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9408,7 +9381,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9417,7 +9390,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9451,10 +9424,10 @@ msgstr ""
"Η εντολή #BADWORDS CLEAR# διαγÏάφει όλες τις καταχωÏήσεις της λίστας\n"
"των απαγοÏευμένων λέξεων."
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9462,15 +9435,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
-#, fuzzy
+#: modules/commands/bs_badwords.cpp:437
msgid ""
"The DEL command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
@@ -9484,7 +9456,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Η εντολή #BADWORDS DEL# αφαιÏεί τη δοσμένη λέξη από τη λίστα των\n"
@@ -9508,36 +9480,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "Η #IMMED# επιλογή δεν είναι διαθέσιμη σε αυτό το δίκτυο."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9588,7 +9560,7 @@ msgstr ""
"Για μια λίστα από λειτουÏγίες των οποίων το access level μποÏείτε να "
"Ï„Ïοποποιήσετε, βλ: HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9599,18 +9571,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9618,7 +9590,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9634,7 +9606,6 @@ msgstr ""
"κανένα Ï„Ïίτο Ï€Ïόσωπο."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9652,7 +9623,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9662,12 +9633,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Το μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î³Î¹Î± τον #%s# αφεÏέθηκε."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "Η λίστα AKILL καθαÏίστηκε."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "Η λίστα AKILL καθαÏίστηκε."
@@ -9686,7 +9657,7 @@ msgstr "Το email του #%s# δεν θα φαίνεται τώÏα στο %s I
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "Το email του #%s# θα φαίνεται τώÏα στο %s INFO."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9716,11 +9687,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Το μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î³Î¹Î± τον #%s# αφεÏέθηκε."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9780,12 +9751,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "Το ÏŒÏιο των μηνυμάτων για τον %s δεν μποÏεί να αλλαχτεί."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Το μήνυμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï Î³Î¹Î± τον #%s# αφεÏέθηκε."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9800,10 +9766,6 @@ msgstr "Το defcon επίπεδο είναι τώÏα: #%d#"
msgid "The nick %s is now being changed to %s."
msgstr "Tο nick #%s# άλλαξε σε #%s#."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9827,12 +9789,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr "Το επίπεδο Ï€Ïόσβασης του #%s# στα Services θα φαίνεται στο %s INFO."
#
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr "Αλλάζεις την λίστα του session-limit exception"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9907,7 +9869,7 @@ msgstr "Δεν υπάÏχουν νέα."
msgid "There is no such configuration block %s."
msgstr "Λάθος στην επαναφόÏτηση του αÏχείου configuration"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Δεν υπάÏχουν νέα για τους opers."
@@ -9934,7 +9896,7 @@ msgstr "Αυτό το κανάλι δεν μποÏεί να χÏησιμοποι
msgid "This channel may not be used."
msgstr "Αυτό το κανάλι δεν μποÏεί να χÏησιμοποιηθεί."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9967,7 +9929,7 @@ msgstr ""
"Αυτή η εντολή επιτÏέπει στους χÏήστες να οÏίσουν τη vhost\n"
"του nick που χÏησιμοποιοÏν, ÏŽÏ‚ vhost για όλα τα nicks στο group τους."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9981,7 +9943,7 @@ msgid "This command is an alias to the command %s."
msgstr ""
#
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
msgid ""
"This command is used by several commands as a way to confirm\n"
"changes made to your account.\n"
@@ -10013,8 +9975,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10112,7 +10074,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10126,7 +10088,7 @@ msgstr ""
"Syntax: #MODLOAD# #FileName#\n"
"Αυτή η εντολή φοÏτώνει ένα module από τη λίστα των modules."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10181,7 +10143,7 @@ msgstr ""
"Syntax: #MODLOAD# #FileName#\n"
"Αυτή η εντολή φοÏτώνει ένα module από τη λίστα των modules."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10197,12 +10159,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Αυτό το κανάλι έχει κατοχυÏωθεί με τον %s."
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "Αυτό το κανάλι έχει κατοχυÏωθεί με τον %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10262,7 +10224,7 @@ msgstr ""
msgid "Topic"
msgstr "Κλείδωμα του Topic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Κλείδωμα του Topic"
@@ -10277,7 +10239,7 @@ msgstr "Topic lock επιλογή για το %s είναι τώÏα #off#."
msgid "Topic lock option for %s is now on."
msgstr "Topic lock επιλογή για το %s είναι τώÏα #ON#."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Topic ενναλαγής"
@@ -10292,7 +10254,7 @@ msgstr "Η διατήÏηση του topic για το %s είναι τώÏα #O
msgid "Topic retention option for %s is now on."
msgstr "Η διατήÏηση του topic για το %s είναι τώÏα #ON#."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10301,18 +10263,19 @@ msgid "Turn caps lock OFF!"
msgstr "Μην γÏάφεις με κεφαλαία γÏάμματα!"
#
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr "ΕνεÏγοποιεί/απενεÏγοποιεί τη λειτουÏγία ασφάλειας ψευδώνυμου"
#
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
msgid "Turn nickname security on or off"
msgstr "ΕνεÏγοποιεί/απενεÏγοποιεί τη λειτουÏγία ασφάλειας ψευδώνυμου"
#
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
msgid "Turn protection on or off"
msgstr "ΕνεÏγοποιεί/απενεÏγοποιεί την Ï€Ïοστασία με αποσÏνδεση"
@@ -10352,7 +10315,7 @@ msgstr ""
"ακόμη να πάÏει πληÏοφοÏίες γι αυτό, χÏησιμοποιώντας την\n"
"εντολή #INFO#)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10384,7 +10347,7 @@ msgstr "ΕνεÏγοποιεί/απενεÏγοποιεί τη λειτουÏγÎ
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr "ΕνεÏγοποιεί/απενεÏγοποιεί τη λειτουÏγία ασφάλειας ψευδώνυμου"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10415,7 +10378,7 @@ msgstr ""
"είναι απολÏτως απαÏαίτητο. Επίσης, οι διαχειÏιστές του\n"
"δικτÏου μποÏεί να έχουν απενεÏγοποιήσει αυτή την επιλογή."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10448,7 +10411,7 @@ msgstr ""
"είναι απολÏτως απαÏαίτητο. Επίσης, οι διαχειÏιστές του\n"
"δικτÏου μποÏεί να έχουν απενεÏγοποιήσει αυτή την επιλογή."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10485,7 +10448,7 @@ msgstr ""
"πάνω σε μία επιλογή. Οι επιλογές θα Ïυθμίζονται στο δωσμένο\n"
"#nickname#. "
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10494,7 +10457,7 @@ msgstr ""
"ΓÏάψε #/msg %s HELP #επιλογή## για πεÏισσότεÏες πληÏοφοÏίες\n"
"για την κάθε εντολή."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10512,8 +10475,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Κάνει unload ένα module."
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Το module #%s# δεν μπόÏεσε να αφαιÏεθεί."
@@ -10556,7 +10519,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr " ΥπογÏάμμιση με kick : %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "’γνωστη SASET επιλογή #%s#."
@@ -10576,7 +10539,7 @@ msgstr "’γνωστη επιλογή #%s#."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "’γνωστη εντολή #%s#. \"%s%s HELP\" για βοήθεια."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "’γνωστη επιλογή χαÏακτήÏα #%c# αγνοήθηκε."
@@ -10604,8 +10567,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"ΣÏνταξη: #DROP #κανάλι##\n"
"\n"
@@ -10622,10 +10585,10 @@ msgstr "Κάνει unsuspend ένα nick."
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10675,32 +10638,32 @@ msgid "Used on"
msgstr ""
#
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "Ο/η #%s# άλλαξε τα usermodes σας."
#
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr "Αλλάζει τη λίστα των εξουσιοδοτημένων χÏηστών"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "γινες unban από το #%s#."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "Η vhost για τον #%s# αφαιÏέθηκε."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Το ÏŒÏιο μηνυμάτων για τον %s άλλαξε σε #%d#."
@@ -10755,12 +10718,12 @@ msgstr "Η vhost για το group #%s# έγινε #%s#@#%s#."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
msgid "VIEW [mask | list | id]"
msgstr ""
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10773,7 +10736,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "Το value του %s:%s άλλαξε σε %s"
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10811,7 +10774,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10897,7 +10860,7 @@ msgstr ""
"The #RESET# option currently resets the maximum user count\n"
"to the number of users currently present on the network."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10906,7 +10869,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Είσαι ήδη μέλος της ομάδας του #%s#."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Είστε ήδη identified."
@@ -10975,7 +10938,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -11002,13 +10965,24 @@ msgstr ""
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "Δεν μποÏείτε να ζητήσετε απόδειξη όταν στέλνετε memo στον εαυτό σας."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "Δεν μποÏείτε να χÏησιμοποιήσετε αυτή την εντολή."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr ""
+"Δεν μποÏείτε να κάνετε unassign τα bots όταν είναι ενεγοποιημένη η επιλογή "
+"persist."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Δεν μποÏείς να σκοτώσεις τον εαυτό σου!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Δεν βÏέθηκαν θέσεις στου %s στην access list."
@@ -11018,17 +10992,12 @@ msgstr "Δεν βÏέθηκαν θέσεις στου %s στην access list."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Δεν μποÏείτε να κάνετε Logout τον %s επειδή είναι Services Operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr ""
"Δεν μποÏείς να απενεÏγοποιήσεις την διεÏθυνση του e-mail σε αυτό το δίκτυο."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "Δεν μποÏείτε να χÏησιμοποιήσετε αυτή την εντολή."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -11039,14 +11008,7 @@ msgstr "Δεν μποÏείς να θέσεις ως ÏŒÏιο μηνυμάτων
msgid "You cannot set your memo limit higher than %d."
msgstr "Δεν μποÏείς να θέσεις ως ÏŒÏιο μηνυμάτων μεγαλÏτεÏο από %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr ""
-"Δεν μποÏείτε να κάνετε unassign τα bots όταν είναι ενεγοποιημένη η επιλογή "
-"persist."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr ""
"Δεν μποÏείς να απενεÏγοποιήσεις την διεÏθυνση του e-mail σε αυτό το δίκτυο."
@@ -11090,12 +11052,12 @@ msgstr "ΜέχÏι στιγμής έχεις #1# μήνυμα."
msgid "You currently have no memos."
msgstr "ΜέχÏις στιγμής δεν έχεις κανένα μήνυμα."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr "Δεν έχετε Ï€Ïόσβαση για να αλλάξετε το mode %c."
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "Δεν έχετε Ï€Ïόσβαση για να αλλάξετε τα modes του %s."
@@ -11131,7 +11093,7 @@ msgstr "Έχετε γίνει invite στο κανάλι #%s#."
msgid "You have been invited to %s."
msgstr "Έχετε γίνει invite στο κανάλι #%s#."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr ""
@@ -11176,35 +11138,30 @@ msgstr ""
"#ΠÏοειδοποίηση:# Έχει φτάσει στο μέγιστο νοÏμεÏο μηνυμάτων (%d). Δεν θα "
"λάβεις καινοÏÏγια μηνÏματα αν δεν σβήσεις μεÏικά από τα παλιά που έχεις."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Έχετε γίνει invite στο κανάλι #%s#."
-
#
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr "ΔιαγÏάφει τη vhost από όλα τα nicks σε ένα group"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr ""
"Δεν μποÏείς να απενεÏγοποιήσεις την διεÏθυνση του e-mail σε αυτό το δίκτυο."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr ""
"Δεν μποÏείς να απενεÏγοποιήσεις την διεÏθυνση του e-mail σε αυτό το δίκτυο."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "Δεν μποÏείτε να κάνετε Logout τον %s επειδή είναι Services Operator."
@@ -11250,32 +11207,12 @@ msgid "You must be a channel operator to register the channel."
msgstr ""
"ΠÏέπει να είσαι να έχεις operator status στο κανάλι για να το κατοχυÏώσεις."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr ""
-"Θα Ï€Ïέπει να έχετε κάνει identify για να χÏησιμοποιήσετε αυτή την εντολή."
-
#
#: modules/commands/cs_register.cpp:37
msgid "You must confirm your account before you can register a channel."
msgstr ""
"ΠÏέπει να είσαι να έχεις operator status στο κανάλι για να το κατοχυÏώσεις."
-#
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr ""
-"ΠÏέπει να είσαι να έχεις operator status στο κανάλι για να το κατοχυÏώσεις."
-
-#
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr ""
-"ΠÏέπει να είσαι να έχεις operator status στο κανάλι για να το κατοχυÏώσεις."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11283,20 +11220,20 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"ΠÏέπει να είστε συνδεδεμένος πεÏισσότεÏο από %d δευτεÏόλεπτα για να κάνετε "
"register."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
"Θα Ï€Ïέπει να έχετε κάνει identify για να χÏησιμοποιήσετε αυτή την εντολή."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11311,33 +11248,15 @@ msgid "You need to be identified to use this command."
msgstr ""
"Θα Ï€Ïέπει να έχετε κάνει identify για να χÏησιμοποιήσετε αυτή την εντολή."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Θα ειδοποιηθείς για νέα μηνÏματα όταν θα φτάσουν."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr "Θα ειδοποιηθείς για νέα μηνÏματα όταν κάνεις logon και όταν φτάσουν."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr "Θα ειδοποιηθείς για νέα μηνÏματα όταν κάνεις logon και όταν φτάσουν."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr "Θα ειδοποιηθείς για νέα μηνÏματα όταν κάνεις logon και όταν φτάσουν."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Θα ειδοποιηθείς για νέα μηνÏματα στο logon."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Θα ειδοποιηθείς για νέα μηνÏματα όταν θα φτάσουν."
@@ -11349,7 +11268,7 @@ msgstr "Δεν θα είσαι ικανός να λάβεις άλλα μηνÏÎ
msgid "You will no longer be informed via email."
msgstr "Δε θα σας στέλνονται πια ειδοποιήσεις μέσω email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Δεν θα σου γίνει ειδοποίηση για νέα μηνÏματα."
@@ -11375,23 +11294,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr ""
#
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
msgid "Your account is already confirmed."
msgstr "Το account σας είναι ήδη επιβεβαιωμένο."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Το account σας θα λήξει αν δεν το κάνετε confirm σε %s"
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "Το E-mail address για τον #%s# άλλαξε σε #%s#."
@@ -11401,7 +11320,7 @@ msgstr "Το E-mail address για τον #%s# άλλαξε σε #%s#."
msgid "Your email address is not allowed, choose a different one."
msgstr "Η διεÏθνση email #%s# έχει επιβεβαιωθεί."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
#, fuzzy
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
@@ -11410,12 +11329,12 @@ msgstr ""
"Το email σας δεν έχει επιβεβαιωθεί. Για να το επιβεβαιώσετε, ακολουθήστετις "
"οδηγίες που σας στάλθηκαν στο email όταν κάνατε register."
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Η διεÏθνση email #%s# έχει επιβεβαιωθεί."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "Το E-mail address για τον #%s# άλλαξε σε #%s#."
@@ -11476,7 +11395,7 @@ msgstr ""
msgid "Your nick isn't registered."
msgstr "Το Nickname %s κατωχυÏώθηκε."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Το ψευδώνυμό σου έχει αλλάξει σε #%s#"
@@ -11485,43 +11404,42 @@ msgstr "Το ψευδώνυμό σου έχει αλλάξει σε #%s#"
msgid "Your oper block doesn't require logging in."
msgstr "To oper block σας δεν χÏειάζεται login."
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Το passcode σας, ξαναστάλθηκε στο %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Ο κωδικός σου είναι #%s# - θυμηθείτε τον για μετέπειτα χÏήση."
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Το αίτημά σας για αλλαγή του password έληξε."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "Bot #%s# διαγÏάφηκε."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Η vhost σας #%s# ενεÏγοποιήθηκε."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Η vhost σας #%s#@#%s# ενεÏγοποιήθηκε."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Η Vhost σας αφαιÏέθηκε και το κανονικό cloaking επανακτήθηκε."
@@ -11570,7 +11488,7 @@ msgid "[account] password"
msgstr "IDENTIFY ^_κωδικό^_"
#
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP ##channel# [#nick#]#"
@@ -11625,8 +11543,8 @@ msgstr ""
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
msgid "[nickname]"
msgstr ""
@@ -11646,7 +11564,7 @@ msgstr "CHANKILL [+#expiry#] {##channel#} [#reason#]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11654,20 +11572,20 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
msgid "[auto memo] Your requested vHost has been approved."
msgstr "#[auto-memo]# Το memo που στείλατε στο %s έχει διαβαστεί."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "#[auto-memo]# Το memo που στείλατε στο %s έχει διαβαστεί."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "Το τελευταίο μήνυμα που πήγαινε για τον #%s# ακυÏώθηκε."
@@ -11771,12 +11689,12 @@ msgstr ""
msgid "seconds"
msgstr "Οι εντολές του %s είναι::"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Η vhost σας #%s# ενεÏγοποιήθηκε."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "Bot #%s# διαγÏάφηκε."
@@ -11812,44 +11730,7 @@ msgstr "UNBAN #κανάλι# [#nick#]"
msgid "{nick | channel}"
msgstr "RSEND {#nick# | #channel#} #memo-text#"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "RSEND {#nick# | #channel#} #memo-text#"
-
-#, fuzzy
-#~ msgid ""
-#~ " \n"
-#~ "The %s commands are limited to founders\n"
-#~ "(unless SECUREOPS is off). However, any user on the\n"
-#~ "VOP list or above may use the %s LIST command.\n"
-#~ " \n"
-#~ msgstr ""
-#~ " \n"
-#~ "Οι εντολές #QOP# πεÏιοÏίζονται στους\n"
-#~ "ιδιοκτήτες (εκτώς αν το SECUREOPS είναι απενεÏγοποιημένο).\n"
-#~ "ΠαÏόλα αυτά όλοι στην λίστα #QOP# μποÏοÏν να χÏησιμοποιήσουν την εντολή "
-#~ "#QOP LIST#\n"
-#~ " \n"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "Exception για #%s# (#%d) μετακινήθηκε στη θέση #%d#."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Οι παλιές πληÏοφοÏίες είναι ίδιες με τις καινοÏÏγιες."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Syntax: #GETEMAIL #user@emailhost##\n"
-#~ "Εμφανίζει τη λίστα με τα ψευδόνυμα που χÏησιμοποιοÏν ένα email. "
-#~ "#ΠÏοσοχή#:\n"
-#~ "Δεν μποÏείτε να χÏησιμοποιείσετε wildcards για το nick ή το emailhost. "
-#~ "Όποτε\n"
-#~ "χÏησιμοποιείται αυτή η εντολή, ένα μήνυμα με το όνομα του ατόμου που τη "
-#~ "χÏησιμοποίησε\n"
-#~ "και το email που έψαξε, θα καταγÏάφεται."
diff --git a/language/anope.en_US.po b/language/anope.en_US.po
index d948208b5..f69d13ace 100644
--- a/language/anope.en_US.po
+++ b/language/anope.en_US.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-07-27 07:54+0200\n"
"PO-Revision-Date: 2014-07-27 07:54+0200\n"
"Last-Translator: <Adam@anope.org>\n"
"Language-Team: English\n"
@@ -28,17 +28,17 @@ msgstr "%d channel(s) cleared, and %d channel(s) dropped."
msgid "%d nickname(s) dropped."
msgstr "%d nickname(s) dropped."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, c-format
msgid "%s added to %s %s list."
msgstr "%s added to %s %s list."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s added to %s access list at level %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s added to %s access list at privilege %s (level %d)"
@@ -48,7 +48,7 @@ msgstr "%s added to %s access list at privilege %s (level %d)"
msgid "%s added to %s autokick list."
msgstr "%s added to %s autokick list."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s added to %s bad words list."
@@ -63,17 +63,17 @@ msgstr "%s added to %s's access list."
msgid "%s added to %s's certificate list."
msgstr "%s added to %s's certificate list."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, c-format
msgid "%s added to ignore list."
msgstr "%s added to ignore list."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s added to the %s list."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s added to the AKILL list."
@@ -114,7 +114,7 @@ msgstr ""
"more information on a specific command, type\n"
"%s%s %s command.\n"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -131,7 +131,7 @@ msgstr ""
"For more information on a specific command, type\n"
"%s%s %s command.\n"
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -146,7 +146,7 @@ msgstr ""
"For more information on a specific command, type\n"
"%s%s %s command.\n"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -165,7 +165,7 @@ msgstr ""
"%s%s command. For more information on a\n"
"specific command, type %s%s HELP command.\n"
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s already exists in %s bad words list."
@@ -186,7 +186,7 @@ msgstr "%s already exists on the EXCEPTION list."
msgid "%s cannot be taken as times to ban."
msgstr "%s cannot be taken as times to ban."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s changed your usermodes to %s."
@@ -196,12 +196,12 @@ msgstr "%s changed your usermodes to %s."
msgid "%s channel list:"
msgstr "%s channel list:"
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, c-format
msgid "%s deleted from %s %s list."
msgstr "%s deleted from %s %s list."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s deleted from %s access list."
@@ -211,7 +211,7 @@ msgstr "%s deleted from %s access list."
msgid "%s deleted from %s autokick list."
msgstr "%s deleted from %s autokick list."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s deleted from %s bad words list."
@@ -236,12 +236,12 @@ msgstr "%s deleted from session-limit exception list."
msgid "%s deleted from the %s list."
msgstr "%s deleted from the %s list."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s deleted from the AKILL list."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s disabled on channel %s."
@@ -313,7 +313,7 @@ msgstr "%s is already in %s!"
msgid "%s is already in %s."
msgstr "%s is already in %s."
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, c-format
msgid "%s is already on the ignore list."
msgstr "%s is already on the ignore list."
@@ -323,7 +323,7 @@ msgstr "%s is already on the ignore list."
msgid "%s is already suspended."
msgstr "%s is already suspended."
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s is not a registered unforbidden nick or channel."
@@ -353,7 +353,7 @@ msgstr "%s is not currently on channel %s."
msgid "%s is not in %s."
msgstr "%s is not in %s."
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, c-format
msgid "%s is not on the ignore list."
msgstr "%s is not on the ignore list."
@@ -387,12 +387,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s matches auto kick entry %s on %s (%s)."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, c-format
msgid "%s not found on %s %s list."
msgstr "%s not found on %s %s list."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s not found on %s access list."
@@ -402,7 +402,7 @@ msgstr "%s not found on %s access list."
msgid "%s not found on %s autokick list."
msgstr "%s not found on %s autokick list."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s not found on %s bad words list."
@@ -441,17 +441,17 @@ msgstr "%s not found on session-limit exception list."
msgid "%s not found on the %s list."
msgstr "%s not found on the %s list."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s not found on the AKILL list."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "%s removed from the %s access list."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, c-format
msgid "%s removed from the ignore list."
msgstr "%s removed from the ignore list."
@@ -481,20 +481,19 @@ msgstr "%s will now permanently be ignored."
msgid "%s%s HELP %s for more information."
msgstr "%s%s HELP %s for more information."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr "ADD nick user host real"
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr "CHANGE oldnick newnick [user [host [real]]]"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL nick"
-#: modules/commands/os_session.cpp:560
-#, fuzzy
+#: modules/commands/os_session.cpp:601
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
"Note that nick!user@host and user@host masks are invalid!\n"
@@ -508,6 +507,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -555,7 +557,7 @@ msgstr ""
"up on the given server. REVOKE removes this\n"
"restriction."
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -575,19 +577,19 @@ msgstr "[auto-memo] The memo you sent to %s has been viewed."
msgid "[target] [password]"
msgstr "[target] [password]"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr "address"
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
msgid "botname {ON|OFF}"
msgstr "botname {ON|OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_log.cpp:106 modules/commands/bs_assign.cpp:91
+#: modules/commands/cs_info.cpp:20 modules/commands/cs_getkey.cpp:20
msgid "channel"
msgstr "channel"
@@ -611,8 +613,8 @@ msgstr "channel mask [reason]"
msgid "channel modes"
msgstr "channel modes"
-#: modules/commands/bs_assign.cpp:20 modules/commands/cs_set.cpp:264
-#: modules/commands/cs_set.cpp:962
+#: modules/commands/cs_set.cpp:264 modules/commands/cs_set.cpp:962
+#: modules/commands/bs_assign.cpp:20
msgid "channel nick"
msgstr "channel nick"
@@ -620,7 +622,7 @@ msgstr "channel nick"
msgid "channel nick [reason]"
msgstr "channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr "channel target [what]"
@@ -628,7 +630,7 @@ msgstr "channel target [what]"
msgid "channel text"
msgstr "channel text"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
msgid "channel time"
msgstr "channel time"
@@ -640,11 +642,11 @@ msgstr "channel user reason"
msgid "channel what"
msgstr "channel what"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
msgid "channel ADD mask"
msgstr "channel ADD mask"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr "channel ADD mask level"
@@ -652,7 +654,7 @@ msgstr "channel ADD mask level"
msgid "channel ADD message"
msgstr "channel ADD message"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr "channel ADD word [SINGLE | START | END]"
@@ -660,17 +662,17 @@ msgstr "channel ADD word [SINGLE | START | END]"
msgid "channel ADD {nick | mask} [reason]"
msgstr "channel ADD {nick | mask} [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
msgid "channel APPEND topic"
msgstr "channel APPEND topic"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_entrymsg.cpp:197
+#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_akick.cpp:428
msgid "channel CLEAR"
msgstr "channel CLEAR"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
msgid "channel CLEAR [what]"
msgstr "channel CLEAR [what]"
@@ -682,7 +684,7 @@ msgstr "channel CLEAR [ALL]"
msgid "channel DEL num"
msgstr "channel DEL num"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
msgid "channel DEL {mask | entry-num | list}"
msgstr "channel DEL {mask | entry-num | list}"
@@ -690,7 +692,7 @@ msgstr "channel DEL {mask | entry-num | list}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "channel DEL {nick | mask | entry-num | list}"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
msgid "channel DEL {word | entry-num | list}"
msgstr "channel DEL {word | entry-num | list}"
@@ -698,7 +700,7 @@ msgstr "channel DEL {word | entry-num | list}"
msgid "channel ENFORCE"
msgstr "channel ENFORCE"
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr "channel LIST"
@@ -706,44 +708,52 @@ msgstr "channel LIST"
msgid "channel LIST [mask | entry-num | list]"
msgstr "channel LIST [mask | entry-num | list]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/cs_xop.cpp:487
+#: modules/commands/bs_badwords.cpp:372
msgid "channel LIST [mask | list]"
msgstr "channel LIST [mask | list]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr "channel LIST [mask | +flags]"
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "channel LOCK {ADD|DEL|SET|LIST} [what]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr "channel MODIFY mask changes"
+
+#: modules/commands/cs_access.cpp:738
msgid "channel RESET"
msgstr "channel RESET"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
msgid "channel SET modes"
msgstr "channel SET modes"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr "channel SET type level"
+#: modules/commands/cs_topic.cpp:157
+msgid "channel SET [topic]"
+msgstr "channel SET [topic]"
+
#: modules/commands/cs_akick.cpp:426
msgid "channel VIEW [mask | entry-num | list]"
msgstr "channel VIEW [mask | entry-num | list]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
msgid "channel VIEW [mask | list]"
msgstr "channel VIEW [mask | list]"
-#: modules/commands/cs_set.cpp:202 modules/commands/cs_register.cpp:20
+#: modules/commands/cs_register.cpp:20 modules/commands/cs_set.cpp:202
msgid "channel [description]"
msgstr "channel [description]"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
msgid "channel [nick]"
msgstr "channel [nick]"
@@ -751,7 +761,7 @@ msgstr "channel [nick]"
msgid "channel [parameters]"
msgstr "channel [parameters]"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_mode.cpp:752 modules/commands/cs_status.cpp:20
msgid "channel [user]"
msgstr "channel [user]"
@@ -763,22 +773,12 @@ msgstr "channel [+expiry] [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "channel [+expiry] {nick | mask} [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "channel MODIFY mask changes"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "channel SET [topic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
msgid "channel [UNLOCK|LOCK]"
msgstr "channel [UNLOCK|LOCK]"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
msgid "channel {ON|OFF}"
msgstr "channel {ON|OFF}"
@@ -801,7 +801,7 @@ msgstr "channel {ON|OFF} [ttb [num]]"
msgid "channel {ON|OFF} [ttb]"
msgstr "channel {ON|OFF} [ttb]"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr "channel {DIS | DISABLE} type"
@@ -809,13 +809,13 @@ msgstr "channel {DIS | DISABLE} type"
msgid "channel {ON | LEVEL | OFF}"
msgstr "channel {ON | LEVEL | OFF}"
-#: modules/commands/cs_list.cpp:181 modules/commands/bs_kick.cpp:781
-#: modules/commands/bs_kick.cpp:846 modules/commands/cs_topic.cpp:21
-#: modules/commands/cs_set.cpp:72 modules/commands/cs_set.cpp:333
-#: modules/commands/cs_set.cpp:398 modules/commands/cs_set.cpp:470
-#: modules/commands/cs_set.cpp:633 modules/commands/cs_set.cpp:695
-#: modules/commands/cs_set.cpp:759 modules/commands/cs_set.cpp:823
-#: modules/commands/cs_set.cpp:1048 modules/extra/stats/m_chanstats.cpp:10
+#: modules/extra/stats/m_chanstats.cpp:10 modules/commands/cs_set.cpp:72
+#: modules/commands/cs_set.cpp:333 modules/commands/cs_set.cpp:398
+#: modules/commands/cs_set.cpp:470 modules/commands/cs_set.cpp:633
+#: modules/commands/cs_set.cpp:695 modules/commands/cs_set.cpp:759
+#: modules/commands/cs_set.cpp:823 modules/commands/cs_set.cpp:1048
+#: modules/commands/bs_kick.cpp:781 modules/commands/bs_kick.cpp:846
+#: modules/commands/cs_topic.cpp:21 modules/commands/cs_list.cpp:181
msgid "channel {ON | OFF}"
msgstr "channel {ON | OFF}"
@@ -823,15 +823,15 @@ msgstr "channel {ON | OFF}"
msgid "email"
msgstr "email"
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr "language"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
msgid "memo-text"
msgstr "memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
msgid "message"
msgstr "message"
@@ -840,7 +840,7 @@ msgstr "message"
msgid "modname"
msgstr "modname"
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr "new-display"
@@ -848,9 +848,9 @@ msgstr "new-display"
msgid "new-password"
msgstr "new-password"
-#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/extra/stats/cs_fantasy_stats.cpp:52 modules/commands/hs_del.cpp:20
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187 modules/commands/cs_seen.cpp:258
msgid "nick"
msgstr "nick"
@@ -874,16 +874,16 @@ msgstr "nick hostmask"
msgid "nick newnick"
msgstr "nick newnick"
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
msgid "nick [reason]"
msgstr "nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_suspend.cpp:161
msgid "nickname"
msgstr "nickname"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr "nickname address"
@@ -891,7 +891,7 @@ msgstr "nickname address"
msgid "nickname email"
msgstr "nickname email"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr "nickname language"
@@ -899,11 +899,11 @@ msgstr "nickname language"
msgid "nickname message"
msgstr "nickname message"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr "nickname new-display"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "nickname new-password"
@@ -911,7 +911,7 @@ msgstr "nickname new-password"
msgid "nickname [parameter]"
msgstr "nickname [parameter]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
msgid "nickname [password]"
msgstr "nickname [password]"
@@ -923,14 +923,14 @@ msgstr "nickname [+expiry] [reason]"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
-#: modules/extra/stats/m_chanstats.cpp:122
+#: modules/extra/stats/m_chanstats.cpp:122 modules/commands/ns_set.cpp:294
+#: modules/commands/ns_set.cpp:610 modules/commands/ns_set.cpp:961
+#: modules/commands/ns_set.cpp:1052 modules/commands/ns_set.cpp:1081
+#: modules/commands/ns_list.cpp:252
msgid "nickname {ON | OFF}"
msgstr "nickname {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "nickname {ON | QUICK | IMMED | OFF}"
@@ -950,7 +950,7 @@ msgstr "option channel {ON|OFF} [settings]"
msgid "option nickname parameters"
msgstr "option nickname parameters"
-#: modules/commands/ns_set.cpp:20 modules/commands/ms_set.cpp:207
+#: modules/commands/ms_set.cpp:207 modules/commands/ns_set.cpp:20
msgid "option parameters"
msgstr "option parameters"
@@ -966,11 +966,11 @@ msgstr "passcode"
msgid "password"
msgstr "password"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
msgid "password [email]"
msgstr "password [email]"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
msgid "password email"
msgstr "password email"
@@ -986,7 +986,7 @@ msgstr "pattern [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "server [reason]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr "user modes"
@@ -994,7 +994,7 @@ msgstr "user modes"
msgid "user [reason]"
msgstr "user [reason]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, c-format
msgid ""
" \n"
@@ -1013,7 +1013,7 @@ msgstr ""
"will result in, at minimum, loss of the abused\n"
"nickname(s)."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
msgid ""
" \n"
"SNLINE ADD adds the given realname mask to the SNLINE\n"
@@ -1047,7 +1047,7 @@ msgstr ""
"Note: because the realname mask may contain spaces, the\n"
"separator between it and the reason is a colon."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1075,7 +1075,7 @@ msgstr ""
"current SQLINE default expiry time can be found with the\n"
"STATS AKILL command."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, c-format
msgid ""
" \n"
@@ -1187,7 +1187,7 @@ msgstr ""
"NOTICE: In order to register a channel, you must have\n"
"first registered your nickname."
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1213,7 +1213,7 @@ msgstr ""
"information on giving a subset of these privileges to\n"
"other channel users.\n"
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1225,7 +1225,7 @@ msgstr ""
"to identify for the nick, and may view the access list for\n"
"any nickname."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1237,7 +1237,7 @@ msgstr ""
"any channel, view (and modify) the access, levels and akick\n"
"lists and settings for any channel."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1251,7 +1251,7 @@ msgstr ""
"be removed after the given time. Set to 0 to disable bans from\n"
"automatically expiring."
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:546
#, c-format
msgid ""
" \n"
@@ -1292,7 +1292,7 @@ msgstr ""
"The %s CLEAR command clears all entries of the\n"
"%s list."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1335,7 +1335,7 @@ msgstr ""
"The AKICK CLEAR command clears all entries of the\n"
"akick list."
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
msgid ""
" \n"
"The AKILL DEL command removes the given mask from the\n"
@@ -1377,7 +1377,7 @@ msgstr ""
" \n"
"AKILL CLEAR clears all entries of the AKILL list."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
msgid ""
" \n"
"The SNLINE DEL command removes the given mask from the\n"
@@ -1419,7 +1419,7 @@ msgstr ""
" \n"
"SNLINE CLEAR clears all entries of the SNLINE list."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1473,7 +1473,7 @@ msgstr ""
"is already assigned to the channel, it is unassigned\n"
"automatically when you enable it."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
msgid ""
" \n"
"This option prevents a bot from being assigned to a\n"
@@ -1494,7 +1494,7 @@ msgstr ""
"Type %s%s HELP command for help on any of the\n"
"above commands."
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr " %s is online using this oper block."
@@ -1509,7 +1509,7 @@ msgstr " Command %s on %s is linked to %s"
msgid " Providing service: %s"
msgstr " Providing service: %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr " This oper is configured in the configuration file."
@@ -1523,7 +1523,7 @@ msgstr " Loaded at: %p"
msgid " but %s mysteriously dematerialized."
msgstr " but %s mysteriously dematerialized."
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1534,7 +1534,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr "\"Jupiter\" a server"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1553,17 +1553,17 @@ msgstr "%b %d %H:%M:%S %Y %Z"
msgid "%c is an unknown status mode."
msgstr "%c is an unknown status mode."
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c is not locked on %s."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s has been unlocked from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "%d access entries from %s have been cloned to %s."
@@ -1588,8 +1588,8 @@ msgstr "%d nickname(s) in the group."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr "%lu nicks are stored in the database, using %.2Lf kB of memory."
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, c-format
msgid "%s %s list is empty."
msgstr "%s %s list is empty."
@@ -1681,9 +1681,9 @@ msgstr "%s (%s) was last seen quitting (%s) %s ago (%s)."
msgid "%s (minimum %d/%d%%)"
msgstr "%s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "%s access list is empty."
@@ -1693,7 +1693,7 @@ msgstr "%s access list is empty."
msgid "%s added to %s's auto join list."
msgstr "%s added to %s's auto join list."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s already exists."
@@ -1704,7 +1704,7 @@ msgstr "%s already exists."
msgid "%s autokick list is empty."
msgstr "%s autokick list is empty."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "%s bad words list is empty."
@@ -1714,8 +1714,8 @@ msgstr "%s bad words list is empty."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s cannot be the successor on channel %s as they are the founder."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
#, c-format
msgid "%s commands:"
msgstr "%s commands:"
@@ -1815,7 +1815,7 @@ msgstr "%s is a client on services."
msgid "%s is a network service."
msgstr "%s is a network service."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s is already covered by %s."
@@ -1830,7 +1830,7 @@ msgstr "%s is already on %s's auto join list."
msgid "%s is an unconfirmed nickname."
msgstr "%s is an unconfirmed nickname."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1856,7 +1856,7 @@ msgstr "%s is disabled"
msgid "%s is enabled"
msgstr "%s is enabled"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, c-format
msgid "%s is not a valid IP address."
msgstr "%s is not a valid IP address."
@@ -1901,7 +1901,7 @@ msgstr "%s is on the channel right now (as %s)!"
msgid "%s is on the channel right now!"
msgstr "%s is on the channel right now!"
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, c-format
msgid "%s list for %s"
msgstr "%s list for %s"
@@ -1911,7 +1911,7 @@ msgstr "%s list for %s"
msgid "%s list is empty."
msgstr "%s list is empty."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, c-format
msgid "%s locked on %s."
msgstr "%s locked on %s."
@@ -1965,7 +1965,7 @@ msgstr ""
msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr "%s will now notify you of memos when you log on or unset /AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) added to the bot list."
@@ -2019,11 +2019,11 @@ msgstr "(Split)"
msgid "(by %s on %s) %s"
msgstr "(by %s on %s) %s"
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
msgid "(disabled)"
msgstr "(disabled)"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr "(founder only)"
@@ -2087,7 +2087,7 @@ msgstr ". %s is still online."
msgid "<unknown>"
msgstr "<unknown>"
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2100,7 +2100,7 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "A massmemo has been sent to all registered users."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
@@ -2108,7 +2108,7 @@ msgstr ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr "A memo informing the user will also be sent."
@@ -2145,7 +2145,7 @@ msgstr "ADD target info"
msgid "ADD text"
msgstr "ADD text"
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr "ADD [+expiry] mask limit reason"
@@ -2161,11 +2161,11 @@ msgstr "ADD [nickname] mask"
msgid "ADD [nickname] [fingerprint]"
msgstr "ADD [nickname] [fingerprint]"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_sxline.cpp:651 modules/commands/os_akill.cpp:380
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+expiry] mask reason"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+expiry] mask:reason"
@@ -2173,15 +2173,15 @@ msgstr "ADD [+expiry] mask:reason"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr "ADDIP server.name ip"
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr "ADDSERVER server.name [zone.name]"
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr "ADDZONE zone.name"
@@ -2194,8 +2194,8 @@ msgstr "AKICK ENFORCE for %s complete; %d users were affected."
msgid "AKILL all users on a specific channel"
msgstr "AKILL all users on a specific channel"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "AKILL list is empty."
@@ -2226,17 +2226,17 @@ msgstr "Access level must be between %d and %d inclusive."
msgid "Access level must be non-zero."
msgstr "Access level must be non-zero."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Access level settings for channel %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Access levels for %s reset to defaults."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, c-format
msgid "Access list for %s:"
msgstr "Access list for %s:"
@@ -2250,23 +2250,15 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Activate security features"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr "Activate the requested vHost for the given nick."
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -2290,7 +2282,7 @@ msgstr ""
"This will show to opers in the respective info command for\n"
"the nick or channel."
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr "Added IP %s to %s."
@@ -2327,13 +2319,7 @@ msgstr "Added server %s."
msgid "Added zone %s."
msgstr "Added zone %s."
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2357,7 +2343,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "All O:lines of %s have been reset."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "All akick entries from %s have been cloned to %s."
@@ -2367,16 +2353,11 @@ msgstr "All akick entries from %s have been cloned to %s."
msgid "All available commands for %s:"
msgstr "All available commands for %s:"
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "All badword entries from %s have been cloned to %s."
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "All akick entries from %s have been cloned to %s."
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "All logon news items deleted."
@@ -2386,12 +2367,12 @@ msgstr "All logon news items deleted."
msgid "All memos for channel %s have been deleted."
msgstr "All memos for channel %s have been deleted."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr "All modes cleared on %s."
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2416,7 +2397,7 @@ msgstr "All operators from %s have been removed."
msgid "All random news items deleted."
msgstr "All random news items deleted."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "All settings from %s have been cloned to %s."
@@ -2427,13 +2408,13 @@ msgid "All user modes on %s have been synced."
msgstr "All user modes on %s have been synced."
#: modules/commands/hs_group.cpp:60
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s."
msgstr "All vhost's in the group %s have been set to %s."
#: modules/commands/hs_group.cpp:58
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "All vhost's in the group %s have been set to %s@%s."
#: src/access.cpp:41
@@ -2557,7 +2538,7 @@ msgstr ""
"Allows Administrators to send messages to all users on the\n"
"network. The message will be sent from the nick %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
msgid ""
"Allows Services Operators to change modes for any channel.\n"
"Parameters are the same as for the standard /MODE command.\n"
@@ -2569,7 +2550,7 @@ msgstr ""
"Alternatively, CLEAR may be given to clear all modes on the channel.\n"
"If CLEAR ALL is given then all modes, including user status, is removed."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
msgid ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
@@ -2577,7 +2558,7 @@ msgstr ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
msgid ""
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
@@ -2651,7 +2632,7 @@ msgstr ""
" \n"
"Ignores will not be enforced on IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
"a user matching an AKILL mask attempts to connect, Services\n"
@@ -2695,7 +2676,7 @@ msgstr ""
"current AKILL default expiry time can be found with the\n"
"STATS AKILL command."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2707,17 +2688,14 @@ msgstr ""
"connect, Services will not allow it to pursue his IRC\n"
"session."
-#: modules/commands/os_sxline.cpp:670
-#, fuzzy
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
@@ -2726,7 +2704,7 @@ msgstr ""
"If the first character of the mask is #, services will\n"
"prevent the use of matching channels."
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2778,8 +2756,7 @@ msgstr ""
"limiting and how to set session limits specific to certain\n"
"hosts and groups thereof."
-#: modules/commands/cs_topic.cpp:193
-#, fuzzy
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2787,9 +2764,8 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2800,7 +2776,7 @@ msgstr ""
"topic lock is set, the channel topic will be unchangeable except via this "
"command."
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -2829,7 +2805,7 @@ msgstr ""
" \n"
"Available options:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2857,7 +2833,7 @@ msgstr ""
"Example:\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2867,7 +2843,7 @@ msgstr ""
"the given user. With MSG set, Services will use messages,\n"
"else they'll use notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2878,7 +2854,7 @@ msgstr ""
"you. With %s set, Services will use messages, else they'll\n"
"use notices."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -2958,7 +2934,7 @@ msgstr ""
"you'll get information about a bot, such as creation\n"
"time or number of channels it is on."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:571
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
@@ -2966,7 +2942,7 @@ msgstr ""
"Alternative methods of modifying channel access lists are\n"
"available. "
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
msgid "Approve the requested vHost of a user"
msgstr "Approve the requested vHost of a user"
@@ -2988,15 +2964,15 @@ msgstr ""
"can then configure the bot for the channel so it fits\n"
"your needs."
-#: data/chanserv.example.conf:1200
+#: data/chanserv.example.conf:1186
msgid "Associate a URL with the channel"
msgstr "Associate a URL with the channel"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr "Associate a URL with this account"
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
msgid "Associate a URL with your account"
msgstr "Associate a URL with your account"
@@ -3004,11 +2980,11 @@ msgstr "Associate a URL with your account"
msgid "Associate a greet message with your nickname"
msgstr "Associate a greet message with your nickname"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
msgid "Associate an E-mail address with the channel"
msgstr "Associate an E-mail address with the channel"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Associate an E-mail address with your nickname"
@@ -3016,11 +2992,11 @@ msgstr "Associate an E-mail address with your nickname"
msgid "Associate oper info with a nick or channel"
msgstr "Associate oper info with a nick or channel"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Associates the given E-mail address with the nickname."
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3030,7 +3006,7 @@ msgstr ""
"This address will be displayed whenever someone requests\n"
"information on the nickname with the INFO command."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3059,19 +3035,12 @@ msgstr "Automatic protect upon join"
msgid "Automatic voice on join"
msgstr "Automatic voice on join"
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, c-format
msgid "Available commands for %s:"
msgstr "Available commands for %s:"
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr ""
-" \n"
-"Available commands are:"
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr "Available privileges for %s:"
@@ -3085,20 +3054,20 @@ msgstr "BANS enforced by "
msgid "Bad words kicker"
msgstr "Bad words kicker"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, c-format
msgid "Bad words list for %s:"
msgstr "Bad words list for %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Bad words list is now empty."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr "Ban expiry may not be longer than 1 day."
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, c-format
msgid "Ban on %s expires in %s."
msgstr "Ban on %s expires in %s."
@@ -3116,7 +3085,7 @@ msgstr "Ban type for channel %s is now #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Bans a given nick or mask on a channel"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3142,7 +3111,7 @@ msgstr "Bans enforced on %s."
msgid "Bolds kicker"
msgstr "Bolds kicker"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Bot %s already exists."
@@ -3157,12 +3126,12 @@ msgstr "Bot %s does not exist."
msgid "Bot %s has been assigned to %s."
msgstr "Bot %s has been assigned to %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot %s has been changed to %s!%s@%s (%s)."
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot %s has been deleted."
@@ -3192,40 +3161,40 @@ msgstr "Bot won't kick ops on channel %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot won't kick voices on channel %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, c-format
msgid "Bot %s is not changeable."
msgstr "Bot %s is not changeable."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, c-format
msgid "Bot %s is not deletable."
msgstr "Bot %s is not deletable."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr "Bot bans will automatically expire after %s."
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
msgid "Bot bans will no longer automatically expire."
msgstr "Bot bans will no longer automatically expire."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot hosts may only be %d characters long."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot hosts may only contain valid host characters."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot idents may only be %d characters long."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot idents may only contain valid ident characters."
@@ -3242,12 +3211,12 @@ msgstr "Bot list:"
msgid "Bot nick"
msgstr "Bot nick"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot nicks may only be %d characters long."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot nicks may only contain valid nick characters."
@@ -3336,8 +3305,8 @@ msgstr "Bot won't kick for flood anymore."
msgid "Bot won't kick for repeats anymore."
msgstr "Bot won't kick for repeats anymore."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_session.cpp:552
msgid "By"
msgstr "By"
@@ -3369,12 +3338,12 @@ msgstr ""
"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."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Cannot clone channel %s to itself!"
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Cannot send mail now; please retry a little later."
@@ -3440,20 +3409,20 @@ msgstr "ChanServ is required to enable persist on this network."
msgid "Change channel modes"
msgstr "Change channel modes"
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Change the communication method of Services"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
msgid "Change user modes"
msgstr "Change user modes"
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Changed usermodes of %s to %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3461,7 +3430,7 @@ msgstr ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3477,7 +3446,7 @@ msgstr ""
"Changes the founder of a channel. The new nickname must\n"
"be a registered one."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3489,7 +3458,7 @@ msgstr ""
"language should be chosen from the following list of\n"
"supported languages:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3501,11 +3470,11 @@ msgstr ""
"language should be chosen from the following list of\n"
"supported languages:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr "Changes the password used to identify as the nick's owner."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3604,12 +3573,12 @@ msgstr "Channel %s will expire."
msgid "Channel %s will not expire."
msgstr "Channel %s will not expire."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Channel %s %s list has been cleared."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Channel %s access list has been cleared."
@@ -3619,7 +3588,7 @@ msgstr "Channel %s access list has been cleared."
msgid "Channel %s akick list has been cleared."
msgstr "Channel %s akick list has been cleared."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Channel %s has no mode locks."
@@ -3643,8 +3612,8 @@ msgstr "Channel list:"
msgid "Channel stats for %s on %s:"
msgstr "Channel stats for %s on %s:"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_flags.cpp:99
+#: modules/commands/cs_xop.cpp:142
msgid "Channels may not be on access lists."
msgstr "Channels may not be on access lists."
@@ -3787,7 +3756,7 @@ msgstr "Configures repeat kicker"
msgid "Configures reverses kicker"
msgstr "Configures reverses kicker"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
msgid "Configures the time bot bans expire in"
msgstr "Configures the time bot bans expire in"
@@ -3799,7 +3768,7 @@ msgstr "Configures underlines kicker"
msgid "Confirm a passcode"
msgstr "Confirm a passcode"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
msgid "Control modes and mode locks on a channel"
msgstr "Control modes and mode locks on a channel"
@@ -3809,12 +3778,11 @@ msgid ""
msgstr ""
"Controls what messages will be sent to users when they join the channel."
-#: modules/commands/cs_clone.cpp:241
-#, fuzzy
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Copies all settings, access, akicks, etc from channel to the\n"
@@ -3822,37 +3790,37 @@ msgstr ""
"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "Copy all settings from one channel to another"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_mode.cpp:431 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_news.cpp:156
+#: modules/commands/hs_request.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/os_session.cpp:552 modules/commands/bs_info.cpp:58
+#: modules/commands/os_akill.cpp:355
msgid "Created"
msgstr "Created"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/hs_list.cpp:58 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_mode.cpp:431 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/os_ignore.cpp:266 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_news.cpp:156 modules/commands/cs_akick.cpp:380
+#: modules/commands/os_akill.cpp:355
msgid "Creator"
msgstr "Creator"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Current %s list:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
msgid "Current AKILL list:"
msgstr "Current AKILL list:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Current Session Limit Exception list:"
@@ -3900,12 +3868,12 @@ msgstr "DEL [nickname] fingerprint"
msgid "DEL [nickname] mask"
msgstr "DEL [nickname] mask"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_sxline.cpp:419 modules/commands/os_sxline.cpp:652
+#: modules/commands/os_akill.cpp:381
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {mask | entry-num | list | id}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
msgid "DEL {mask | entry-num | list}"
msgstr "DEL {mask | entry-num | list}"
@@ -3921,19 +3889,19 @@ msgstr "DEL {num | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr "DELIP server.name ip"
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr "DELSERVER server.name [zone.name]"
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr "DELZONE zone.name"
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
msgid "DEPOOL server.name"
msgstr "DEPOOL server.name"
@@ -3946,7 +3914,7 @@ msgstr "Database cleared, removed %lu nicks that were added after %s."
msgid "Date/Time"
msgstr "Date/Time"
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4073,12 +4041,12 @@ msgstr "Delete a memo or memos"
msgid "Delete the vhost of another user"
msgstr "Delete the vhost of another user"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Deleted %d entries from %s %s list."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Deleted %d entries from %s access list."
@@ -4088,7 +4056,7 @@ msgstr "Deleted %d entries from %s access list."
msgid "Deleted %d entries from %s autokick list."
msgstr "Deleted %d entries from %s autokick list."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Deleted %d entries from %s bad words list."
@@ -4108,7 +4076,7 @@ msgstr "Deleted %d entries from the %s list."
msgid "Deleted %d entries from the AKILL list."
msgstr "Deleted %d entries from the AKILL list."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "Deleted 1 entry from %s access list."
@@ -4118,7 +4086,7 @@ msgstr "Deleted 1 entry from %s access list."
msgid "Deleted 1 entry from %s autokick list."
msgstr "Deleted 1 entry from %s autokick list."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Deleted 1 entry from %s bad words list."
@@ -4141,7 +4109,7 @@ msgstr "Deleted 1 entry from the AKILL list."
msgid "Deleted info from %s."
msgstr "Deleted info from %s."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Deleted one entry from %s %s list."
@@ -4198,13 +4166,13 @@ msgstr ""
"Deletes the vhost for all nicks in the same group as\n"
"that of the given nick."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr "Depooled %s."
+#: modules/commands/cs_access.cpp:784 modules/commands/ns_alist.cpp:48
#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
msgid "Description"
msgstr "Description"
@@ -4242,7 +4210,7 @@ msgstr ""
" \n"
"Reason may be required on certain networks."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, c-format
msgid "Displayed %d records (%d total)."
msgstr "Displayed %d records (%d total)."
@@ -4357,12 +4325,12 @@ msgstr ""
"you may own. Any other user will be able to gain control of\n"
"this nick."
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail address for %s changed to %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail address for %s unset."
@@ -4417,8 +4385,8 @@ msgid "Email address"
msgstr "Email address"
#: modules/commands/ns_getemail.cpp:41
-#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+#, c-format
+msgid "Email matched: %s to %s."
msgstr "Email matched: %s to %s."
#: modules/fantasy.cpp:19
@@ -4429,7 +4397,7 @@ msgstr "Enable fantaisist commands"
msgid "Enable greet messages"
msgstr "Enable greet messages"
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr "Enable or disable keep modes"
@@ -4458,7 +4426,7 @@ msgstr ""
"modes is enabled, services will remember modes set on the channel\n"
"and attempt to re-set them the next time the channel is created."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4468,7 +4436,7 @@ msgstr ""
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4555,11 +4523,10 @@ msgstr ""
"the access/qop command."
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Enables or disables the secure ops option for a channel.\n"
"When secure ops is set, users who are not on the userlist\n"
@@ -4581,7 +4548,7 @@ msgstr ""
"next time the channel is created."
#: modules/commands/cs_set.cpp:603
-#, fuzzy, c-format
+#, c-format
msgid ""
"Enables or disables the persistent channel setting.\n"
"When persistent is set, the service bot will remain\n"
@@ -4599,7 +4566,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -4623,20 +4590,20 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
msgid "End of AKILL list."
msgstr "End of AKILL list."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
msgid "End of access list"
msgstr "End of access list"
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "End of access list - %d/%d entries shown."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "End of access list."
@@ -4644,7 +4611,7 @@ msgstr "End of access list."
msgid "End of autokick list"
msgstr "End of autokick list"
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
msgid "End of bad words list."
msgstr "End of bad words list."
@@ -4674,7 +4641,7 @@ msgstr "End of forbid list."
msgid "End of list - %d channels shown."
msgstr "End of list - %d channels shown."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "End of list - %d/%d matches shown."
@@ -4721,8 +4688,8 @@ msgstr ""
"kicking users affected by them, and LIMIT will kick users until the\n"
"user count drops below the channel limit, if one is set."
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: src/language.cpp:44 modules/commands/ns_set.cpp:832
+#: modules/commands/ns_set.cpp:867
msgid "English"
msgstr "English"
@@ -4807,31 +4774,36 @@ msgstr ""
" CERT LIST\n"
" Displays the current certificate list."
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "Exception for %s (#%d) moved to position %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception for %s has been updated to %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/chanserv.cpp:460
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540 modules/commands/os_ignore.cpp:266
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/ns_group.cpp:315
+#: modules/commands/os_akill.cpp:355
msgid "Expires"
msgstr "Expires"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Expiry and reason updated for %s."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "Expiry for %s updated."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasy"
@@ -4859,16 +4831,16 @@ msgstr "Fingerprint %s already present on %s's certificate list."
msgid "Fingerprint %s is already in use."
msgstr "Fingerprint %s is already in use."
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr "Flags"
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Flags for %s on %s set to +%s"
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Flags list for %s"
@@ -4931,7 +4903,7 @@ msgstr "Forcefully part a user from a channel"
msgid "Forcefully part a user from a channel."
msgstr "Forcefully part a user from a channel."
-#: modules/commands/cs_info.cpp:47 modules/commands/ns_alist.cpp:64
+#: modules/commands/ns_alist.cpp:64 modules/commands/cs_info.cpp:47
msgid "Founder"
msgstr "Founder"
@@ -4944,7 +4916,7 @@ msgstr "Founder of %s changed to %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "GETPASS command unavailable because encryption is in use."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Ghost with your nick has been killed."
@@ -4952,7 +4924,7 @@ msgstr "Ghost with your nick has been killed."
msgid "Give Operflags to a certain user"
msgstr "Give Operflags to a certain user"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -4961,7 +4933,7 @@ msgstr ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Gives you or the specified nick %s status on a channel"
@@ -5036,25 +5008,20 @@ msgstr "I don't know who %s is."
msgid "I've never seen %s on this channel."
msgstr "I've never seen %s on this channel."
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-#, fuzzy
-msgid "INFO [type]"
+msgid "INFO type"
msgstr "INFO type"
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr "IP"
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, c-format
msgid "IP %s already exists for %s."
msgstr "IP %s already exists for %s."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, c-format
msgid "IP %s does not exist for %s."
msgstr "IP %s does not exist for %s."
@@ -5063,8 +5030,8 @@ msgstr "IP %s does not exist for %s."
msgid "Identify yourself with your password"
msgstr "Identify yourself with your password"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "If you do not change within %s, I will change your nick."
@@ -5077,11 +5044,11 @@ msgstr "Ignore list has been cleared."
msgid "Ignore list is empty."
msgstr "Ignore list is empty."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
msgid "Ignore list:"
msgstr "Ignore list:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
msgid "Immediate protection"
msgstr "Immediate protection"
@@ -5135,7 +5102,7 @@ msgid ""
msgstr ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr "Invalid passcode."
@@ -5152,7 +5119,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Invalid threshold value. It must be a valid integer greater than 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr "Invalid value for LIMIT. Must be numerical."
@@ -5169,16 +5136,16 @@ msgstr "Italics kicker"
msgid "Join a group"
msgstr "Join a group"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/cs_set.cpp:1358 modules/commands/ns_set.cpp:1294
msgid "Keep modes"
msgstr "Keep modes"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:582
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Keep modes for %s is now off."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:576
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Keep modes for %s is now on."
@@ -5196,7 +5163,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr "Kick a user from a channel"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr "Kicked %d/%d users matching %s from %s."
@@ -5205,7 +5172,7 @@ msgstr "Kicked %d/%d users matching %s from %s."
msgid "Kicks a specified nick from a channel"
msgstr "Kicks a specified nick from a channel"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
@@ -5234,12 +5201,12 @@ msgstr "LIMIT enforced on %s, %d users removed."
msgid "LIST threshold"
msgstr "LIST threshold"
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_sxline.cpp:420 modules/commands/os_sxline.cpp:653
+#: modules/commands/os_akill.cpp:382
msgid "LIST [mask | list | id]"
msgstr "LIST [mask | list | id]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr "LIST [mask | list]"
@@ -5252,15 +5219,10 @@ msgstr "LIST [nickname]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [text|num]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Language changed to English."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Successor for %s changed to %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5270,7 +5232,7 @@ msgstr "Last memo to %s has been cancelled."
msgid "Last quit message"
msgstr "Last quit message"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
msgid "Last seen"
msgstr "Last seen"
@@ -5278,11 +5240,11 @@ msgstr "Last seen"
msgid "Last seen address"
msgstr "Last seen address"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr "Last topic"
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
msgid "Last used"
msgstr "Last used"
@@ -5290,28 +5252,28 @@ msgstr "Last used"
msgid "Last usermask"
msgstr "Last usermask"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr "Level"
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Level for %s on channel %s changed to %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Level must be between %d and %d inclusive."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/os_dns.cpp:217
+#: modules/commands/os_dns.cpp:217 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552
msgid "Limit"
msgstr "Limit"
@@ -5323,7 +5285,7 @@ msgstr "List all registered nicknames that match a given pattern"
msgid "List channels you have access on"
msgstr "List channels you have access on"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr "List for mode %c is full."
@@ -5332,7 +5294,7 @@ msgstr "List for mode %c is full."
msgid "List loaded modules"
msgstr "List loaded modules"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr "List of entries matching %s:"
@@ -5663,7 +5625,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr "Looking for yourself, eh %s?"
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr "MOVE num position"
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5730,11 +5696,11 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr "Maintain the AutoKick list"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
msgid "Maintains network bot list"
msgstr "Maintains network bot list"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -5745,7 +5711,7 @@ msgstr ""
"on the %s list receive the following privileges:\n"
" "
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -5776,7 +5742,7 @@ msgstr ""
"will be added to the akick list instead of the mask.\n"
"All users within that nickgroup will then be akicked.\n"
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -5795,7 +5761,7 @@ msgstr ""
"a user level of 0, and any unregistered user has a user level\n"
"of -1."
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -5828,7 +5794,7 @@ msgstr ""
"be issued every time word is said by a user.\n"
" \n"
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
msgid "Maintains the bad words list"
msgstr "Maintains the bad words list"
@@ -5876,7 +5842,7 @@ msgstr ""
"option enabled, provided that you have the necessary\n"
"access on it."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
msgid "Manage DNS zones for this network"
msgstr "Manage DNS zones for this network"
@@ -5892,12 +5858,12 @@ msgstr "Manage the memo ignore list"
msgid "Manage your auto join list"
msgstr "Manage your auto join list"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, c-format
msgid "Manipulate the %s list"
msgstr "Manipulate the %s list"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "Manipulate the AKILL list"
@@ -5905,19 +5871,19 @@ msgstr "Manipulate the AKILL list"
msgid "Manipulate the DefCon system"
msgstr "Manipulate the DefCon system"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
msgid "Manipulate the topic of the specified channel"
msgstr "Manipulate the topic of the specified channel"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
+#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_ignore.cpp:266
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_forbid.cpp:346 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_list.cpp:147 modules/commands/bs_info.cpp:56
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
msgid "Mask"
msgstr "Mask"
@@ -5930,8 +5896,8 @@ msgstr "Mask %s already present on %s's access list."
msgid "Mask must be in the form user@host."
msgstr "Mask must be in the form user@host."
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_flags.cpp:122
+#: modules/commands/cs_xop.cpp:165
msgid "Masks and unregistered users may not be on access lists."
msgstr "Masks and unregistered users may not be on access lists."
@@ -5959,7 +5925,7 @@ msgstr "Memo %d from %s (%s)."
msgid "Memo %d has been deleted."
msgstr "Memo %d has been deleted."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
msgid "Memo ignore list is empty."
msgstr "Memo ignore list is empty."
@@ -5978,7 +5944,7 @@ msgstr "Memo limit for %s set to %d."
msgid "Memo limit for %s set to 0."
msgstr "Memo limit for %s set to 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo sent to %s."
@@ -5992,7 +5958,7 @@ msgstr "Memos for %s:"
msgid "Message"
msgstr "Message"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Message mode"
@@ -6000,25 +5966,25 @@ msgstr "Message mode"
msgid "Method"
msgstr "Method"
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr "Missing parameter for mode %c."
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr "Mode"
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Mode %s is not a status or list mode."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
msgid "Mode lock"
msgstr "Mode lock"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, c-format
msgid "Mode locks for %s:"
msgstr "Mode locks for %s:"
@@ -6027,11 +5993,6 @@ msgstr "Mode locks for %s:"
msgid "Modes"
msgstr "Modes"
-#: modules/commands/os_mode.cpp:44
-#, fuzzy, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr "%d channel(s) cleared, and %d channel(s) dropped."
-
#: modules/commands/ns_access.cpp:166
#, c-format
msgid ""
@@ -6095,7 +6056,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr "Modify the Services ignore list"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, c-format
msgid "Modify the list of %s users"
msgstr "Modify the list of %s users"
@@ -6104,7 +6065,7 @@ msgstr "Modify the list of %s users"
msgid "Modify the list of authorized addresses"
msgstr "Modify the list of authorized addresses"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
msgid "Modify the list of privileged users"
msgstr "Modify the list of privileged users"
@@ -6112,7 +6073,7 @@ msgstr "Modify the list of privileged users"
msgid "Modify the nickname client certificate list"
msgstr "Modify the nickname client certificate list"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
msgid "Modify the session-limit exception list"
msgstr "Modify the session-limit exception list"
@@ -6159,14 +6120,14 @@ msgstr "Module: %s Version: %s Author: %s Loaded: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module: %s [%s] [%s]"
-#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75 modules/commands/os_list.cpp:42
+#: modules/commands/os_list.cpp:147
msgid "Name"
msgstr "Name"
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr "Name Type"
@@ -6179,18 +6140,18 @@ msgstr "Network stats for %s:"
msgid "Never"
msgstr "Never"
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
-#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/bs_botlist.cpp:27
+#: modules/commands/hs_request.cpp:300 modules/commands/ns_list.cpp:75
+#: modules/commands/ns_group.cpp:315
msgid "Nick"
msgstr "Nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, c-format
msgid "Nick %s has been confirmed."
msgstr "Nick %s has been confirmed."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, c-format
msgid "Nick %s is already an operator."
msgstr "Nick %s is already an operator."
@@ -6205,7 +6166,6 @@ msgstr "Nick %s is already confirmed."
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s is an illegal nickname and cannot be used."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6221,7 +6181,7 @@ msgstr "Nick %s is forbidden by %s: %s"
msgid "Nick %s is forbidden."
msgstr "Nick %s is forbidden."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, c-format
msgid "Nick %s is not a Services Operator."
msgstr "Nick %s is not a Services Operator."
@@ -6246,12 +6206,12 @@ msgstr "Nick %s isn't registered."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s was truncated to %d characters."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s will expire."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s will not expire."
@@ -6316,17 +6276,17 @@ msgstr "Nickname %s is already registered!"
msgid "Nickname %s may not be registered."
msgstr "Nickname %s may not be registered."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Nickname %s registered under your user@host-mask: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, c-format
msgid "Nickname %s registered."
msgstr "Nickname %s registered."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
msgid "No auto-op"
msgstr "No auto-op"
@@ -6334,7 +6294,7 @@ msgstr "No auto-op"
msgid "No bot"
msgstr "No bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/cs_set.cpp:1356 modules/commands/ns_set.cpp:1292
msgid "No expire"
msgstr "No expire"
@@ -6362,13 +6322,13 @@ msgstr "No logon news items to delete!"
msgid "No matches for %s found."
msgstr "No matches for %s found."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, c-format
msgid "No matching entries on %s %s list."
msgstr "No matching entries on %s %s list."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_flags.cpp:334 modules/commands/cs_xop.cpp:432
#, c-format
msgid "No matching entries on %s access list."
msgstr "No matching entries on %s access list."
@@ -6378,21 +6338,21 @@ msgstr "No matching entries on %s access list."
msgid "No matching entries on %s autokick list."
msgstr "No matching entries on %s autokick list."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "No matching entries on %s bad words list."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "No matching entries on session-limit exception list."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, c-format
msgid "No matching entries on the %s list."
msgstr "No matching entries on the %s list."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "No matching entries on the AKILL list."
@@ -6404,7 +6364,12 @@ msgstr "No memo was cancelable."
msgid "No modules currently loaded matching that criteria."
msgstr "No modules currently loaded matching that criteria."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, c-format
+msgid "No nick registrations matching %s found."
+msgstr "No nick registrations matching %s found."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr "No one is using your nick, and services are not holding it."
@@ -6424,12 +6389,7 @@ msgstr "No random news items to delete!"
msgid "No records to display."
msgstr "No records to display."
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "No nick registrations matching %s found."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr "No request for nick %s found."
@@ -6438,8 +6398,8 @@ msgstr "No request for nick %s found."
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr "No signed kick when SIGNKICK LEVEL is used"
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, c-format
msgid "No stats for %s."
msgstr "No stats for %s."
@@ -6449,7 +6409,7 @@ msgstr "No stats for %s."
msgid "No such info \"%s\" on %s."
msgstr "No such info \"%s\" on %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, c-format
msgid "No users on %s match %s."
msgstr "No users on %s match %s."
@@ -6464,30 +6424,30 @@ msgstr "No-bot mode is now off on channel %s."
msgid "No-bot mode is now on on channel %s."
msgstr "No-bot mode is now on on channel %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr "Non-status modes cleared on %s."
-#: modules/commands/bs_info.cpp:59 modules/commands/os_dns.cpp:225
+#: modules/commands/os_dns.cpp:225 modules/commands/bs_info.cpp:59
msgid "None"
msgstr "None"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr "Nothing to do."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/hs_list.cpp:58 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_xop.cpp:381 modules/commands/ns_alist.cpp:48
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/ms_list.cpp:64
+#: modules/commands/bs_badwords.cpp:193 modules/commands/os_news.cpp:156
+#: modules/commands/hs_request.cpp:300 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_log.cpp:127
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/ns_ajoin.cpp:100
msgid "Number"
msgstr "Number"
@@ -6499,13 +6459,6 @@ msgstr "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgid "Online from"
msgstr "Online from"
-#: modules/commands/os_oper.cpp:139
-#, fuzzy, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr " This oper is configured in the configuration file."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr "Oper Info"
@@ -6529,12 +6482,12 @@ msgstr "Oper news item #%s not found!"
msgid "Oper news items:"
msgstr "Oper news items:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr "Oper privileges removed from %s (%s)."
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, c-format
msgid "Oper type %s has not been configured."
msgstr "Oper type %s has not been configured."
@@ -6549,17 +6502,17 @@ msgstr "Operflags %s have been added for %s."
msgid "Operflags %s have been removed from %s."
msgstr "Operflags %s have been removed from %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr "Opertype %s has no allowed commands."
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr "Opertype %s has no allowed privileges."
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr "Opertype %s receives modes %s once identified."
@@ -6568,15 +6521,15 @@ msgstr "Opertype %s receives modes %s once identified."
msgid "Ops protection"
msgstr "Ops protection"
-#: modules/commands/bs_info.cpp:59 src/misc.cpp:259
+#: src/misc.cpp:259 modules/commands/bs_info.cpp:59
msgid "Options"
msgstr "Options"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
msgid "POOL server.name"
msgstr "POOL server.name"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr "Param"
@@ -6592,12 +6545,12 @@ msgstr "Password accepted."
msgid "Password authentication required for that command."
msgstr "Password authentication required for that command."
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, c-format
msgid "Password for %s changed to %s."
msgstr "Password for %s changed to %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, c-format
msgid "Password for %s changed."
msgstr "Password for %s changed."
@@ -6616,7 +6569,7 @@ msgstr "Password incorrect."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Peace"
@@ -6630,7 +6583,7 @@ msgstr "Peace option for %s is now off."
msgid "Peace option for %s is now on."
msgstr "Peace option for %s is now on."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
msgid "Persistent"
msgstr "Persistent"
@@ -6663,12 +6616,12 @@ msgstr "Please use the symbol of # when attempting to register."
msgid "Please wait %d seconds and retry."
msgstr "Please wait %d seconds and retry."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Please wait %d seconds before requesting a new vHost."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Please wait %d seconds before using the %s command again."
@@ -6678,12 +6631,12 @@ msgstr "Please wait %d seconds before using the %s command again."
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Please wait %d seconds before using the GROUP command again."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr "Please wait %d seconds before using the REGISTER command again."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr "Pooled %s."
@@ -6696,7 +6649,7 @@ msgstr "Pooled/Active"
msgid "Pooled/Not Active"
msgstr "Pooled/Not Active"
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr "Prevent a bot from being assigned by non IRC operators"
@@ -6716,7 +6669,7 @@ msgstr "Prevent the channel from expiring"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Prevent the nickname from appearing in the LIST command"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
msgid "Prevent the nickname from expiring"
msgstr "Prevent the nickname from expiring"
@@ -6724,17 +6677,17 @@ msgstr "Prevent the nickname from expiring"
msgid "Prevents users being kicked by Services"
msgstr "Prevents users being kicked by Services"
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/ns_list.cpp:297 modules/commands/cs_list.cpp:262
+#: modules/commands/bs_info.cpp:59
msgid "Private"
msgstr "Private"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, c-format
msgid "Private mode of bot %s is now off."
msgstr "Private mode of bot %s is now off."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, c-format
msgid "Private mode of bot %s is now on."
msgstr "Private mode of bot %s is now on."
@@ -6759,36 +6712,36 @@ msgstr "Private option is now off for %s."
msgid "Private option is now on for %s."
msgstr "Private option is now on for %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr "Privilege %s added to %s on %s, new flags are +%s"
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Privilege %s removed from %s on %s, new flags are +%s"
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Protection"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, c-format
msgid "Protection is now off for %s."
msgstr "Protection is now off for %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Protection is now on for %s, with a reduced delay."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Protection is now on for %s, with no delay."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, c-format
msgid "Protection is now on for %s."
msgstr "Protection is now on for %s."
@@ -6803,7 +6756,7 @@ msgstr ""
"uses the entire real ident@host for every nick, and\n"
"then enforces the AKILL."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
msgid "Quick protection"
msgstr "Quick protection"
@@ -6845,20 +6798,20 @@ msgstr "Read a memo or memos"
msgid "Real name"
msgstr "Real name"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_ignore.cpp:266 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355
msgid "Reason"
msgstr "Reason"
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, c-format
msgid "Reason for %s updated."
msgstr "Reason for %s updated."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -6874,21 +6827,21 @@ msgstr ""
"GHOST command). If they are not identified they will be\n"
"forced off of the nick."
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
msgid "Redefine the meanings of access levels"
msgstr "Redefine the meanings of access levels"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
msgid "Regains control of your nick"
msgstr "Regains control of your nick"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_sxline.cpp:324 modules/commands/os_sxline.cpp:538
+#: modules/commands/os_akill.cpp:129
msgid "Regex is disabled."
msgstr "Regex is disabled."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_sxline.cpp:452 modules/commands/os_sxline.cpp:684
+#: modules/commands/os_akill.cpp:438
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6897,9 +6850,9 @@ msgstr ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
+#: modules/commands/os_ignore.cpp:386 modules/commands/os_forbid.cpp:416
+#: modules/commands/ns_list.cpp:172 modules/commands/cs_list.cpp:167
#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6912,7 +6865,7 @@ msgstr ""
msgid "Register a channel"
msgstr "Register a channel"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
msgid "Register a nickname"
msgstr "Register a nickname"
@@ -6967,7 +6920,7 @@ msgstr ""
"%s will also automatically give the founder\n"
"channel-operator privileges when s/he enters the channel."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7006,7 +6959,7 @@ msgstr ""
"you should choose a password at least 5 characters long.\n"
"Finally, the space character cannot be used in passwords."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
msgid "Registration is currently disabled."
msgstr "Registration is currently disabled."
@@ -7014,11 +6967,11 @@ msgstr "Registration is currently disabled."
msgid "Regulate the use of critical commands"
msgstr "Regulate the use of critical commands"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
msgid "Reject the requested vHost for the given nick."
msgstr "Reject the requested vHost for the given nick."
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
msgid "Reject the requested vHost of a user"
msgstr "Reject the requested vHost of a user"
@@ -7054,22 +7007,22 @@ msgstr "Remove all bans preventing a user from entering a channel"
msgid "Remove all operators from a server remotely"
msgstr "Remove all operators from a server remotely"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, c-format
msgid "Removed IP %s from %s."
msgstr "Removed IP %s from %s."
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr "Removed server %s from zone %s."
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr "Removed server %s."
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7078,7 +7031,7 @@ msgstr ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Removes %s status from you or the specified nick on a channel"
@@ -7088,17 +7041,16 @@ msgid "Removes a selected nicks status from a channel"
msgstr "Removes a selected nicks status from a channel"
#: modules/commands/cs_updown.cpp:223
-#, fuzzy
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
"Removes a selected nicks status modes on a channel. If nick is\n"
"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr "Removing %s because %s covers it."
@@ -7112,7 +7064,7 @@ msgstr "Repeat kicker"
msgid "Request a vHost for your nick"
msgstr "Request a vHost for your nick"
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
"Request the given vHost to be activated for your nick by the\n"
"network administrators. Please be patient while your request\n"
@@ -7122,7 +7074,7 @@ msgstr ""
"network administrators. Please be patient while your request\n"
"is being considered."
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
msgid "Resend registration confirmation email"
msgstr "Resend registration confirmation email"
@@ -7130,7 +7082,7 @@ msgstr "Resend registration confirmation email"
msgid "Restrict access to the channel"
msgstr "Restrict access to the channel"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
msgid "Restricted access"
msgstr "Restricted access"
@@ -7161,7 +7113,7 @@ msgstr "Retain topic when channel is not in use"
msgid "Retrieve the password for a nickname"
msgstr "Retrieve the password for a nickname"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr "Retrieves the vhost requests"
@@ -7174,9 +7126,16 @@ msgid "Returns the key of the given channel."
msgstr "Returns the key of the given channel."
#: modules/commands/ns_getemail.cpp:58
-#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr "Returns the key of the given channel."
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7243,16 +7202,16 @@ msgstr "Reverses the effect of the IDENTIFY command"
msgid "SET server"
msgstr "SET server"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr "SET server.name option value"
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "SSL certificate fingerprint accepted, you are now identified to %s."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "SSL certificate fingerprint accepted, you are now identified."
@@ -7273,7 +7232,7 @@ msgstr "Save databases and restart Services"
msgid "Searches logs for a matching pattern"
msgstr "Searches logs for a matching pattern"
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
msgid "Secure founder"
msgstr "Secure founder"
@@ -7287,7 +7246,7 @@ msgstr "Secure founder option for %s is now off."
msgid "Secure founder option for %s is now on."
msgstr "Secure founder option for %s is now on."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
msgid "Secure ops"
msgstr "Secure ops"
@@ -7311,12 +7270,12 @@ msgstr "Secure option for %s is now off."
msgid "Secure option for %s is now on."
msgstr "Secure option for %s is now on."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, c-format
msgid "Secure option is now off for %s."
msgstr "Secure option is now off for %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, c-format
msgid "Secure option is now on for %s."
msgstr "Secure option is now on for %s."
@@ -7326,11 +7285,11 @@ msgstr "Secure option is now on for %s."
msgid "Secureops enforced on %s."
msgstr "Secureops enforced on %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/cs_set.cpp:1346 modules/commands/ns_set.cpp:1286
msgid "Security"
msgstr "Security"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:574
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7339,7 +7298,7 @@ msgstr ""
"See %s%s HELP %s for more information\n"
"about the access list."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:577
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7390,7 +7349,7 @@ msgstr "Sends all registered users a memo containing memo-text."
msgid "Sends all services staff a memo containing memo-text."
msgstr "Sends all services staff a memo containing memo-text."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
msgid ""
"Sends the named nick or channel a memo containing\n"
"memo-text. When sending to a nickname, the recipient will\n"
@@ -7455,14 +7414,14 @@ msgid "Server %s already exists."
msgstr "Server %s already exists."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, c-format
msgid "Server %s does not exist."
msgstr "Server %s does not exist."
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, c-format
msgid "Server %s has no configured IPs."
msgstr "Server %s has no configured IPs."
@@ -7472,12 +7431,12 @@ msgstr "Server %s has no configured IPs."
msgid "Server %s is already in zone %s."
msgstr "Server %s is already in zone %s."
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, c-format
msgid "Server %s is already pooled."
msgstr "Server %s is already pooled."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, c-format
msgid "Server %s is not currently linked."
msgstr "Server %s is not currently linked."
@@ -7492,12 +7451,12 @@ msgstr "Server %s is not in zone %s."
msgid "Server %s is not linked to the network."
msgstr "Server %s is not linked to the network."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, c-format
msgid "Server %s is not pooled."
msgstr "Server %s is not pooled."
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr "Server %s must be quit before it can be deleted."
@@ -7515,18 +7474,17 @@ msgstr "Servers found: %d"
msgid "Service"
msgstr "Service"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, c-format
msgid "Service's hold on %s has been released."
msgstr "Service's hold on %s has been released."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
msgid "Services Operator commands"
msgstr "Services Operator commands"
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
msgid "Services are in DefCon mode, please try again later."
msgstr "Services are in DefCon mode, please try again later."
@@ -7576,7 +7534,7 @@ msgstr "Services have been configured to not send mail."
msgid "Services ignore list:"
msgstr "Services ignore list:"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:38
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
"correctly?"
@@ -7589,7 +7547,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Services up %s."
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services will from now on set status modes on %s in channels."
@@ -7599,7 +7557,7 @@ msgstr "Services will from now on set status modes on %s in channels."
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Services will no longer automatically give modes to users in %s."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services will no longer set status modes on %s in channels."
@@ -7609,12 +7567,12 @@ msgstr "Services will no longer set status modes on %s in channels."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services will now automatically give modes to users in %s."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services will now reply to %s with messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services will now reply to %s with notices."
@@ -7632,7 +7590,7 @@ msgstr "Session"
msgid "Session limit for %s set to %d."
msgstr "Session limit for %s set to %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Session limiting is disabled."
@@ -7669,7 +7627,7 @@ msgstr "Set the channel as permanent"
msgid "Set the channel description"
msgstr "Set the channel description"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
msgid "Set the display of your group in Services"
msgstr "Set the display of your group in Services"
@@ -7677,11 +7635,11 @@ msgstr "Set the display of your group in Services"
msgid "Set the founder of a channel"
msgstr "Set the founder of a channel"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
msgid "Set the language Services will use when messaging you"
msgstr "Set the language Services will use when messaging you"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
msgid "Set the nickname password"
msgstr "Set the nickname password"
@@ -7999,7 +7957,7 @@ msgstr ""
msgid "Sets various nickname options. option can be one of:"
msgstr "Sets various nickname options. option can be one of:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8013,7 +7971,7 @@ msgstr ""
"Sets whether the given channel will expire. Setting this\n"
"to ON prevents the channel from expiring."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8028,7 +7986,7 @@ msgstr ""
"is entering channels. Note that depending on channel settings\n"
"some modes may not get set automatically."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8036,7 +7994,7 @@ msgstr ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8049,7 +8007,7 @@ msgstr ""
"when entering channels. Note that depending on channel settings some modes\n"
"may not get set automatically."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8108,11 +8066,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Signed kick option for %s is now on."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Signed kicks"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "Sorry, %s currently has too many memos and cannot receive more."
@@ -8122,7 +8080,7 @@ msgstr "Sorry, %s currently has too many memos and cannot receive more."
msgid "Sorry, I have not seen %s."
msgstr "Sorry, I have not seen %s."
-#: modules/commands/bs_badwords.cpp:404
+#: modules/commands/bs_badwords.cpp:403
msgid "Sorry, bad words list modification is temporarily disabled."
msgstr "Sorry, bad words list modification is temporarily disabled."
@@ -8130,30 +8088,30 @@ msgstr "Sorry, bad words list modification is temporarily disabled."
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Sorry, bot assignment is temporarily disabled."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Sorry, bot modification is temporarily disabled."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Sorry, bot option setting is temporarily disabled."
-#: modules/commands/bs_set.cpp:112
+#: modules/commands/bs_set.cpp:103
msgid "Sorry, changing bot options is temporarily disabled."
msgstr "Sorry, changing bot options is temporarily disabled."
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Sorry, channel %s list modification is temporarily disabled."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Sorry, channel access list modification is temporarily disabled."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Sorry, channel autokick list modification is temporarily disabled."
@@ -8185,7 +8143,7 @@ msgstr "Sorry, nickname de-registration is temporarily disabled."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Sorry, nickname grouping is temporarily disabled."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Sorry, nickname registration is temporarily disabled."
@@ -8204,13 +8162,8 @@ msgstr "Sorry, the maximum of %d auto join entries has been reached."
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Sorry, the maximum of %d certificate entries has been reached."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "The oper info list for %s is full."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_flags.cpp:173
+#: modules/commands/cs_xop.cpp:201
#, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8224,7 +8177,7 @@ msgstr ""
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Sorry, you can only have %d autokick masks on a channel."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Sorry, you can only have %d bad words entries on a channel."
@@ -8271,7 +8224,7 @@ msgstr "Stricter control of channel founder status"
msgid "Stricter control of chanop status"
msgstr "Stricter control of chanop status"
-#: modules/commands/cs_info.cpp:50 modules/commands/ns_alist.cpp:75
+#: modules/commands/ns_alist.cpp:75 modules/commands/cs_info.cpp:50
msgid "Successor"
msgstr "Successor"
@@ -8487,7 +8440,6 @@ msgstr ""
"--noexpire."
#: modules/commands/ms_set.cpp:246
-#, fuzzy
msgid ""
"Syntax: NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\n"
" \n"
@@ -8500,7 +8452,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -8575,7 +8527,7 @@ msgstr ""
"This option is not persistent, and should only be used when\n"
"needed, and set back to OFF when no longer needed."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -8660,7 +8612,7 @@ msgstr "Terminate services with save"
msgid "Text"
msgstr "Text"
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -8678,7 +8630,7 @@ msgstr ""
"When a user joins the channel the access they receive is from the\n"
"highest level entry in the access list."
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -8692,7 +8644,7 @@ msgstr ""
"You may remove yourself from an access list, even if you\n"
"do not have access to modify that list otherwise."
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -8722,7 +8674,7 @@ msgstr ""
"The ACCESS CLEAR command clears all entries of the\n"
"access list."
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
"The CLEAR command clears the channel access list. This requires channel "
"founder access."
@@ -8749,7 +8701,7 @@ msgstr ""
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
msgid ""
"The DEL command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
@@ -8821,11 +8773,11 @@ msgstr ""
"The ENTRYMSG LIST command displays a listing of messages\n"
"shown to users when they join the channel."
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "The IMMED option is not available on this network."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -8868,7 +8820,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -8886,7 +8838,7 @@ msgstr ""
"given, only those\n"
"on the access list with the specified flags are returned."
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
"The MODIFY command allows you to modify the access list. If the mask is\n"
"not already on the access list it is added, then the changes are applied.\n"
@@ -8916,7 +8868,7 @@ msgid ""
msgstr ""
"The STATS command prints out statistics about stored nicks and memory usage."
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -8978,12 +8930,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "The %s list for %s is full."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, c-format
msgid "The %s list has been cleared."
msgstr "The %s list has been cleared."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "The AKILL list has been cleared."
@@ -9002,7 +8954,7 @@ msgstr "The E-mail address of %s will now be hidden from %s INFO displays."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "The E-mail address of %s will now be shown in %s INFO displays."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr "The available flags are:"
@@ -9031,11 +8983,11 @@ msgstr "The email address %s has reached its usage limit of 1 user."
msgid "The entry message list for %s is full."
msgstr "The entry message list for %s is full."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr "The following feature/function names are available:"
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9100,12 +9052,7 @@ msgstr "The mask must contain at least one non wildcard character."
msgid "The memo limit for %s may not be changed."
msgstr "The memo limit for %s may not be changed."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "The oper info list for %s is full."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr "The new display MUST be a nickname of the nickname group %s."
@@ -9120,7 +9067,7 @@ msgstr "The new display is now %s."
msgid "The nick %s is now being changed to %s."
msgstr "The nick %s is now being changed to %s."
-#: modules/commands/bs_bot.cpp:149
+#: modules/commands/bs_bot.cpp:142
msgid "The old information is the same as the new information specified."
msgstr "The old information is the same as the new information specified."
@@ -9147,11 +9094,11 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"The services access status of %s will now be shown in %s INFO displays."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
msgid "The session exception list is empty."
msgstr "The session exception list is empty."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9226,7 +9173,7 @@ msgstr "There is no random news."
msgid "There is no such configuration block %s."
msgstr "There is no such configuration block %s."
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, c-format
msgid "There is no such mode %s."
msgstr "There is no such mode %s."
@@ -9252,7 +9199,7 @@ msgstr "This channel is suspended."
msgid "This channel may not be used."
msgstr "This channel may not be used."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9306,7 +9253,7 @@ msgstr ""
"CURRENT nick to be the vhost for all nicks in the same\n"
"group."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9323,7 +9270,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr "This command is an alias to the command %s."
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
msgid ""
"This command is used by several commands as a way to confirm\n"
"changes made to your account.\n"
@@ -9441,7 +9388,7 @@ msgstr ""
"Services Operators may provide a nick to modify other users'\n"
"auto join lists."
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9453,7 +9400,7 @@ msgstr ""
msgid "This command reloads the module named modname."
msgstr "This command reloads the module named modname."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr "This command retrieves the vhost requests."
@@ -9515,7 +9462,7 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "This command unloads the module named modname."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr "This command will resend you the registration confirmation email."
@@ -9533,12 +9480,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "This nickname has been forbidden: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "This nickname has been recovered by %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -9601,7 +9548,7 @@ msgstr "Top %i of %s"
msgid "Topic"
msgstr "Topic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
msgid "Topic lock"
msgstr "Topic lock"
@@ -9615,7 +9562,7 @@ msgstr "Topic lock option for %s is now off."
msgid "Topic lock option for %s is now on."
msgstr "Topic lock option for %s is now on."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
msgid "Topic retention"
msgstr "Topic retention"
@@ -9629,7 +9576,7 @@ msgstr "Topic retention option for %s is now off."
msgid "Topic retention option for %s is now on."
msgstr "Topic retention option for %s is now on."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr "Topic set by"
@@ -9637,15 +9584,16 @@ msgstr "Topic set by"
msgid "Turn caps lock OFF!"
msgstr "Turn caps lock OFF!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
msgid "Turn chanstats statistics on or off"
msgstr "Turn chanstats statistics on or off"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
msgid "Turn nickname security on or off"
msgstr "Turn nickname security on or off"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
msgid "Turn protection on or off"
msgstr "Turn protection on or off"
@@ -9679,7 +9627,7 @@ msgstr ""
"(However, anyone who knows your nickname can still get\n"
"information on it using the INFO command.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9706,7 +9654,7 @@ msgstr "Turns Chanstats statistics ON or OFF."
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr "Turns chanstats channel statistics ON or OFF for this user."
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9735,7 +9683,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -9764,7 +9712,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/bs_badwords.cpp:193 modules/commands/os_forbid.cpp:346
msgid "Type"
msgstr "Type"
@@ -9803,7 +9751,7 @@ msgstr ""
"on a specific option. The options will be set on the given\n"
"nickname."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -9812,7 +9760,7 @@ msgstr ""
"Type %s%s HELP %s option for more information on a\n"
"particular option."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -9827,8 +9775,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Un-Load a module"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_sxline.cpp:331 modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:136
#, c-format
msgid "Unable to find regex engine %s."
msgstr "Unable to find regex engine %s."
@@ -9867,7 +9815,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Underlines kicker"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
msgid "Unknown SET option."
msgstr "Unknown SET option."
@@ -9886,7 +9834,7 @@ msgstr "Unknown command %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Unknown command %s. \"%s%s HELP\" for help."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "Unknown mode character %c ignored."
@@ -9925,10 +9873,9 @@ msgid "Unsuspends a nickname which allows it to be used again."
msgstr "Unsuspends a nickname which allows it to be used again."
#: modules/commands/cs_updown.cpp:126
-#, fuzzy
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
"Updates a selected nicks status modes on a channel. If nick is\n"
@@ -9976,28 +9923,28 @@ msgstr "Use the %s ALL command to list all commands and their descriptions."
msgid "Used on"
msgstr "Used on"
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
msgid "Used to manage channels"
msgstr "Used to manage channels"
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
msgid "Used to manage the list of privileged users"
msgstr "Used to manage the list of privileged users"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr "Used to modify the channel status of you or other users"
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
msgid "User has been banned from the channel"
msgstr "User has been banned from the channel"
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, c-format
msgid "User limit for %s removed."
msgstr "User limit for %s removed."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, c-format
msgid "User limit for %s set to %d."
msgstr "User limit for %s set to %d."
@@ -10048,12 +9995,12 @@ msgstr "VHost for group %s set to %s@%s."
msgid "VIEW host"
msgstr "VIEW host"
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_sxline.cpp:421 modules/commands/os_sxline.cpp:654
+#: modules/commands/os_akill.cpp:383
msgid "VIEW [mask | list | id]"
msgstr "VIEW [mask | list | id]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr "VIEW [mask | list]"
@@ -10066,7 +10013,7 @@ msgstr "Value"
msgid "Value of %s:%s changed to %s"
msgstr "Value of %s:%s changed to %s"
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr "Vhost"
@@ -10104,7 +10051,7 @@ msgstr ""
"When private is set, the channel will not appear in\n"
"%s's %s command."
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
msgid ""
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
@@ -10184,7 +10131,7 @@ msgstr ""
" \n"
"The ALL option displays all of the above statistics."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr "Word"
@@ -10193,7 +10140,7 @@ msgstr "Word"
msgid "You are already a member of the group of %s."
msgstr "You are already a member of the group of %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "You are already identified."
@@ -10252,7 +10199,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr "You can not NOOP Services."
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10277,13 +10224,13 @@ msgstr "You can not reload this module directly, instead reload %s."
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "You can not request a receipt when sending a memo to yourself."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/ns_recover.cpp:143
#, c-format
msgid "You can't %s yourself!"
msgstr "You can't %s yourself!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_flags.cpp:111
+#: modules/commands/cs_xop.cpp:154
msgid "You can't add a channel to its own access list."
msgstr "You can't add a channel to its own access list."
@@ -10292,12 +10239,12 @@ msgstr "You can't add a channel to its own access list."
msgid "You can't logout %s, they are a Services Operator."
msgstr "You can't logout %s, they are a Services Operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, c-format
msgid "You cannot %s on this network."
msgstr "You cannot %s on this network."
-#: modules/commands/cs_flags.cpp:231
+#: modules/commands/cs_flags.cpp:230
#, c-format
msgid "You cannot set the %c flag."
msgstr "You cannot set the %c flag."
@@ -10316,7 +10263,7 @@ msgstr "You cannot set your memo limit higher than %d."
msgid "You cannot unassign bots while persist is set on the channel."
msgstr "You cannot unassign bots while persist is set on the channel."
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "You cannot unset the e-mail on this network."
@@ -10356,12 +10303,12 @@ msgstr "You currently have 1 memo."
msgid "You currently have no memos."
msgstr "You currently have no memos."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr "You do not have access to set mode %c."
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "You do not have the access to change %s's modes."
@@ -10399,7 +10346,7 @@ msgstr "You have been invited to %s by %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "You have been logged in as %s."
@@ -10439,29 +10386,24 @@ msgstr ""
"You have reached your maximum number of memos (%d). You will be unable to "
"receive any new memos until you delete some of your current ones."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
msgid "You may drop any nick within your group."
msgstr "You may drop any nick within your group."
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr "You may not (un)lock mode %c."
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
msgid "You may not change the e-mail of other Services Operators."
msgstr "You may not change the e-mail of other Services Operators."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
msgid "You may not change the email of an unconfirmed account."
msgstr "You may not change the email of an unconfirmed account."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
msgid "You may not change the password of other Services Operators."
msgstr "You may not change the password of other Services Operators."
@@ -10511,16 +10453,6 @@ msgstr "You must be in %s to use this command."
msgid "You must confirm your account before you can register a channel."
msgstr "You must confirm your account before you can register a channel."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "You must confirm your account before you can register a channel."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "You must confirm your account before you can register a channel."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -10530,18 +10462,18 @@ msgstr ""
"You must enter the channel name twice as a confirmation that you wish to drop"
" %s."
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"You must have been using this nick for at least %d seconds to register."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You must have the %s(ME) privilege on the channel to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -10555,33 +10487,15 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "You will be notified when new memos arrive."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr "You will be notified of new memos at logon and when they arrive."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr "You will be notified of new memos at logon and when they arrive."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr "You will be notified of new memos at logon and when they arrive."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "You will be notified of new memos at logon."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "You will be notified when new memos arrive."
@@ -10593,7 +10507,7 @@ msgstr "You will no longer be able to receive memos."
msgid "You will no longer be informed via email."
msgstr "You will no longer be informed via email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "You will not be notified of new memos."
@@ -10621,22 +10535,22 @@ msgstr ""
"Your IRCd does not support vIdent's, if this is incorrect, please report "
"this as a possible bug"
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Your account %s has been successfully created."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
msgid "Your account is already confirmed."
msgstr "Your account is already confirmed."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Your account will expire, if not confirmed, in %s."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Your email address has been changed to %s."
@@ -10645,7 +10559,7 @@ msgstr "Your email address has been changed to %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Your email address is not allowed, choose a different one."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
@@ -10653,12 +10567,12 @@ msgstr ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Your email address of %s has been confirmed."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, c-format
msgid "Your email has been updated to %s"
msgstr "Your email has been updated to %s"
@@ -10715,7 +10629,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Your nick isn't registered."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Your nickname is now being changed to %s"
@@ -10724,42 +10638,41 @@ msgstr "Your nickname is now being changed to %s"
msgid "Your oper block doesn't require logging in."
msgstr "Your oper block doesn't require logging in."
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Your passcode has been re-sent to %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Your password is %s - remember this for later use."
#: include/language.h:77
-#, fuzzy, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr "Your password is too long. Please try again with a shorter password."
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
msgid "Your vHost has been requested."
msgstr "Your vHost has been requested."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Your vhost of %s is now activated."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Your vhost of %s@%s is now activated."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -10854,8 +10767,8 @@ msgstr "[nick]"
msgid "[nickname [REVALIDATE]]"
msgstr "[nickname [REVALIDATE]]"
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_alist.cpp:25 modules/commands/ns_status.cpp:20
+#: modules/commands/ns_info.cpp:20
msgid "[nickname]"
msgstr "[nickname]"
@@ -10875,7 +10788,7 @@ msgstr "[+expiry] channel reason"
msgid "[Hostname hidden]"
msgstr "[Hostname hidden]"
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr "[Suspended]"
@@ -10883,20 +10796,20 @@ msgstr "[Suspended]"
msgid "[Unconfirmed]"
msgstr "[Unconfirmed]"
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto memo] Your requested vHost has been approved."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto memo] Your requested vHost has been rejected."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[auto memo] Your requested vHost has been rejected. Reason: %s"
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] vHost %s has been requested by %s."
@@ -10998,12 +10911,12 @@ msgstr "second"
msgid "seconds"
msgstr "seconds"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, c-format
msgid "vHost for %s has been activated."
msgstr "vHost for %s has been activated."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, c-format
msgid "vHost for %s has been rejected."
msgstr "vHost for %s has been rejected."
@@ -11037,23 +10950,6 @@ msgstr "{channel | nickname}"
msgid "{nick | channel}"
msgstr "{nick | channel}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
msgid "{nick | channel} memo-text"
msgstr "{nick | channel} memo-text"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "Exception for %s (#%d) moved to position %d."
-
-#~ msgid "MOVE num position"
-#~ msgstr "MOVE num position"
-
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
diff --git a/language/anope.es_ES.po b/language/anope.es_ES.po
index 5bd76e97c..17a0eb187 100644
--- a/language/anope.es_ES.po
+++ b/language/anope.es_ES.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2014-02-24 20:45+0100\n"
"Last-Translator: Isaac Fontal <i_fontal@hotmail.com>\n"
"Language-Team: Spanish\n"
@@ -29,17 +29,17 @@ msgstr "%d canale(s) limpiado(s), y %d canale(s) borrado(s)."
msgid "%d nickname(s) dropped."
msgstr "%d nick(s) borrado(s)."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, c-format
msgid "%s added to %s %s list."
msgstr "%s añadido a la lista de %s de %s."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s añadido a la lista de acceso de %s con nivel %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s añadido a la lista de acceso de %s con privilegios de %s (nivel %d)"
@@ -49,7 +49,7 @@ msgstr "%s añadido a la lista de acceso de %s con privilegios de %s (nivel %d
msgid "%s added to %s autokick list."
msgstr "%s añadido a la lista de kicks automaticos en el canal %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s añadido a la lista de bad words de %s."
@@ -64,17 +64,17 @@ msgstr "%s añadido a la lista de acceso de %s."
msgid "%s added to %s's certificate list."
msgstr "%s añadido a la lista de certificados de %s."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, c-format
msgid "%s added to ignore list."
msgstr "%s añadido a la lista de ignorados."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s añadido a la lista %s."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s añadido a la lista de AKILLs."
@@ -116,7 +116,7 @@ msgstr ""
"información sobre un comando específico, escribe\n"
"%s%s %s comando.\n"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -133,7 +133,7 @@ msgstr ""
"Para más información acerca de un comando específico,\n"
"escribe %s%s %s comando.\n"
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -148,7 +148,7 @@ msgstr ""
"Para más información acerca de un comando específico,\n"
"escribe %s%s %s comando.\n"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -168,7 +168,7 @@ msgstr ""
"información acerca de un comando específico, escribe\n"
"%s%s HELP comando.\n"
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s ya existe en la lista de bad words de %s."
@@ -189,7 +189,7 @@ msgstr "%s ya existe en la lista de EXCEPCIONES."
msgid "%s cannot be taken as times to ban."
msgstr "%s no es válido como veces para banear."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s cambió tus modos de usuario a %s."
@@ -199,12 +199,12 @@ msgstr "%s cambió tus modos de usuario a %s."
msgid "%s channel list:"
msgstr "Lista de canales de %s."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, c-format
msgid "%s deleted from %s %s list."
msgstr "%s borrado de la lista de %s de %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s borrado de la lista de acceso de %s."
@@ -214,7 +214,7 @@ msgstr "%s borrado de la lista de acceso de %s."
msgid "%s deleted from %s autokick list."
msgstr "%s borrado de la lista de kicks automáticos del canal %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s borrado de la lista de bad words de %s."
@@ -239,12 +239,12 @@ msgstr "%s borrado de la lista de excepciones al limite de sesiones."
msgid "%s deleted from the %s list."
msgstr "%s borrado de la lista %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s borrado de la lista de AKILLs."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s deshabilitado en el canal %s."
@@ -316,7 +316,7 @@ msgstr "¡%s ya está en %s!"
msgid "%s is already in %s."
msgstr "%s ya está en %s."
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, c-format
msgid "%s is already on the ignore list."
msgstr "%s ya está en la lista de ignorados."
@@ -326,7 +326,7 @@ msgstr "%s ya está en la lista de ignorados."
msgid "%s is already suspended."
msgstr "%s ya está suspendido."
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s no es un nick o canal registrado."
@@ -356,7 +356,7 @@ msgstr "%s no está actualmente en el canal %s."
msgid "%s is not in %s."
msgstr "%s no está en %s."
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, c-format
msgid "%s is not on the ignore list."
msgstr "%s no está en la lista de ignorados."
@@ -391,12 +391,12 @@ msgid "%s matches auto kick entry %s on %s (%s)."
msgstr ""
"%s concuerda con la entrada %s de la lista de kicks automáticos en %s (%s)."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, c-format
msgid "%s not found on %s %s list."
msgstr "%s no encontrado en la lista de %s de %s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s no encontrado en la lista de acceso de %s."
@@ -406,7 +406,7 @@ msgstr "%s no encontrado en la lista de acceso de %s."
msgid "%s not found on %s autokick list."
msgstr "%s no encontrado en la lista de kicks automáticos en el canal %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s no encontrado en la lista de bad words de %s."
@@ -445,17 +445,17 @@ msgstr "%s no encontrado en la lista de excepciones al límite de sesiones."
msgid "%s not found on the %s list."
msgstr "%s no encontrado en la lista %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s no encontrado en la lista de AKILLs."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "%s borrado de la lista de acceso de %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, c-format
msgid "%s removed from the ignore list."
msgstr "%s borrado de tu lista de ignorados."
@@ -485,20 +485,19 @@ msgstr "%s será ignorado permanentemente."
msgid "%s%s HELP %s for more information."
msgstr "%s%s HELP %s para más información."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr "ADD nick usuario host nom-real"
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr "CHANGE viejo-nick nuevo-nick [usuario [host [nombre-real]]]"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL nick"
-#: modules/commands/os_session.cpp:560
-#, fuzzy
+#: modules/commands/os_session.cpp:601
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
"Note that nick!user@host and user@host masks are invalid!\n"
@@ -512,6 +511,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -559,7 +561,7 @@ msgstr ""
"dado y evita que adquieran estado de operadores.\n"
"REVOKE elimina esta restricción."
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -580,17 +582,17 @@ msgstr "[auto-memo] El memo que enviaste a %s ha sido leido."
msgid "[target] [password]"
msgstr "objetivo contraseña"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr "dirección"
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
msgid "botname {ON|OFF}"
msgstr "nombre-de-bot {ON|OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
msgid "channel"
@@ -625,7 +627,7 @@ msgstr "canal nick"
msgid "channel nick [reason]"
msgstr "canal nick [razón]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr "canal objetivo [que]"
@@ -633,7 +635,7 @@ msgstr "canal objetivo [que]"
msgid "channel text"
msgstr "canal texto"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
msgid "channel time"
msgstr "canal tiempo"
@@ -645,11 +647,11 @@ msgstr "canal usuario razón"
msgid "channel what"
msgstr "canal que"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
msgid "channel ADD mask"
msgstr "canal ADD máscara"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr "canal ADD máscara nivel"
@@ -657,7 +659,7 @@ msgstr "canal ADD máscara nivel"
msgid "channel ADD message"
msgstr "canal ADD mensaje"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr "canal ADD palabra [SINGLE | START | END]"
@@ -665,17 +667,17 @@ msgstr "canal ADD palabra [SINGLE | START | END]"
msgid "channel ADD {nick | mask} [reason]"
msgstr "canal ADD {nick | máscara} [razón]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
msgid "channel APPEND topic"
msgstr "canal APPEND topic"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
msgid "channel CLEAR"
msgstr "canal CLEAR"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
msgid "channel CLEAR [what]"
msgstr "canal CLEAR [que]"
@@ -687,7 +689,7 @@ msgstr "canal CLEAR [ALL]"
msgid "channel DEL num"
msgstr "canal DEL num"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
msgid "channel DEL {mask | entry-num | list}"
msgstr "canal DEL {máscara | num-entrada | lista}"
@@ -695,7 +697,7 @@ msgstr "canal DEL {máscara | num-entrada | lista}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "canal DEL {nick | máscara | num-entrada | lista}"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
msgid "channel DEL {word | entry-num | list}"
msgstr "canal DEL {palabra | num-entrada | lista}"
@@ -703,7 +705,7 @@ msgstr "canal DEL {palabra | num-entrada | lista}"
msgid "channel ENFORCE"
msgstr "canal ENFORCE"
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr "canal LIST"
@@ -711,36 +713,44 @@ msgstr "canal LIST"
msgid "channel LIST [mask | entry-num | list]"
msgstr "canal LIST [máscara | num-entrada | lista]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
msgid "channel LIST [mask | list]"
msgstr "canal LIST [máscara | lista]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr "canal LIST [máscara | +marcas]"
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "canal LOCK {ADD|DEL|SET|LIST} [que]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr "canal MODIFY máscara cambios"
+
+#: modules/commands/cs_access.cpp:738
msgid "channel RESET"
msgstr "canal RESET"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
msgid "channel SET modes"
msgstr "canal SET modos"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr "canal SET tipo nivel"
+#: modules/commands/cs_topic.cpp:157
+msgid "channel SET [topic]"
+msgstr "canal SET [topic]"
+
#: modules/commands/cs_akick.cpp:426
msgid "channel VIEW [mask | entry-num | list]"
msgstr "canal VIEW [máscara | num-entrada | lista]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
msgid "channel VIEW [mask | list]"
msgstr "canal VIEW [máscara | lista]"
@@ -748,7 +758,7 @@ msgstr "canal VIEW [máscara | lista]"
msgid "channel [description]"
msgstr "canal [descripción]"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
msgid "channel [nick]"
msgstr "canal [nick]"
@@ -756,7 +766,7 @@ msgstr "canal [nick]"
msgid "channel [parameters]"
msgstr "canal [parámetros]"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
msgid "channel [user]"
msgstr "canal [usuario]"
@@ -768,22 +778,12 @@ msgstr "canal [+expiración] [razón]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "canal [+expiración] {nick | máscara} [razón]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "canal MODIFY máscara cambios"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "canal SET [topic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
msgid "channel [UNLOCK|LOCK]"
msgstr "canal [UNLOCK|LOCK]"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
msgid "channel {ON|OFF}"
msgstr "canal {ON|OFF}"
@@ -806,7 +806,7 @@ msgstr "canal {ON|OFF} [ttb [num]]"
msgid "channel {ON|OFF} [ttb]"
msgstr "canal {ON|OFF} [ttb]"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr "canal {DIS | DISABLE} tipo"
@@ -828,24 +828,24 @@ msgstr "canal {ON | OFF}"
msgid "email"
msgstr "email"
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr "idioma"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
msgid "memo-text"
msgstr "texto-del-memo"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
msgid "message"
msgstr "mensaje"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr "nombre-del-módulo"
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr "nuevo-display"
@@ -854,8 +854,9 @@ msgid "new-password"
msgstr "nueva-contraseña"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
msgid "nick"
msgstr "nick"
@@ -880,16 +881,16 @@ msgstr "nick máscara"
msgid "nick newnick"
msgstr "nick nuevo-nick"
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
msgid "nick [reason]"
msgstr "nick [razón]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
msgid "nickname"
msgstr "nick"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr "nick dirección"
@@ -897,7 +898,7 @@ msgstr "nick dirección"
msgid "nickname email"
msgstr "nick email"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr "nick idioma"
@@ -905,11 +906,11 @@ msgstr "nick idioma"
msgid "nickname message"
msgstr "nick mensaje"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr "nick nuevo-display"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "nick nueva-contraseña"
@@ -917,7 +918,7 @@ msgstr "nick nueva-contraseña"
msgid "nickname [parameter]"
msgstr "nick [parámetro]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
msgid "nickname [password]"
msgstr "nick [contraseña]"
@@ -929,14 +930,14 @@ msgstr "nick [+expiración] [razón]"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "nick {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
msgid "nickname {ON | OFF}"
msgstr "nick {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "nick {ON | QUICK | IMMED | OFF}"
@@ -972,11 +973,11 @@ msgstr "código"
msgid "password"
msgstr "contraseña"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
msgid "password [email]"
msgstr "contraseña [email]"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
msgid "password email"
msgstr "contraseña email"
@@ -992,7 +993,7 @@ msgstr "patrón [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "servidor [razón]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr "usuario modos"
@@ -1000,7 +1001,7 @@ msgstr "usuario modos"
msgid "user [reason]"
msgstr "usuario [razón]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, c-format
msgid ""
" \n"
@@ -1018,7 +1019,7 @@ msgstr ""
"acciones maliciosas. El abuso de %s conllevará, como\n"
"mínimo, la pérdida del nick o los nicks empleados."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
msgid ""
" \n"
"SNLINE ADD adds the given realname mask to the SNLINE\n"
@@ -1052,7 +1053,7 @@ msgstr ""
"Aviso: ya que la máscara (nombre real) puede contener espcios,\n"
"el separador entre ella y la razón debe ser una coma."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1080,7 +1081,7 @@ msgstr ""
"expiración predeterminado de una SQLINE se puede ver con\n"
"el comandoSTATS AKILL."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, c-format
msgid ""
" \n"
@@ -1193,7 +1194,7 @@ msgstr ""
"AVISO: Para registrar un canal, primero debes registrar\n"
"tu nick."
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1220,7 +1221,7 @@ msgstr ""
"obtener información sobre como dar parte de estos privilegios\n"
"a otros usuarios del canal.\n"
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1232,7 +1233,7 @@ msgstr ""
"cualquier nick y pueden ver la lista de acceso de cualquier\n"
"nick sin necesidad de conocer la contraseña."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1244,7 +1245,7 @@ msgstr ""
"de su acceso, eliminar cualquier canal, ver (y modicar) las listas\n"
"de acceso, niveles y akicks, y configuraciones de cualquier canal."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1258,7 +1259,23 @@ msgstr ""
"después del tiempo dado. Ponlo en 0 para deshabilitar la expiración\n"
"automática."
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+" \n"
+"Los comandos %s están limitados al fundador\n"
+"(a menos que SECUREOPS se ponga a off). Sin embargo,\n"
+"cualquier usuario en la lista VOP o superior puede usar el\n"
+"comando %s LIST\n"
+" \n"
+
+#: modules/commands/cs_xop.cpp:546
#, c-format
msgid ""
" \n"
@@ -1297,7 +1314,7 @@ msgstr ""
"El comando %s CLEAR borra todas las entradas de la\n"
"lista %s."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1339,7 +1356,7 @@ msgstr ""
"El comando AKICK CLEAR borra todas las entradas de la\n"
"list akick."
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
msgid ""
" \n"
"The AKILL DEL command removes the given mask from the\n"
@@ -1380,7 +1397,7 @@ msgstr ""
" \n"
"AKILL CLEAR borra todas las entradas de la lista AKILL."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
msgid ""
" \n"
"The SNLINE DEL command removes the given mask from the\n"
@@ -1421,7 +1438,7 @@ msgstr ""
" \n"
"SNLINE CLEAR borra todas las entradas de la lista SNLINE."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1463,19 +1480,18 @@ msgstr ""
"SQLINE CLEAR borra todas las entradas de la lista SQLINE."
#: modules/commands/bs_assign.cpp:197
-#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
" \n"
"Esta opción hace al canal no asignable. Si un bot ya\n"
"está asignado al canal, es desasignado automáticamente\n"
"cuando habilitas esta opción."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
msgid ""
" \n"
"This option prevents a bot from being assigned to a\n"
@@ -1496,7 +1512,7 @@ msgstr ""
"Escribe %s%s HELP comando para ayuda sobre cualquiera\n"
"de los comandos anteriores."
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr " %s está en línea usando este bloque de operador."
@@ -1511,7 +1527,7 @@ msgstr " El comando %s en %s está asociado a %s"
msgid " Providing service: %s"
msgstr " Servicio proporcionado: %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr " Este operador está definido en el archivo de configuración."
@@ -1525,7 +1541,7 @@ msgstr " Cargado en: %p"
msgid " but %s mysteriously dematerialized."
msgstr " pero %s misteriosamente desmaterializado."
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1536,7 +1552,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr "\"Jupitear\" un servidor"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1556,17 +1572,17 @@ msgstr "%b %d %H:%M:%S %Y %Z"
msgid "%c is an unknown status mode."
msgstr "%c es un modo de estado desconocido."
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c no está bloqueado en %s."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s ha sido desbloqueado desde %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "%d entradas de acceso de %s han sido clonadas a %s."
@@ -1592,8 +1608,8 @@ msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
"%lu nicks están almacenados en la base de datos, usando %.2Lf kB de memoria."
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, c-format
msgid "%s %s list is empty."
msgstr "La lista de %s de %s está vacía."
@@ -1686,9 +1702,9 @@ msgstr "%s (%s) fue visto por última vez desconectando (%s) hace %s (%s)."
msgid "%s (minimum %d/%d%%)"
msgstr "%s (mínimo %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "La lista de acceso de %s esta vacía."
@@ -1698,7 +1714,7 @@ msgstr "La lista de acceso de %s esta vacía."
msgid "%s added to %s's auto join list."
msgstr "%s añadido a la lista de auto join de %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s ya existe."
@@ -1709,7 +1725,7 @@ msgstr "%s ya existe."
msgid "%s autokick list is empty."
msgstr "La lista de kicks automáticos del canal %s está vacía."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "La lista de bad words de %s está vacía."
@@ -1719,8 +1735,8 @@ msgstr "La lista de bad words de %s está vacía."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s no puede ser el sucesor en el canal %s ya que es el fundador."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Comandos para %s:"
@@ -1821,7 +1837,7 @@ msgstr "%s es un cliente en los Servicios."
msgid "%s is a network service."
msgstr "%s es un servicio de red."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s ya está cubierto por %s."
@@ -1836,7 +1852,7 @@ msgstr "%s ya está en la lista de auto join de %s."
msgid "%s is an unconfirmed nickname."
msgstr "%s es un nick no confirmado."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1862,7 +1878,7 @@ msgstr "%s está deshabilitado"
msgid "%s is enabled"
msgstr "%s está habilitado"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, c-format
msgid "%s is not a valid IP address."
msgstr "%s no es una IP válida."
@@ -1908,7 +1924,7 @@ msgstr "¡%s está en el canal ahora mismo (como %s)!"
msgid "%s is on the channel right now!"
msgstr "¡%s está en el canal ahora mismo!"
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, c-format
msgid "%s list for %s"
msgstr "Lista %s para %s"
@@ -1918,7 +1934,7 @@ msgstr "Lista %s para %s"
msgid "%s list is empty."
msgstr "La lista %s esta vacia."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, c-format
msgid "%s locked on %s."
msgstr "%s bloqueado en %s."
@@ -1973,7 +1989,7 @@ msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr ""
"%s ahora te notificará de tus memos cuando te conectes o saques tu /AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) añadido a la lista de bots."
@@ -2027,11 +2043,11 @@ msgstr "(Split)"
msgid "(by %s on %s) %s"
msgstr "(por %s en %s) %s"
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
msgid "(disabled)"
msgstr "(deshabilitado)"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr "(solo fundador)"
@@ -2095,7 +2111,7 @@ msgstr ". %s todavía está en línea."
msgid "<unknown>"
msgstr "<desconocido>"
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2108,7 +2124,7 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Un massmemo ha sido enviado a todos los usuarios registrados."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
@@ -2116,7 +2132,7 @@ msgstr ""
"También se enviará un memo informando al usuario, que incluirá la razón si "
"se proporciona."
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr "También se enviará un memo informando al usuario."
@@ -2152,7 +2168,7 @@ msgstr "ADD objetivo info"
msgid "ADD text"
msgstr "ADD texto"
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr "ADD [+expiración] máscara límite razón"
@@ -2169,11 +2185,11 @@ msgstr "ADD [nick] máscara"
msgid "ADD [nickname] [fingerprint]"
msgstr "ADD [nick] huella"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+expiración] máscara razón"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+expiración] máscara:razón"
@@ -2181,15 +2197,15 @@ msgstr "ADD [+expiración] máscara:razón"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiración] entrada razón"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr "ADDIP nombre-de-servidor ip"
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr "ADDSERVER nombre-de-servidor [nombre-de-zona]"
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr "ADDZONE nombre-de-zona"
@@ -2202,8 +2218,8 @@ msgstr "AKICK ENFORCE en %s completo; %d usuarios afectados."
msgid "AKILL all users on a specific channel"
msgstr "AKILL todos los usuarios de un canal específico"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "La lista de AKILLS está vacía."
@@ -2234,17 +2250,17 @@ msgstr "El nivel de acceso debe estar entre %d y %d inclusive."
msgid "Access level must be non-zero."
msgstr "El nivel de acceso no puede ser cero."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Opciones del nivel de acceso para el canal %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Niveles de acceso para %s resetados a los valores originales."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, c-format
msgid "Access list for %s:"
msgstr "Lista de acceso para %s:"
@@ -2258,23 +2274,15 @@ msgstr ""
"El acceso a este comando requiere que el permiso %s esté presente en tu tipo "
"de oper."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Activar características de seguridad"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr "Activar el vHost solicitado para el nick dado."
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -2298,7 +2306,7 @@ msgstr ""
"Esto se mostrará a los opers con el respectivo comando para el\n"
"nick o canal."
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr "Añadida IP %s a %s."
@@ -2335,13 +2343,7 @@ msgstr "Añadido servidor %s."
msgid "Added zone %s."
msgstr "Añadida zona %s."
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2366,7 +2368,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Todas las O:lines de %s han sido reseteadas."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Todas las entradas akick de %s han sido clonadas a %s."
@@ -2376,16 +2378,11 @@ msgstr "Todas las entradas akick de %s han sido clonadas a %s."
msgid "All available commands for %s:"
msgstr "Comandos disponibles para %s:"
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Todas las bad words de %s han sido clonadas a %s."
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Todas las entradas akick de %s han sido clonadas a %s."
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Todas las noticias de entrada borradas."
@@ -2395,12 +2392,12 @@ msgstr "Todas las noticias de entrada borradas."
msgid "All memos for channel %s have been deleted."
msgstr "Todos los memos para el canal %s han sido borrados."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr "Se han limpiado todos los modos en %s."
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2425,7 +2422,7 @@ msgstr "Todos los operadores de %s han sido borrados."
msgid "All random news items deleted."
msgstr "Todas las noticias al azar borradas."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Todas la configuración de %s ha sido clonada a %s."
@@ -2436,13 +2433,13 @@ msgid "All user modes on %s have been synced."
msgstr "Todas los modos de usuario en %s han sido sincronizados."
#: modules/commands/hs_group.cpp:60
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Todos los vhosts en el grupo %s han sido establecidos a %s"
#: modules/commands/hs_group.cpp:58
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Todos los vhosts en el grupo %s han sido establecidos a %s@%s."
#: src/access.cpp:41
@@ -2566,7 +2563,7 @@ msgstr ""
"Permite a los Administrators a enviar mensajes a todos los\n"
"usuarios de la red. El mensaje será enviado desde el nick %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
msgid ""
"Allows Services Operators to change modes for any channel.\n"
"Parameters are the same as for the standard /MODE command.\n"
@@ -2579,7 +2576,7 @@ msgstr ""
"CLEAR para borrar todos los modos del canal. Si se especifica\n"
"CLEAR ALL se limpian también los status de usuarios."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
msgid ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
@@ -2588,8 +2585,7 @@ msgstr ""
"cualquier usuario. Los parámetros son los mismos que para el\n"
"comando estándar /MODE."
-#: modules/commands/bs_bot.cpp:352
-#, fuzzy
+#: modules/commands/bs_bot.cpp:336
msgid ""
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
@@ -2599,13 +2595,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2663,7 +2659,7 @@ msgstr ""
" \n"
"Los ignores no funcionarán con IRCOps."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
"a user matching an AKILL mask attempts to connect, Services\n"
@@ -2707,7 +2703,7 @@ msgstr ""
"La expiración predeterminada para un AKILL se puede ver con el comando\n"
"STATS AKILL."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2718,17 +2714,14 @@ msgstr ""
"Si un usuario con nombre real coincidente con una SNLINE intenta\n"
"conectar, los Servicios no lo permitirán."
-#: modules/commands/os_sxline.cpp:670
-#, fuzzy
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
"Permite a los Operadores de Servicios manipular la lista SQLINE.\n"
"Si un usuario con nick coincidente con una máscara SQLINE intenta\n"
@@ -2736,7 +2729,7 @@ msgstr ""
"Si el primer caracter de la máscara es #, los servicios evitarán el uso\n"
"de los canales coincidentes."
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2787,8 +2780,7 @@ msgstr ""
"Mira la ayuda sobre EXCEPTION para más informacion acerca de\n"
"limites de sesion y como establecerlos para ciertos hosts y grupos."
-#: modules/commands/cs_topic.cpp:193
-#, fuzzy
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2796,9 +2788,8 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
"Permite manipular el topic del canal especificado.\n"
"El comando SET cambia el topic del canal al topic dado o borra el topic\n"
@@ -2810,7 +2801,7 @@ msgstr ""
"con\n"
"este comando."
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -2839,7 +2830,7 @@ msgstr ""
" \n"
"Opciones disponibles:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2868,7 +2859,7 @@ msgstr ""
"Ejemplo:\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2878,7 +2869,7 @@ msgstr ""
"el usuario dado. Con MSG establecido, los Servicios usarán mensajes,\n"
"si no, usarán notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2889,7 +2880,7 @@ msgstr ""
"contigo. Con %s establecido, los Servicios usarán mensajes,\n"
"si no, usarán notices."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -2969,7 +2960,7 @@ msgstr ""
"recibirás información acerca de un bot, tal como la fecha\n"
"de creación o el número de canales en los que está."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
@@ -2977,7 +2968,7 @@ msgstr ""
"Están disponibles métodos alternativos de modificar las listas\n"
"de acceso."
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
msgid "Approve the requested vHost of a user"
msgstr "Aprueba el vHost solicitado por un usuario"
@@ -2985,14 +2976,9 @@ msgstr "Aprueba el vHost solicitado por un usuario"
msgid "As a Services Operator, you may drop any nick."
msgstr "Como Operador de Servicios, puedes borrar cualquier nick."
-#: modules/commands/bs_assign.cpp:19
-msgid "Assigns a bot to a channel"
-msgstr "Asigna un bot a un canal"
-
#: modules/commands/bs_assign.cpp:78
-#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3000,15 +2986,19 @@ msgstr ""
"Luego puedes configurar el bot para acomodarlo a tus\n"
"necesidades."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+msgid "Assigns a bot to a channel"
+msgstr "Asigna un bot a un canal"
+
+#: data/chanserv.example.conf:1186
msgid "Associate a URL with the channel"
msgstr "Asociar una URL con el canal"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr "Asociar una URL con esta cuenta"
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
msgid "Associate a URL with your account"
msgstr "Asociar una URL con tu cuenta"
@@ -3016,11 +3006,11 @@ msgstr "Asociar una URL con tu cuenta"
msgid "Associate a greet message with your nickname"
msgstr "Asociar un saludo con tu nick"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
msgid "Associate an E-mail address with the channel"
msgstr "Asociar un e-mail con el canal"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Asociar un e-mail con tu nick"
@@ -3028,11 +3018,11 @@ msgstr "Asociar un e-mail con tu nick"
msgid "Associate oper info with a nick or channel"
msgstr "Asociar información de operador con un nick o con un canal"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Asocia el e-mail dado con el nick."
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3042,7 +3032,7 @@ msgstr ""
"mostrada cuando alguien pida información sobre el\n"
"nick con el comando INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3071,19 +3061,12 @@ msgstr "Protección automáticamente al entrar"
msgid "Automatic voice on join"
msgstr "Voz automáticamente al entrar"
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, c-format
msgid "Available commands for %s:"
msgstr "Comandos disponibles para %s:"
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr ""
-" \n"
-"Los comandos disponibles son:"
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr "Privilegios disponibles para %s:"
@@ -3097,20 +3080,20 @@ msgstr "BANS forzado por "
msgid "Bad words kicker"
msgstr "Kick por Bad words"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, c-format
msgid "Bad words list for %s:"
msgstr "Lista de bad words para %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "La lista de bad words esta ahora vacía."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr "La expiración del ban no puede ser superior a 1 día."
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, c-format
msgid "Ban on %s expires in %s."
msgstr "El ban en %s expira en %s."
@@ -3128,7 +3111,7 @@ msgstr "El tipo de ban para el canal %s es ahora #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Banea el nick o máscara dados en un canal"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3154,7 +3137,7 @@ msgstr "Bans forzados en %s."
msgid "Bolds kicker"
msgstr "Kick por negritas"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "El bot %s ya existe."
@@ -3169,12 +3152,12 @@ msgstr "El bot %s no existe."
msgid "Bot %s has been assigned to %s."
msgstr "El bot %s ha sido asignado al canal %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "El bot %s ha sido cambiado a %s!%s@%s (%s)."
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "El bot %s ha sido borrado."
@@ -3204,40 +3187,40 @@ msgstr "El bot no kickeará ops en el canal %s."
msgid "Bot won't kick voices on channel %s."
msgstr "El bot no kickeará voices en el canal %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, c-format
msgid "Bot %s is not changeable."
msgstr "El bot %s no se puede cambiar."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, c-format
msgid "Bot %s is not deletable."
msgstr "El bot %s no se puede borrar."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr "Los bans del bot expirarán automáticamente después de %s."
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
msgid "Bot bans will no longer automatically expire."
msgstr "Los bans del bot ya no expirarán automáticamente."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Los hosts de bots solo pueden tener %d caracteres."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
msgid "Bot hosts may only contain valid host characters."
msgstr "Los hosts de bots solo pueden contener caracteres de hosts válidos."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Los idents de bots solo pueden tener %d caracteres."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
msgid "Bot idents may only contain valid ident characters."
msgstr "Los idents de bots solo pueden contener caracteres de ident válidos."
@@ -3254,12 +3237,12 @@ msgstr "Lista de bots:"
msgid "Bot nick"
msgstr "Nick del bot"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Los nicks de bots solo pueden tener %d caracteres."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
msgid "Bot nicks may only contain valid nick characters."
msgstr "Los nicks de bots solo pueden contener caracteres de nicks válidos."
@@ -3348,8 +3331,8 @@ msgstr "El bot ya no kickeará por flood."
msgid "Bot won't kick for repeats anymore."
msgstr "El bot ya no kickeará por repetir."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr "Por"
@@ -3382,12 +3365,12 @@ msgstr ""
"siempre y cuando no haya sido leído en el momento en el que\n"
"usaste el comando."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "¡No se puede clonar el canal %s a sí mismo!"
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Imposible enviar el e-mail ahora; por favor inténtalo más tarde."
@@ -3456,20 +3439,20 @@ msgstr ""
msgid "Change channel modes"
msgstr "Cambiar modos de canal"
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Cambiar el método de comunicacion con los Servicios"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
msgid "Change user modes"
msgstr "Cambiar modos de usuario"
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Cambiados los modos de usuario de %s a %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3477,7 +3460,7 @@ msgstr ""
"Cambia el display usado para referirte a un grupo de\n"
"nicks. El nuevo display DEBE ser un nick del grupo."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3493,7 +3476,7 @@ msgstr ""
"Cambia el fundador de un canal. El nuevo nick debe estar\n"
"registrado."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3505,7 +3488,7 @@ msgstr ""
"idioma debe ser uno de los de la siguiente lista de idiomas\n"
"soportados:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3517,11 +3500,11 @@ msgstr ""
"idioma debe ser uno de los de la siguiente lista de idiomas\n"
"soportados:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr "Cambia la contraseña usada para identificarse como dueño del nick."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3541,7 +3524,7 @@ msgstr ""
"el sucesor se convertirá en el nuevo fundador del canal.\n"
"El nuevo nick debe estar registrado."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
msgid "Channel"
msgstr "Canal"
@@ -3620,12 +3603,12 @@ msgstr "El canal %s expirará."
msgid "Channel %s will not expire."
msgstr "El canal %s no expirará."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "La lista de %s de %s ha sido limpiada."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "La lista de acceso para el canal %s ha sido limpiada."
@@ -3635,7 +3618,7 @@ msgstr "La lista de acceso para el canal %s ha sido limpiada."
msgid "Channel %s akick list has been cleared."
msgstr "La lista de kicks automáticos del canal %s ha sido limpiada."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, c-format
msgid "Channel %s has no mode locks."
msgstr "El canal %s no tiene modos bloqueados."
@@ -3659,8 +3642,8 @@ msgstr "Lista de canales:"
msgid "Channel stats for %s on %s:"
msgstr "Estadísticas de canal para %s en %s:"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
msgid "Channels may not be on access lists."
msgstr "Los canales no pueden estar en las listas de acceso."
@@ -3720,10 +3703,9 @@ msgid "Checks if last memo to a nick was read"
msgstr "Comprueba si el último memo enviado a un nick ha sido leído"
#: modules/commands/ms_check.cpp:69
-#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Verifica si el _último_ memo que enviaste a nick ha sido leído.\n"
"Ten en cuenta solo funciona para nicks, no para canales."
@@ -3805,7 +3787,7 @@ msgstr "Configura kicks por repetir"
msgid "Configures reverses kicker"
msgstr "Configura kicks por fondos"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
msgid "Configures the time bot bans expire in"
msgstr "Configura el tiempo de expiración de los bans del bot"
@@ -3817,7 +3799,7 @@ msgstr "Configura kicks por subrayados"
msgid "Confirm a passcode"
msgstr "Confirmar un código"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
msgid "Control modes and mode locks on a channel"
msgstr "Controlar modos y bloqueos de modos en un canal"
@@ -3827,12 +3809,11 @@ msgid ""
msgstr ""
"Controla que mensajes son enviados a los usuarios cuando entran al canal."
-#: modules/commands/cs_clone.cpp:241
-#, fuzzy
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Copia toda la configuración, accesos, akicks, etc de canal al canal\n"
@@ -3840,37 +3821,37 @@ msgstr ""
"solo se clonan las respectivas opciones.\n"
"Debes ser el fundador de canal y objetivo."
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "Copia toda la configuración de un canal a otro"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
msgid "Created"
msgstr "Creado"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
msgid "Creator"
msgstr "Creador"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Lista %s actual:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
msgid "Current AKILL list:"
msgstr "Lista actual de AKILLs:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Lista de excepciones al límite de sesiones actual:"
@@ -3918,12 +3899,12 @@ msgstr "DEL [nick] huella"
msgid "DEL [nickname] mask"
msgstr "DEL [nick] máscara"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {máscara | entrada-num | lista | id}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
msgid "DEL {mask | entry-num | list}"
msgstr "DEL {máscara | entrada-num | lista}"
@@ -3939,19 +3920,19 @@ msgstr "DEL {num | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} entrada"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr "DELIP nombre-de-servidor ip"
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr "DELSERVER nombre-de-servidor [nombre-de-zona]"
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr "DELZONE nombre-de-zona"
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
msgid "DEPOOL server.name"
msgstr "DEPOOL nombre-de-servidor"
@@ -3966,7 +3947,7 @@ msgstr ""
msgid "Date/Time"
msgstr "Fecha/Hora"
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4095,16 +4076,20 @@ msgstr ""
msgid "Delete a memo or memos"
msgstr "Borra uno o más memos"
+#: modules/commands/hs_del.cpp:59
+msgid "Delete the vhost for all nicks in a group"
+msgstr "Borra el vhost de todos los nicks en un grupo"
+
#: modules/commands/hs_del.cpp:19
msgid "Delete the vhost of another user"
msgstr "Borra el vhost de otro usuario"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Borradas %d entradas de la lista de %s de %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "%d entradas borradas de la lista de acceso de %s."
@@ -4114,7 +4099,7 @@ msgstr "%d entradas borradas de la lista de acceso de %s."
msgid "Deleted %d entries from %s autokick list."
msgstr "%d entradas borradas de la lista de kicks automáticos del canal %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "%d entradas borradas de la lista de bad words de %s."
@@ -4134,7 +4119,7 @@ msgstr "Borradas %d entradas de la lista de %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "%d entradas borradas de la lista de AKILLs."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "1 entrada borrada de la lista de acceso de %s."
@@ -4144,7 +4129,7 @@ msgstr "1 entrada borrada de la lista de acceso de %s."
msgid "Deleted 1 entry from %s autokick list."
msgstr "1 entrada borrada de la lista de kicks automáticos del canal %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "1 palabra borrada de la lista de bad words de %s."
@@ -4167,7 +4152,7 @@ msgstr "1 entrada borrada de la lista de AKILLs."
msgid "Deleted info from %s."
msgstr "Borrada información de %s."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Borrada una entrada de la lista de %s de %s."
@@ -4210,11 +4195,6 @@ msgid ""
"database."
msgstr "Elimina el vhost asignado al nick dado de la base de datos."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr "Borra el vhost de todos los nicks en un grupo"
-
#: modules/commands/hs_del.cpp:93
msgid ""
"Deletes the vhost for all nicks in the same group as\n"
@@ -4223,13 +4203,13 @@ msgstr ""
"Elimina el vhost para todos los nicks en el mismo grupo que el\n"
"nick dado."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr "%s sacado del pool dns."
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
msgid "Description"
msgstr "Descripción"
@@ -4243,7 +4223,7 @@ msgstr "Descripción de %s cambiada a%s."
msgid "Description of %s unset."
msgstr "Descripción de %s eliminada."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
msgid "Disabled"
msgstr "Deshabilitado"
@@ -4267,7 +4247,7 @@ msgstr ""
" \n"
"La razón puede ser obligatoria en algunas redes."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, c-format
msgid "Displayed %d records (%d total)."
msgstr "Mostrados %d registros (%d en total)."
@@ -4381,12 +4361,12 @@ msgstr ""
"perderás tus accesos y los canales que poseas. Cualquier otro\n"
"usuario podrá tomar el control de ese nick."
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "Dirección e-mail para %s cambiada a %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "Dirección e-mail para %s borrada."
@@ -4441,8 +4421,8 @@ msgid "Email address"
msgstr "Dirección email"
#: modules/commands/ns_getemail.cpp:41
-#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+#, c-format
+msgid "Email matched: %s to %s."
msgstr "Emails que coinciden: %s a %s."
#: modules/fantasy.cpp:19
@@ -4453,11 +4433,11 @@ msgstr "Habilitar comandos fantasía"
msgid "Enable greet messages"
msgstr "Activar mensajes de saludo"
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr "Activa o desactiva la conservación de modos"
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
msgid "Enabled"
msgstr "Habilitado"
@@ -4484,7 +4464,7 @@ msgstr ""
"los modos del usuario e intentarán restablecerlos la próxima vez que\n"
"se cree el canal."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4495,7 +4475,7 @@ msgstr ""
"los modos del usuario e intentarán restablecerlos la próxima vez que\n"
"se identifique."
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4582,11 +4562,10 @@ msgstr ""
"de fundador con el comando access/qop."
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Habilita o deshabilita la opcion seguridad de ops para un\n"
"canal. Cuando seguridad de ops está activado, los usuarios\n"
@@ -4609,7 +4588,7 @@ msgstr ""
"vez que el canal sea creado."
#: modules/commands/cs_set.cpp:603
-#, fuzzy, c-format
+#, c-format
msgid ""
"Enables or disables the persistent channel setting.\n"
"When persistent is set, the service bot will remain\n"
@@ -4627,7 +4606,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -4650,20 +4629,20 @@ msgstr ""
"para el canal. Adicionalmente, los servicios pondrán o quitarán\n"
"dicho modo cuando actives o desactives la persistencia."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
msgid "End of AKILL list."
msgstr "Fin de la lista AKILL."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
msgid "End of access list"
msgstr "Fin de la lista de acceso"
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Fin de la lista de acceso - %d/%d resultado(s) mostrado(s)."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Fin de la lista de acceso."
@@ -4671,7 +4650,7 @@ msgstr "Fin de la lista de acceso."
msgid "End of autokick list"
msgstr "Fin de la lista autokick"
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
msgid "End of bad words list."
msgstr "Fin de la lista de bad words."
@@ -4701,7 +4680,7 @@ msgstr "Fin de la lista de prohibiciones."
msgid "End of list - %d channels shown."
msgstr "Fin de la lista - %d canales mostrados."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Fin de la lista - %d/%d resultado(s) mostrado(s)."
@@ -4749,8 +4728,8 @@ msgstr ""
"de usuarios en el canal sea inferior al límite del canal, si está "
"establecido."
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Español"
@@ -4808,17 +4787,16 @@ msgstr ""
"caracteres."
#: modules/commands/ns_cert.cpp:325
-#, fuzzy
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
@@ -4836,31 +4814,36 @@ msgstr ""
" CERT LIST\n"
" Muestra la lista de certificados actual."
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "La excepción para %s (#%d) movida a la posicion %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "La excepción para %s ha sido actualizada a %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
msgid "Expires"
msgstr "Expira"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Tiempo de expiración y razón actualizados para %s."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "Tiempo de expiración para %s actualizado."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasía"
@@ -4888,16 +4871,16 @@ msgstr "La huella %s ya está presente en la lista de certificados de %s."
msgid "Fingerprint %s is already in use."
msgstr "%s ya está en %s."
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr "Marcas"
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Marcas para %s en %s establecidas a +%s"
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Lista de marcas para %s"
@@ -4973,7 +4956,7 @@ msgstr "Fundador de %s cambiado a %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "El comando GETPASS no está disponible debido al uso de encriptación."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "El fantasma con tu nick ha sido killeado."
@@ -4981,7 +4964,7 @@ msgstr "El fantasma con tu nick ha sido killeado."
msgid "Give Operflags to a certain user"
msgstr "Otorga marcas de IRCOp a cierto usuario"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -4990,7 +4973,7 @@ msgstr ""
"Da status de %s al nick seleccionado en el canal. Si no se\n"
"proporciona nick te dará status de %s a ti"
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Te da a ti o al nick especificado status de %s en un canal"
@@ -5065,25 +5048,20 @@ msgstr "No sé quien es %s."
msgid "I've never seen %s on this channel."
msgstr "Nunca he visto a %s en este canal."
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-#, fuzzy
-msgid "INFO [type]"
+msgid "INFO type"
msgstr "INFO tipo"
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr "IP"
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, c-format
msgid "IP %s already exists for %s."
msgstr "La IP %s ya existe para %s."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, c-format
msgid "IP %s does not exist for %s."
msgstr "La IP %s no existe para %s."
@@ -5092,8 +5070,8 @@ msgstr "La IP %s no existe para %s."
msgid "Identify yourself with your password"
msgstr "Te identifica con tu contraseña"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Si no lo cambias en %s, yo cambiaré tu nick."
@@ -5106,11 +5084,11 @@ msgstr "La lista de ignorados ha sido vaciada."
msgid "Ignore list is empty."
msgstr "La lista de ignorados está vacía."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
msgid "Ignore list:"
msgstr "Lista de ignorados:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
msgid "Immediate protection"
msgstr "Proteccion inmediata"
@@ -5165,7 +5143,7 @@ msgstr ""
"Se ha introducido un código no válido, por favor, revisa otra vez el email e "
"inténtalo de nuevo"
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr "Código no válido."
@@ -5182,7 +5160,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Valor de umbral no válido. Debe ser un entero válido mayor a 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr "Valor no válido para LIMIT. Debe ser un número."
@@ -5199,16 +5177,16 @@ msgstr "Kick por cursivas"
msgid "Join a group"
msgstr "Entrar en un grupo"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
msgid "Keep modes"
msgstr "Guardar modos"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Guardar modos para %s Desactivado."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Guardar modos para %s Activado."
@@ -5226,7 +5204,7 @@ msgstr "La clave para el canal %s es %s."
msgid "Kick a user from a channel"
msgstr "Kickear un usuario de un canal"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr "Kickeados %d/%d usuarios que coinciden con %s en %s."
@@ -5235,13 +5213,12 @@ msgstr "Kickeados %d/%d usuarios que coinciden con %s en %s."
msgid "Kicks a specified nick from a channel"
msgstr "Kickea un nick especificado de un canal"
-#: modules/commands/cs_kick.cpp:128
-#, fuzzy
+#: modules/commands/cs_kick.cpp:115
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Kickea al nick especificado del canal.\n"
" \n"
@@ -5266,17 +5243,17 @@ msgstr "LIMIT forzado en %s, %d usuarios eliminados."
msgid "LIST threshold"
msgstr "LIST umbral"
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
msgid "LIST [mask | list | id]"
msgstr "LIST [máscara | lista | id]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr "LIST [máscara | lista]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
msgid "LIST [nickname]"
msgstr "LIST [nick]"
@@ -5284,15 +5261,10 @@ msgstr "LIST [nick]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [texto|número]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Idioma cambiado a Español."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Sucesor de %s cambiado a %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5302,7 +5274,7 @@ msgstr "El último memo enviado a %s ha sido cancelado."
msgid "Last quit message"
msgstr "Último mensaje quit"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
msgid "Last seen"
msgstr "Última vez visto"
@@ -5310,11 +5282,11 @@ msgstr "Última vez visto"
msgid "Last seen address"
msgstr "Última dirección vista"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr "Último topic"
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
msgid "Last used"
msgstr "Usado por última vez"
@@ -5322,27 +5294,27 @@ msgstr "Usado por última vez"
msgid "Last usermask"
msgstr "Última máscara"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr "Nivel"
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "El nivel para %s en el canal %s cambiado a %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "El nivel para %s en el canal %s cambiado a solo fundador."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "El nivel debe estar entre %d y %d inclusive."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr "Límite"
@@ -5355,7 +5327,7 @@ msgstr "Listar todos los nick registrados que concuerdan con el patrón dado"
msgid "List channels you have access on"
msgstr "Listar canales en los que tienes acceso"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr "La lista para el modo %c está llena."
@@ -5364,7 +5336,7 @@ msgstr "La lista para el modo %c está llena."
msgid "List loaded modules"
msgstr "Listar módulos cargados"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr "Lista de entradas que coinciden con %s:"
@@ -5597,19 +5569,17 @@ msgid "Lists currently loaded modules."
msgstr "Lista todos los módulos cargados."
#: modules/commands/cs_info.cpp:19
-#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr "Lista información sobre el canal registrado dado"
#: modules/commands/cs_info.cpp:76
-#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Lista información sobre el canal registrado dado,\n"
"incluyendo su fundador, tiempo de registro, y última vez\n"
@@ -5703,7 +5673,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr "Buscándote a ti mismo, ¿eh %s?"
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr "MOVE num posición"
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5770,11 +5744,11 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr "Mantiene la lista de AutoKick"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
msgid "Maintains network bot list"
msgstr "Mantiene la lista de bots de la red"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -5785,7 +5759,7 @@ msgstr ""
"entrada de la lista %s reciben los siguientes privilegios:\n"
" "
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -5814,7 +5788,7 @@ msgstr ""
"lista la cuenta de %s en vez de la máscara; es decir, todos\n"
"los usuarios en el grupo serán también kickeados.\n"
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -5832,7 +5806,7 @@ msgstr ""
"Cualquier usuario que no esté en la lista de acceso tendrá\n"
"nivel 0, y cualquier usuario no registrado tendrá nivel -1."
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -5866,7 +5840,7 @@ msgstr ""
"palabra sea dicho por un usuario.\n"
"\n"
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
msgid "Maintains the bad words list"
msgstr "Mantiene lista de bad words"
@@ -5875,22 +5849,19 @@ msgid "Makes the bot do the equivalent of a \"/me\" command"
msgstr "Hace que el bot haga el equivalente al comando \"/me\" "
#: modules/commands/bs_control.cpp:127
-#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Hace que el bot haga el equivalente al comando \"/me\" \n"
"en el canal dado usando el texto dado."
#: modules/commands/bs_control.cpp:19
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr "Hace que el bot diga el texto dado en el canal dado"
#: modules/commands/bs_control.cpp:69
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr "Hace que el bot diga el texto dado en el canal dado."
#: modules/commands/greet.cpp:157
@@ -5917,7 +5888,7 @@ msgstr ""
"GREET habilitada, siempre que tengas acceso suficiente\n"
"en dicho canal."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
msgid "Manage DNS zones for this network"
msgstr "Administra las zonas DNS para esta red"
@@ -5933,12 +5904,12 @@ msgstr "Administra la lista de ignorados en los memos"
msgid "Manage your auto join list"
msgstr "Administra tu lista de auto join"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, c-format
msgid "Manipulate the %s list"
msgstr "Manipula la lista %s"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "Manipula la lista AKILL"
@@ -5946,19 +5917,19 @@ msgstr "Manipula la lista AKILL"
msgid "Manipulate the DefCon system"
msgstr "Manipula el sistema DefCon"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
msgid "Manipulate the topic of the specified channel"
msgstr "Manipula el topic del canal especificado"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr "Máscara"
@@ -5971,8 +5942,8 @@ msgstr "La máscara %s ya está presente en la lista de acceso de %s."
msgid "Mask must be in the form user@host."
msgstr "La máscara debe ser en formato usuario@host"
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
msgid "Masks and unregistered users may not be on access lists."
msgstr ""
"Las listas de acceso no pueden contener máscaras o usuarios no registrados."
@@ -6001,7 +5972,7 @@ msgstr "Memo %d de %s (%s)."
msgid "Memo %d has been deleted."
msgstr "El memo %d ha sido borrado."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
msgid "Memo ignore list is empty."
msgstr "La lista de ignorados está vacía."
@@ -6020,7 +5991,7 @@ msgstr "Límite de memos para %s establecido a %d."
msgid "Memo limit for %s set to 0."
msgstr "Límite de memos para %s establecido a 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo enviado a %s."
@@ -6034,7 +6005,7 @@ msgstr "Memos para %s:"
msgid "Message"
msgstr "Mensaje"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Modo de mensaje"
@@ -6042,25 +6013,25 @@ msgstr "Modo de mensaje"
msgid "Method"
msgstr "Método"
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr "Falta un parámetro para el modo %c."
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr "Modo"
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, c-format
msgid "Mode %s is not a status or list mode."
msgstr "El modo %s no es un modo de status."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
msgid "Mode lock"
msgstr "Bloqueo de modos"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, c-format
msgid "Mode locks for %s:"
msgstr "Modos bloqueado para %s:"
@@ -6069,11 +6040,6 @@ msgstr "Modos bloqueado para %s:"
msgid "Modes"
msgstr "Modos"
-#: modules/commands/os_mode.cpp:44
-#, fuzzy, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr "%d canale(s) limpiado(s), y %d canale(s) borrado(s)."
-
#: modules/commands/ns_access.cpp:166
#, c-format
msgid ""
@@ -6118,11 +6084,10 @@ msgstr ""
" Muestra la lista de acceso actual."
#: modules/commands/ns_cert.cpp:319
-#, fuzzy
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6137,7 +6102,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr "Modificar la lista de ignorados por los Servicios"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, c-format
msgid "Modify the list of %s users"
msgstr "Modificar la lista de usuarios %s"
@@ -6146,7 +6111,7 @@ msgstr "Modificar la lista de usuarios %s"
msgid "Modify the list of authorized addresses"
msgstr "Modificar la lista de direcciones autorizadas"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
msgid "Modify the list of privileged users"
msgstr "Modificar la lista de usuarios privilegiados"
@@ -6154,7 +6119,7 @@ msgstr "Modificar la lista de usuarios privilegiados"
msgid "Modify the nickname client certificate list"
msgstr "Modificar la lista de certificados del nick"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
msgid "Modify the session-limit exception list"
msgstr "Modifica la lista de excepciones al límite de sesión"
@@ -6201,14 +6166,14 @@ msgstr "Módulo: %s Versión: %s Autor: %s Cargado: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Módulo: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr "Nombre"
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr "Nombre Tipo"
@@ -6221,18 +6186,18 @@ msgstr "Estadísticas de red para %s:"
msgid "Never"
msgstr "Nunca"
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
msgid "Nick"
msgstr "Nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, c-format
msgid "Nick %s has been confirmed."
msgstr "El nick %s ha sido confirmado."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, c-format
msgid "Nick %s is already an operator."
msgstr "El nick %s ya es un operador."
@@ -6247,7 +6212,6 @@ msgstr "El nick %s ya está confirmado."
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "El nick %ses un nick ilegal, y no puede ser usado."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6263,7 +6227,7 @@ msgstr "El nick %s está prohibido por %s: %s"
msgid "Nick %s is forbidden."
msgstr "El nick %s está prohibido."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, c-format
msgid "Nick %s is not a Services Operator."
msgstr "El nick %s no es un Operador de Servicios."
@@ -6288,12 +6252,12 @@ msgstr "El nick %s no está registrado."
msgid "Nick %s was truncated to %d characters."
msgstr "El nick %s fue reducido a %d caracteres."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "El nick %s sí expirará."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "El nick %s no expirará."
@@ -6358,17 +6322,17 @@ msgstr "¡El nick %s ya está registrado!"
msgid "Nickname %s may not be registered."
msgstr "El nick %s no puede ser registrado."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Nick %s registrado bajo tu máscara usuario@host: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, c-format
msgid "Nickname %s registered."
msgstr "Nick %s registrado."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
msgid "No auto-op"
msgstr "No auto-op"
@@ -6376,7 +6340,7 @@ msgstr "No auto-op"
msgid "No bot"
msgstr "No hay bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
msgid "No expire"
msgstr "No expira"
@@ -6404,13 +6368,13 @@ msgstr "¡No hay noticias de entrada para borrar!"
msgid "No matches for %s found."
msgstr "No se encontraron coincidencias para %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, c-format
msgid "No matching entries on %s %s list."
msgstr "No hay entradas que coincidan en la lista de %s de %s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "No hay entradas que concuerden en la lista de acceso de %s ."
@@ -6422,23 +6386,23 @@ msgstr ""
"No hay entradas que concuerden en la lista de kicks automaticos en el canal "
"%s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "No existen palabras que concuerden en la lista de bad words de %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr ""
"No hay entradas que concuerden en la lista de excepciones al límite de "
"sesiones."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, c-format
msgid "No matching entries on the %s list."
msgstr "No hay entradas que coincidan en la lista de %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "No hay entradas que concuerden en la lista de AKILLs."
@@ -6450,7 +6414,12 @@ msgstr "¡Ningun memo pudo ser cancelado."
msgid "No modules currently loaded matching that criteria."
msgstr "Actualmente no hay módulos cargados que coincidan con ese patrón."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, c-format
+msgid "No nick registrations matching %s found."
+msgstr "No se encontraron nicks registrados que concuerden con %s."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr "Nadie está usando tu nick, y los servicios no lo están reteniendo."
@@ -6470,12 +6439,7 @@ msgstr "¡No hay noticias al azar para borrar!"
msgid "No records to display."
msgstr "No hay registros para mostrar."
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "No se encontraron nicks registrados que concuerden con %s."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr "No se encontraron peticiones para el nick %s."
@@ -6484,8 +6448,8 @@ msgstr "No se encontraron peticiones para el nick %s."
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr "No se firman los kicks cuando se usa SIGNKICK LEVEL"
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, c-format
msgid "No stats for %s."
msgstr "No hay estadísticas para %s."
@@ -6495,7 +6459,7 @@ msgstr "No hay estadísticas para %s."
msgid "No such info \"%s\" on %s."
msgstr "No existe la información \"%s\" en %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, c-format
msgid "No users on %s match %s."
msgstr "Ningún usuario en %s concuerda con %s."
@@ -6510,7 +6474,7 @@ msgstr "El modo no bot está ahora Desactivado en el canal %s."
msgid "No-bot mode is now on on channel %s."
msgstr "El modo no bot está ahora Activado en el canal %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr "Modos no-status borrados en %s"
@@ -6519,21 +6483,21 @@ msgstr "Modos no-status borrados en %s"
msgid "None"
msgstr "Ninguno"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr "Nada que hacer."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr "Número"
@@ -6541,17 +6505,14 @@ msgstr "Número"
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [texto|número]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "La informacion antigua es igual a la nueva."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
msgid "Online from"
msgstr "En línea desde"
-#: modules/commands/os_oper.cpp:139
-#, fuzzy, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr " Este operador está definido en el archivo de configuración."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr "Información de Operador"
@@ -6575,12 +6536,12 @@ msgstr "¡Noticia de oper #%s no encontrada!"
msgid "Oper news items:"
msgstr "Noticias de oper:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr "Privilegios de Oper eliminados para %s (%s)."
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, c-format
msgid "Oper type %s has not been configured."
msgstr "El tipo de operador %s no ha sido configurado."
@@ -6595,17 +6556,17 @@ msgstr "Se han añadido los marcas de IRCOp %s para %s."
msgid "Operflags %s have been removed from %s."
msgstr "Las marcas de IRCOp %s se han eliminado para %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr "El Operador de tipo %s no tiene comandos permitidos."
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr "El Operador de tipo %s no tiene privilegios permitidos."
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr "El Operador de tipo %s recibe los modos %s una vez identificado."
@@ -6618,11 +6579,11 @@ msgstr "Proteccion de Ops"
msgid "Options"
msgstr "Opciones"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
msgid "POOL server.name"
msgstr "POOL nombre-de-servidor"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr "Parámetro"
@@ -6638,12 +6599,12 @@ msgstr "Contraseña aceptada."
msgid "Password authentication required for that command."
msgstr "Este comando requiere identificación por contraseña"
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, c-format
msgid "Password for %s changed to %s."
msgstr "Contraseña de %s cambiada a %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, c-format
msgid "Password for %s changed."
msgstr "Contraseña de %s cambiada."
@@ -6662,7 +6623,7 @@ msgstr "Contraseña incorrecta."
msgid "Password reset email for %s has been sent."
msgstr "Ha sido enviado un email de restablecimiento de contraseña para %s."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Paz"
@@ -6676,7 +6637,7 @@ msgstr "Opción de paz para %s Desactivada."
msgid "Peace option for %s is now on."
msgstr "Opción de paz para %s Activada."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
msgid "Persistent"
msgstr "Persistente"
@@ -6711,12 +6672,12 @@ msgstr "Por favor, usa el símbolo # cuando intentes registrar un canal."
msgid "Please wait %d seconds and retry."
msgstr "Por favor, espera %d segundos e inténtalo de nuevo."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Por favor, espera %d segundos antes de solicitar un nuevo vHost."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr ""
@@ -6728,13 +6689,13 @@ msgid "Please wait %d seconds before using the GROUP command again."
msgstr ""
"Por favor, espera %d segundos antes de usar el comando GROUP nuevamente."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Por favor, espera %d segundos antes de usar el comando REGISTER nuevamente."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr "%s añadido al pool dns."
@@ -6747,7 +6708,7 @@ msgstr "En el pool/Activo"
msgid "Pooled/Not Active"
msgstr "En el pool/No Activo"
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr "Evita que un bot sea asignado por usuarios que no son IRCOps"
@@ -6767,7 +6728,7 @@ msgstr "Evita que el canal expire"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Evita que el nick aparezca en el comando LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
msgid "Prevent the nickname from expiring"
msgstr "Evita que el nick expire"
@@ -6775,17 +6736,17 @@ msgstr "Evita que el nick expire"
msgid "Prevents users being kicked by Services"
msgstr "Evita que los usuarios sean kickeados por los Servicios"
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privado"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, c-format
msgid "Private mode of bot %s is now off."
msgstr "El modo privado del bot %s está ahora Desactivado."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, c-format
msgid "Private mode of bot %s is now on."
msgstr "El modo privado del bot %s está ahora Activado."
@@ -6810,37 +6771,37 @@ msgstr "Privacidad Desactivada para %s."
msgid "Private option is now on for %s."
msgstr "Privacidad Activada para %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr "Privilegios de %s dados a %s en %s, las nuevas marcas son +%s"
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Privilegios de %s quitados a %s en %s, las nuevas marcas son +%s"
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Protección"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, c-format
msgid "Protection is now off for %s."
msgstr "La protección para %sahora está Desactivada."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr ""
"La protección está ahora Activada para %s, con tiempo de espera reducido."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "La protección está ahora Activada para %s, sin tiempo de espera."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, c-format
msgid "Protection is now on for %s."
msgstr "La protección para %sahora está Activada."
@@ -6855,7 +6816,7 @@ msgstr ""
"la máscara completa ident@host para cada nick, luego\n"
"fuerza el AKILL."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
msgid "Quick protection"
msgstr "Proteccion rápida"
@@ -6897,20 +6858,20 @@ msgstr "Leer un memo o memos"
msgid "Real name"
msgstr "Nombre real"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr "Razón"
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, c-format
msgid "Reason for %s updated."
msgstr "Razón para %s actualizada."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -6925,21 +6886,21 @@ msgstr ""
"expulsado de la red (similar al viejo comando GHOST). Si no\n"
"está identificado, se forzará el cambio de nick."
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
msgid "Redefine the meanings of access levels"
msgstr "Redefine el significado de los niveles de acceso"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
msgid "Regains control of your nick"
msgstr "Recupera el control de tu nick"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
msgid "Regex is disabled."
msgstr "Regex está deshabilitado."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6948,9 +6909,9 @@ msgstr ""
"También se pueden usar expresiones regulares usando el motor %s.\n"
"Encierra tu máscara entre // si lo deseas."
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6963,11 +6924,11 @@ msgstr ""
msgid "Register a channel"
msgstr "Registrar un canal"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
msgid "Register a nickname"
msgstr "Registrar un nick"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
msgid "Registered"
msgstr "Registrado"
@@ -7022,7 +6983,7 @@ msgstr ""
"le dará status de operador del canal automáticamente\n"
"al entrar al canal."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7061,7 +7022,7 @@ msgstr ""
"elegir una contraseña de al menos 5 caracteres.\n"
"Por último, las contraseñas no pueden contener espacios."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
msgid "Registration is currently disabled."
msgstr "El registro está deshabilitado en este momento."
@@ -7069,11 +7030,11 @@ msgstr "El registro está deshabilitado en este momento."
msgid "Regulate the use of critical commands"
msgstr "Regular el uso de comandos críticos"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
msgid "Reject the requested vHost for the given nick."
msgstr "Rechazar el vHost solicitado para el nick dado"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
msgid "Reject the requested vHost of a user"
msgstr "Rechazar el vHost solicitado por un usuario"
@@ -7109,22 +7070,22 @@ msgstr "Eliminar todos los bans que evitan que un usuario entre a un canal"
msgid "Remove all operators from a server remotely"
msgstr "Elimina todos los operadores de un servidor remotamente"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, c-format
msgid "Removed IP %s from %s."
msgstr "Eliminada IP %s de %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr "Servidor %s eliminado de la zona %s."
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr "Servidor %s eliminado."
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7133,27 +7094,26 @@ msgstr ""
"Quita el status de %s del nick seleccionado en un canal. Si no se\n"
"especifica nick, te quitará es status de %s a ti"
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Te quita el status de %s a ti o al nick especificado en un canal"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
msgid "Removes a selected nicks status from a channel"
msgstr "Elimina el status del nick especificado de un canal"
-#: modules/commands/cs_updown.cpp:223
-#, fuzzy
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
"Elimina los modos de status del nick especificado en un canal. Si\n"
"se omite nick se eliminará tu status. Si se omite canal se eliminará\n"
"tu status en todos los canales en los que estés."
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr "Eliminando %s porque lo cubre %s."
@@ -7167,10 +7127,9 @@ msgstr "Kick por repeticion"
msgid "Request a vHost for your nick"
msgstr "Solicitar un vHost para tu nick"
-#: modules/commands/hs_request.cpp:180
-#, fuzzy
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
@@ -7178,7 +7137,7 @@ msgstr ""
"administradores de la red. Por favor, ten paciencia mientras\n"
"tu petición es considerada."
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
msgid "Resend registration confirmation email"
msgstr "Reenviar email de confirmación"
@@ -7186,7 +7145,7 @@ msgstr "Reenviar email de confirmación"
msgid "Restrict access to the channel"
msgstr "Restringir el acceso al canal"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
msgid "Restricted access"
msgstr "Acceso restringido"
@@ -7217,7 +7176,7 @@ msgstr "Retiene el topic cuando el canal no está en uso"
msgid "Retrieve the password for a nickname"
msgstr "Recupera la contraseña de un nick"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr "Devuelve las solicitudes de vhost"
@@ -7230,9 +7189,15 @@ msgid "Returns the key of the given channel."
msgstr "Devuelve la clave del canal dado."
#: modules/commands/ns_getemail.cpp:58
-#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr "Devuelve la clave del canal dado."
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Muestra los nicks que usan el email dado. Ten en cuenta que no\n"
+"puedes usar comodines. Cuando se usa este comando, se registrará\n"
+"la persona que usó el comando y el email usado."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7299,16 +7264,16 @@ msgstr "Revierte el efecto del comando IDENTIFY"
msgid "SET server"
msgstr "SET servidor"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr "SET nombre-servidor opción valor"
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Huella SSL aceptada, ahora estás identificado en %s."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Huella SSL aceptada, ahora estás identificado."
@@ -7329,7 +7294,7 @@ msgstr "Guardar la base de datos y reiniciar los Servicios"
msgid "Searches logs for a matching pattern"
msgstr "Busca registros con el patrón dado"
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
msgid "Secure founder"
msgstr "Fundador Seguro"
@@ -7343,7 +7308,7 @@ msgstr "Seguridad de fundador para %s Desactivada."
msgid "Secure founder option for %s is now on."
msgstr "Seguridad de fundador para %s Activada."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
msgid "Secure ops"
msgstr "Ops Seguros"
@@ -7367,12 +7332,12 @@ msgstr "Seguridad para %s ahora Desactivada."
msgid "Secure option for %s is now on."
msgstr "Seguridad para %s ahora Activada."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, c-format
msgid "Secure option is now off for %s."
msgstr "Seguridad Desactivada para %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, c-format
msgid "Secure option is now on for %s."
msgstr "Seguridad Activada para %s."
@@ -7382,11 +7347,11 @@ msgstr "Seguridad Activada para %s."
msgid "Secureops enforced on %s."
msgstr "Seguridad de OPs forzada en %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Seguridad"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7395,7 +7360,7 @@ msgstr ""
"%s%s HELP %s para más información sobre\n"
"la lista de acceso."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7446,7 +7411,7 @@ msgstr "Envía a todos los usuarios registrados un memo conteniendo texto-memo
msgid "Sends all services staff a memo containing memo-text."
msgstr "Envía a todo el staff de servicios un memo conteniendo texto-memo."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
msgid ""
"Sends the named nick or channel a memo containing\n"
"memo-text. When sending to a nickname, the recipient will\n"
@@ -7510,14 +7475,14 @@ msgid "Server %s already exists."
msgstr "El servidor %s ya existe."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, c-format
msgid "Server %s does not exist."
msgstr "El servidor %s no existe."
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, c-format
msgid "Server %s has no configured IPs."
msgstr "El servidor %s no tiene IPs configuradas."
@@ -7527,12 +7492,12 @@ msgstr "El servidor %s no tiene IPs configuradas."
msgid "Server %s is already in zone %s."
msgstr "El servidor %s ya está en la zona %s."
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, c-format
msgid "Server %s is already pooled."
msgstr "El servidor %s ya está en el pool dns."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, c-format
msgid "Server %s is not currently linked."
msgstr "El servidor %s no está conectado."
@@ -7547,12 +7512,12 @@ msgstr "El servidor %s no está en la zona %s."
msgid "Server %s is not linked to the network."
msgstr "El servidor %s no está conectado a la red."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, c-format
msgid "Server %s is not pooled."
msgstr "El servidor %s no está en el pool dns."
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr "El servidor %s debe desconectarse antes de ser borrado."
@@ -7570,19 +7535,18 @@ msgstr "Servidores encontrados: %d"
msgid "Service"
msgstr "Servicio"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, c-format
msgid "Service's hold on %s has been released."
msgstr "El nick %s retenido por los servicios ha sido liberado."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s es un Operador de Servicios del tipo %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
msgid "Services are in DefCon mode, please try again later."
msgstr "Los servicios están en modo DefCon, por favor, inténtalo más tarde."
@@ -7632,7 +7596,7 @@ msgstr "Los servicios han sido configurados para no enviar e-mails."
msgid "Services ignore list:"
msgstr "Lista de ignorados de los Servicios:"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
"correctly?"
@@ -7645,7 +7609,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Servicios en línea %s."
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr ""
@@ -7658,7 +7622,7 @@ msgstr ""
"Los Servicios ya no establecerán automáticamente los modos de los usuarios en"
" %s."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr ""
@@ -7670,12 +7634,12 @@ msgid "Services will now automatically give modes to users in %s."
msgstr ""
"Los Servicios establecerán automáticamente los modos de los usuarios en %s."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Los Services ahora responderán a %s con mensajes."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Los Services ahora responderán a %s con notices."
@@ -7693,7 +7657,7 @@ msgstr "Sesión"
msgid "Session limit for %s set to %d."
msgstr "Límite de sesión para %s establecido a %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Límites de sesión no disponibles."
@@ -7730,7 +7694,7 @@ msgstr "Establece el canal como permanente"
msgid "Set the channel description"
msgstr "Establece la descripción del canal"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
msgid "Set the display of your group in Services"
msgstr "Establece el display de tu grupo en los Servicios"
@@ -7738,11 +7702,11 @@ msgstr "Establece el display de tu grupo en los Servicios"
msgid "Set the founder of a channel"
msgstr "Establece el fundador de un canal"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
msgid "Set the language Services will use when messaging you"
msgstr "Establece el idioma en el que los Servicios te enviarán mensajes"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
msgid "Set the nickname password"
msgstr "Establece la contraseña del nick"
@@ -8066,7 +8030,7 @@ msgstr ""
msgid "Sets various nickname options. option can be one of:"
msgstr "Configura varias opciones de nick. opción puede ser:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8081,7 +8045,7 @@ msgstr ""
"Configura la expiración para el canal dado. Si se pone\n"
"a ON evita que el canal expire."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8097,7 +8061,7 @@ msgstr ""
"de la configuración del canal, algún modo puede no ser establecido\n"
"automáticamente."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8105,7 +8069,7 @@ msgstr ""
"Configura la expiración para el nick dado. Si se pone\n"
"a ON evita que el nick expire."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8121,7 +8085,7 @@ msgstr ""
"puede\n"
"no ser establecido automáticamente."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8181,11 +8145,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Opción de kick firmado para %s Activada."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Kicks Firmados"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "Lo siento, %s tiene muchos memos actualmente y no puede recibir más."
@@ -8195,55 +8159,47 @@ msgstr "Lo siento, %s tiene muchos memos actualmente y no puede recibir más."
msgid "Sorry, I have not seen %s."
msgstr "Lo siento, no he visto a %s."
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr ""
-"Lo siento, la lista de bad words para canales está temporalmente "
-"dehabilitada."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Lo siento, la asignación de bots está temporalmente deshabilitada."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Lo siento, la modificación de bots está temporalmente deshabilitada."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr ""
"Lo siento, la configuración de opciones del bot está temporalmente "
"deshabilitada."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr ""
-"Lo siento, la configuración de opciones del bot está temporalmente "
-"deshabilitada."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Lo siento, la modificación de la lista %s de canal está temporalmente "
"deshabilitada."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr ""
"Lo siento, la modificación de acceso a canales está temporalmete "
"deshabilitada."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr ""
"Lo siento, la modificación de kicks automaticos en canales está "
"temporalmente deshabilitada."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr ""
+"Lo siento, la lista de bad words para canales está temporalmente "
+"dehabilitada."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Lo siento, el borrado de canales está temporalmente deshabilitado."
@@ -8275,7 +8231,7 @@ msgstr "Lo siento, el borrado de nicks esta temporalmente deshabilitado."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Lo siento, la agrupación de nicks esta temporalmente deshabilitada."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Lo siento, el registro de nicks está temporalmente deshabilitado."
@@ -8295,13 +8251,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Lo siento, solo puedes tener %d entradas en tu lista de certificados."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "La lista de información de oper para %s está llena."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8316,7 +8267,7 @@ msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr ""
"Lo siento, solo puedes tener %d máscaras para kicks automáticos en un canal."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Lo siento, solo puedes tener %d bad words en un canal."
@@ -8578,7 +8529,6 @@ msgstr ""
"en la línea de comandos."
#: modules/commands/ms_set.cpp:246
-#, fuzzy
msgid ""
"Syntax: NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\n"
" \n"
@@ -8591,7 +8541,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -8662,7 +8612,7 @@ msgstr ""
"Esta opción no es persistente y debe ser usada\n"
"solo cuando sea necesario."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -8678,12 +8628,12 @@ msgstr ""
"la has cambiado)."
#: modules/commands/cs_invite.cpp:91
-#, fuzzy, c-format
+#, c-format
msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Le dice a %s que te invite a ti, u opcionalmente al nick\n"
@@ -8693,14 +8643,14 @@ msgstr ""
"superior en el canal."
#: modules/commands/cs_unban.cpp:103
-#, fuzzy, c-format
+#, c-format
msgid ""
"Tells %s to remove all bans preventing you or the given\n"
"user from entering the given channel. If no channel is\n"
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Le dice a %s que elimine todos los bans que evitan que\n"
@@ -8747,7 +8697,7 @@ msgstr "Termina el programa de Servicios guardando los cambios"
msgid "Text"
msgstr "Texto"
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -8764,7 +8714,7 @@ msgstr ""
"(por ejemplo AUTOOP). Cuando un usuario entra al canal, el status\n"
"que recibe es el mayor de los que tenga en la lista."
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -8778,7 +8728,7 @@ msgstr ""
"Puede eliminarte a ti mismo de la lista incluso si no tienes acceso\n"
"para modificarla de otro modo."
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -8808,21 +8758,20 @@ msgstr ""
"El comando ACCESS CLEAR borra todas las entradas de la\n"
"lista de acceso."
-#: modules/commands/cs_flags.cpp:447
-#, fuzzy
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
"El comando CLEAR limpia la lista de acceso del canal, lo que requiere "
"permisos de fundador."
#: modules/commands/cs_seen.cpp:174
-#, fuzzy, c-format
+#, c-format
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
@@ -8835,8 +8784,7 @@ msgstr ""
" %s CLEAR 30m\n"
" Eliminará todas las entradas añadidas en los últimos 30 minutos."
-#: modules/commands/bs_badwords.cpp:438
-#, fuzzy
+#: modules/commands/bs_badwords.cpp:437
msgid ""
"The DEL command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
@@ -8850,7 +8798,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"El comando DEL elimina la palabra dada de la lista\n"
@@ -8867,20 +8815,18 @@ msgstr ""
"El comando CLEAR borra todas las entradas de la lista."
#: modules/commands/cs_entrymsg.cpp:241
-#, fuzzy
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
"El comando ENTRYMSG ADD añade el mensaje dado a la lista\n"
"de mensajes a ser mostrados a los usuarios cuando entran al canal."
#: modules/commands/cs_entrymsg.cpp:253
-#, fuzzy
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
"El comando ENTRYMSG CLEAR borra todas las entradas de\n"
@@ -8888,11 +8834,10 @@ msgstr ""
"al canal."
#: modules/commands/cs_entrymsg.cpp:245
-#, fuzzy
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
"El comando ENTRYMSG DEL borra el mensaje dado de la lista de\n"
@@ -8901,19 +8846,18 @@ msgstr ""
"obtener listando todos los mensajes como se explica más abajo."
#: modules/commands/cs_entrymsg.cpp:250
-#, fuzzy
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
"El comando ENTRYMSG LIST muestra una lista de mensajes a ser\n"
"mostrados a los usuario al entrar al canal."
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "La opcion IMMED no está disponible en esta red."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -8955,7 +8899,7 @@ msgstr ""
"Para obtener una lista de todas las funciones cuyos niveles\n"
"pueden ser cambiados, mira HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -8973,19 +8917,18 @@ msgstr ""
"entradas que\n"
"tengan dichas marcas."
-#: modules/commands/cs_flags.cpp:435
-#, fuzzy
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
"El comando MODIFY te permite modificar la lista de acceso. Si la máscara\n"
"no está ya en la lista, se añade; después se aplican los cambios.\n"
@@ -9004,7 +8947,7 @@ msgstr ""
"El comando STATS imprime estadísticas sobre nicks almacenados y uso de "
"memoria."
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -9019,7 +8962,6 @@ msgstr ""
"si no está ya como opción predeterminada."
#: modules/commands/cs_log.cpp:258
-#, fuzzy, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9037,7 +8979,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9068,12 +9010,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "La lista de bans de %s está llena."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, c-format
msgid "The %s list has been cleared."
msgstr "La lista %s ha sido limpiada."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "La lista de AKILLs ha sido limpiada."
@@ -9092,7 +9034,7 @@ msgstr "La dirección de e-mail de %s ahora se ocultará en la salida %s INFO.
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "La dirección de e-mail de %s ahora se mostrará en la salida %s INFO."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr "Las marcas disponibles son:"
@@ -9121,11 +9063,11 @@ msgstr "Este email ha alcanzado su límite de uso de 1 usuario."
msgid "The entry message list for %s is full."
msgstr "La lista de mensajes de entrada para %s está llena."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr "Están disponibles las siguientes funciones/características:"
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9192,12 +9134,7 @@ msgstr "La máscara debe contener al menos un caracter no comodín."
msgid "The memo limit for %s may not be changed."
msgstr "El límite de memos para %s no puede ser cambiado."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "La lista de información de oper para %s está llena."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr "El nuevo display DEBE ser un nick de tu grupo %s."
@@ -9212,10 +9149,6 @@ msgstr "El nuevo display ahora es %s."
msgid "The nick %s is now being changed to %s."
msgstr "El nick %s está siendo cambiado a %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, c-format
msgid "The oper info already exists on %s."
@@ -9241,11 +9174,11 @@ msgstr ""
"El estado de acceso a los Servicios de %s ahora se mostrará en la salida %s "
"INFO."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
msgid "The session exception list is empty."
msgstr "La lista de excepciones al límite de sesión está vacía."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9320,7 +9253,7 @@ msgstr "No hay Noticias al Azar."
msgid "There is no such configuration block %s."
msgstr "No existe el bloque de configuración %s."
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, c-format
msgid "There is no such mode %s."
msgstr "No existe el modo %s."
@@ -9346,7 +9279,7 @@ msgstr "Este canal está suspendido."
msgid "This channel may not be used."
msgstr "Este canal esta prohibido."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9400,7 +9333,7 @@ msgstr ""
"de su nick ACTUAL como vhost para todos los nicks del\n"
"mismo grupo."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9416,7 +9349,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr "Este comando es un alias del comando %s."
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
msgid ""
"This command is used by several commands as a way to confirm\n"
"changes made to your account.\n"
@@ -9441,10 +9374,9 @@ msgid "This command lists information about the specified loaded module."
msgstr "Este comando lista información sobre el módulo cargado especificado. "
#: modules/commands/hs_list.cpp:136
-#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -9536,7 +9468,7 @@ msgstr ""
"Los Operadores de Servicios pueden especificar un nick para modificar\n"
"las listas auto join de otros usuarios."
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9548,7 +9480,7 @@ msgstr ""
msgid "This command reloads the module named modname."
msgstr "Este comando recarga el módulo llamado nombre-del-módulo."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr "Este comando devuelve las solicitudes de vhost."
@@ -9610,7 +9542,7 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "Este comando descarga el módulo llamado nombre-del-módulo."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr "Este comando te reenviará el email de confirmación del registro."
@@ -9628,12 +9560,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Este nick ha sido prohibido: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "Este nick ha sido recuperado por %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -9696,7 +9628,7 @@ msgstr "Top %i de %s"
msgid "Topic"
msgstr "Topic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
msgid "Topic lock"
msgstr "Bloqueo de topic"
@@ -9710,7 +9642,7 @@ msgstr "Bloqueo de topic para %s Desactivado."
msgid "Topic lock option for %s is now on."
msgstr "Bloqueo de topic para %s Activado."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
msgid "Topic retention"
msgstr "Retención de topic"
@@ -9724,7 +9656,7 @@ msgstr "Retención de topic para %s Desactivada."
msgid "Topic retention option for %s is now on."
msgstr "Retención de topic para %s Activada."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr "Topic puesto por"
@@ -9732,15 +9664,16 @@ msgstr "Topic puesto por"
msgid "Turn caps lock OFF!"
msgstr "¡Apaga las mayusculas!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
msgid "Turn chanstats statistics on or off"
msgstr "Pone las estadísticas de canal a on u off."
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
msgid "Turn nickname security on or off"
msgstr "Pone la seguridad del nick a on u off."
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
msgid "Turn protection on or off"
msgstr "Pone la protección a on u off."
@@ -9774,7 +9707,7 @@ msgstr ""
"(Sin embargo, cualquier persona que sepa tu nick podrá\n"
"comprobar tu información usando el comando INFO.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9800,7 +9733,7 @@ msgstr "Pone las estadísticas de canal a ON u OFF."
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr "Pone las estadísticas de canal para este usuario a ON u OFF."
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9829,7 +9762,7 @@ msgstr ""
"necesario. Además, los administradores de la red pueden haber\n"
"deshabilitado esta opción."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -9858,7 +9791,7 @@ msgstr ""
"necesario. Además, los administradores de la red pueden haber\n"
"deshabilitado esta opción."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr "Tipo"
@@ -9897,7 +9830,7 @@ msgstr ""
"acerca de una opción específica. Las opciones se establecerán\n"
"para el nick dado."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -9906,7 +9839,7 @@ msgstr ""
"Escribe %s%s HELP %s opción para más información\n"
"sobre una opción en particular."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -9920,8 +9853,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Descargar un módulo"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, c-format
msgid "Unable to find regex engine %s."
msgstr "Imposible encontrar el motor regex %s."
@@ -9959,7 +9892,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Kicker por subrayados"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
msgid "Unknown SET option."
msgstr "Opción SET desconocida."
@@ -9978,7 +9911,7 @@ msgstr "Comando %s desconocido."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Comando %s desconocido. \"%s%s HELP\" para ayuda."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "Caracter de modo %c desconocido e ignorado."
@@ -10001,10 +9934,9 @@ msgstr ""
"el fundador del canal."
#: modules/commands/cs_drop.cpp:74
-#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Borra el canal dado. Solo los Operadores de Servicios\n"
"pueden borrar un canal del que no son fundadores."
@@ -10017,11 +9949,10 @@ msgstr "De-suspende el nick dado"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr "Quita la suspensión de un nick para que pueda ser usado de nuevo."
-#: modules/commands/cs_updown.cpp:126
-#, fuzzy
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
"Actualiza el modo de status de un canal para el nick especificado. Si\n"
@@ -10072,30 +10003,30 @@ msgstr ""
msgid "Used on"
msgstr "Usado el"
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "Puede cambiar el topic del canal"
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr "Modificar la lista de usuarios privilegiados"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
msgid "User has been banned from the channel"
msgstr "El usuario ha sido baneado del canal"
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, c-format
msgid "User limit for %s removed."
msgstr "Límite de usuarios para %s eliminado."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, c-format
msgid "User limit for %s set to %d."
msgstr "Límite de usuarios para %s establecido a %d."
@@ -10146,12 +10077,12 @@ msgstr "VHost para el grupo %s establecido a %s@%s."
msgid "VIEW host"
msgstr "VIEW host"
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
msgid "VIEW [mask | list | id]"
msgstr "VIEW [máscara | lista | id]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr "VIEW [máscara | lista]"
@@ -10164,7 +10095,7 @@ msgstr "Valor"
msgid "Value of %s:%s changed to %s"
msgstr "El valor de %s:%s ha sido cambiado a %s"
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr "Vhost"
@@ -10202,7 +10133,7 @@ msgstr ""
"Cuando la privacidad está activada, el canal no aparecerá\n"
"en el comando %s's %s."
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
msgid ""
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
@@ -10282,7 +10213,7 @@ msgstr ""
" \n"
"La opción ALL muestra todas las estadísticas anteriores."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr "Palabra"
@@ -10291,7 +10222,7 @@ msgstr "Palabra"
msgid "You are already a member of the group of %s."
msgstr "Ya eres miembro del grupo de %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Ya estás identificado."
@@ -10351,7 +10282,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr "No puedes usar NOOP con los Servicios."
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10378,13 +10309,24 @@ msgid "You can not request a receipt when sending a memo to yourself."
msgstr ""
"No puedes solicitar una confirmación cuando te envías un memo a ti mismo."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, c-format
+msgid "You can not set the %c flag."
+msgstr "No puedes establecer la marca %c."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr ""
+"No puedes desasignar bots mientras el modo persistente esté establecido en "
+"el canal."
+
+#: modules/commands/ns_recover.cpp:143
#, c-format
msgid "You can't %s yourself!"
msgstr "¡No puedes %s a ti mismo!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
msgid "You can't add a channel to its own access list."
msgstr "No puedes añadir un canal a su propia lista de acceso."
@@ -10393,16 +10335,11 @@ msgstr "No puedes añadir un canal a su propia lista de acceso."
msgid "You can't logout %s, they are a Services Operator."
msgstr "No puedes desconectar a %s porque es un Operador de Servicios."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, c-format
msgid "You cannot %s on this network."
msgstr "No puedes %s en esta red."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "No puedes establecer la marca %c."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10413,14 +10350,7 @@ msgstr "No puedes establecer el límite de memos para %s a más de %d."
msgid "You cannot set your memo limit higher than %d."
msgstr "No puedes establecer tu límite de memos a más de %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr ""
-"No puedes desasignar bots mientras el modo persistente esté establecido en "
-"el canal."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "No puedes borrar tu direccion de e-mail en esta red."
@@ -10460,12 +10390,12 @@ msgstr "Tienes 1 memo."
msgid "You currently have no memos."
msgstr "No tienes memos."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr "No tienes acceso para establecer el modo %c."
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "No tienes acceso para cambiar los modos de %s"
@@ -10503,7 +10433,7 @@ msgstr "Has sido invitado a %s."
msgid "You have been invited to %s."
msgstr "Has sido invitado a %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "Te has identificado como %s."
@@ -10543,30 +10473,25 @@ msgstr ""
"Has alcanzado el máximo número de memos (%d). No podrás recibir más memos "
"hasta que borres algunos de los existentes."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Has sido invitado a %s."
-
#: modules/commands/ns_drop.cpp:66
msgid "You may drop any nick within your group."
msgstr "Puedes borrar cualquier nick de tu grupo."
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr "No puedes (des)bloquear el modo %c"
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
msgid "You may not change the e-mail of other Services Operators."
msgstr "No puedes cambiar el e-mail de otro Operador de Servicios."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "No puedes cambiar el e-mail de otro Operador de Servicios."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
msgid "You may not change the password of other Services Operators."
msgstr "No puedes cambiar la contraseña de otro Operador de Servicios."
@@ -10609,25 +10534,10 @@ msgstr "Debes asignar un bot al canal antes de usar este comando."
msgid "You must be a channel operator to register the channel."
msgstr "Debes ser un operador de canal para registrar el canal."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "Tienes que estar identificado para usar este comando."
-
#: modules/commands/cs_register.cpp:37
msgid "You must confirm your account before you can register a channel."
msgstr "Debes confirmar tu cuenta antes de que puedas registar un canal."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "Debes confirmar tu cuenta antes de que puedas registar un canal."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "Debes confirmar tu cuenta antes de que puedas registar un canal."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -10637,17 +10547,17 @@ msgstr ""
"Debes introducir el nombre del canal dos veces como confirmación de que "
"quieres borrar %s."
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr "Debes estar conectado más de %d segundos para registrar tu nick."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "Debes tener el privilegio %s(ME) en el canal para usar este comando."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -10661,39 +10571,17 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "Tienes que estar identificado para usar este comando."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Serás notificado cuando te envíen nuevos memos."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Serás notificado de nuevos memos cuando te conectes y en cuanto te sean "
-"enviados."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Serás notificado de nuevos memos cuando te conectes y en cuanto te sean "
"enviados."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Serás notificado de nuevos memos cuando te conectes y en cuanto te sean "
-"enviados."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Serás notificado de nuevos memos cuando te conectes."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Serás notificado cuando te envíen nuevos memos."
@@ -10705,7 +10593,7 @@ msgstr "No te será posible recibir más memos."
msgid "You will no longer be informed via email."
msgstr "No serás informado de nuevos memos via email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "No serás notificado de nuevos memos."
@@ -10733,22 +10621,22 @@ msgstr ""
"Tu IRCd no soporta vIdent's, si esto no es correcto, por favor, repórtalo "
"como posible bug."
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Tu cuenta %s ha sido creada correctamente."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
msgid "Your account is already confirmed."
msgstr "Tu cuenta ya está confirmada."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Tu cuenta expirará si no es confirmada en %s"
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Tu dirección email ha sido cambiada a %s."
@@ -10757,7 +10645,7 @@ msgstr "Tu dirección email ha sido cambiada a %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Tu dirección de email no está permitida, escoje otra diferente."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
@@ -10765,12 +10653,12 @@ msgstr ""
"Tu dirección de email no está confirmada. Para confirmarla, sigue las "
"instrucciones que se enviaron a tu email."
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Tu dirección email de %s ha sido confirmada."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, c-format
msgid "Your email has been updated to %s"
msgstr "Tu email ha sido actualizado a %s"
@@ -10827,7 +10715,7 @@ msgstr "Tu nick no está agrupado a nada, no puedes desagruparlo."
msgid "Your nick isn't registered."
msgstr "Tu nick no está registrado."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Tu nick se ha cambiado a %s"
@@ -10836,19 +10724,18 @@ msgstr "Tu nick se ha cambiado a %s"
msgid "Your oper block doesn't require logging in."
msgstr "Tu bloque de operador no requiere inicio de sesión."
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Tu contraseña ha sido reenviada a %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Tu contraseña es %s - Recuérdala para usos futuros."
#: include/language.h:77
-#, fuzzy, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
"Tu contraseña es demasiado larga. Por favor, inténtalo de nuevo con una más "
"corta."
@@ -10857,23 +10744,23 @@ msgstr ""
msgid "Your password reset request has expired."
msgstr "Tu petición de restablecimiento de contraseña ha expirado."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
msgid "Your vHost has been requested."
msgstr "Tu vHost ha sido solicitado."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Tu vhost %s ha sido activado."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Tu vhost %s@%s ha sido activado."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Tu vhost ha sido eliminado y el enmascaramiento normal restaurado."
@@ -10920,7 +10807,7 @@ msgstr "[Noticias al Azar - %s] %s"
msgid "[account] password"
msgstr "[cuenta] contraseña"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
msgid "[channel [nick]]"
msgstr "[canal [nick]]"
@@ -10968,8 +10855,8 @@ msgstr "[nick]"
msgid "[nickname [REVALIDATE]]"
msgstr "[nick [REVALIDATE]]"
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
msgid "[nickname]"
msgstr "[nick]"
@@ -10989,7 +10876,7 @@ msgstr "[+expiración] canal razón"
msgid "[Hostname hidden]"
msgstr "[Host oculto]"
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr "[Suspendido]"
@@ -10997,20 +10884,20 @@ msgstr "[Suspendido]"
msgid "[Unconfirmed]"
msgstr "[No confirmado]"
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto memo] Tu vHost solicitado ha sido aprobado."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto memo] Tu vHost solicitado ha sido rechazado."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[auto memo] Tu solicitud de vHost ha sido rechazada. Razón: %s"
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] El vHost %s ha sido solicitado por %s."
@@ -11112,12 +10999,12 @@ msgstr "segundo"
msgid "seconds"
msgstr "segundos"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, c-format
msgid "vHost for %s has been activated."
msgstr "El vHost para %s ha sido activado."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, c-format
msgid "vHost for %s has been rejected."
msgstr "El vHost para %s ha sido rechazado."
@@ -11151,39 +11038,6 @@ msgstr "{canal | nick}"
msgid "{nick | channel}"
msgstr "{nick | canal}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
msgid "{nick | channel} memo-text"
msgstr "{nick | canal} texto-del-memo"
-
-#~ msgid ""
-#~ " \n"
-#~ "The %s commands are limited to founders\n"
-#~ "(unless SECUREOPS is off). However, any user on the\n"
-#~ "VOP list or above may use the %s LIST command.\n"
-#~ " \n"
-#~ msgstr ""
-#~ " \n"
-#~ "Los comandos %s están limitados al fundador\n"
-#~ "(a menos que SECUREOPS se ponga a off). Sin embargo,\n"
-#~ "cualquier usuario en la lista VOP o superior puede usar el\n"
-#~ "comando %s LIST\n"
-#~ " \n"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "La excepción para %s (#%d) movida a la posicion %d."
-
-#~ msgid "MOVE num position"
-#~ msgstr "MOVE num posición"
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "La informacion antigua es igual a la nueva."
-
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Muestra los nicks que usan el email dado. Ten en cuenta que no\n"
-#~ "puedes usar comodines. Cuando se usa este comando, se registrará\n"
-#~ "la persona que usó el comando y el email usado."
diff --git a/language/anope.fr_FR.po b/language/anope.fr_FR.po
index 55d3684eb..4059d8790 100644
--- a/language/anope.fr_FR.po
+++ b/language/anope.fr_FR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-10-25 00:23+0200\n"
"PO-Revision-Date: 2014-10-28 18:47+0100\n"
"Last-Translator: Thomas Fargeix <t.fargeix@gmail.com>\n"
"Language-Team: French\n"
@@ -28,17 +28,17 @@ msgstr "%d canau(x) vidé(s) et %d canau(x) supprimé(s)."
msgid "%d nickname(s) dropped."
msgstr "%d pseudo(s) effacé(s)."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:222
#, c-format
msgid "%s added to %s %s list."
msgstr "%1$s ajouté à la liste des %3$s de %2$s."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:223
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s ajouté à la liste d'accès de %s avec le niveau %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:221
#, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s ajouté à la liste d'accès de %s avec le privilège %s (niveau %d)"
@@ -68,12 +68,12 @@ msgstr "%s ajouté à la liste des certificats de %s."
msgid "%s added to ignore list."
msgstr "%s ajouté à la liste d'ignore."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s ajouté à la liste des %s."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s ajouté à la liste d'AKILL."
@@ -116,7 +116,7 @@ msgstr ""
"%s%s commande. Pour plus d'informations sur\n"
"une commande spécifique, tapez %s%s %s commande.\n"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:462
#, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -133,7 +133,7 @@ msgstr ""
"d'informations sur une certaine commande, tapez\n"
"%s%s %s commande.\n"
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:469
#, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -149,7 +149,7 @@ msgstr ""
"Pour plus d'informations sur une commande spécifique, tapez\n"
"%s%s %s commande.\n"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -190,7 +190,7 @@ msgstr "%s existe déjà dans la liste des exceptions."
msgid "%s cannot be taken as times to ban."
msgstr "%s ne peut être utilisé comme nombre de fois avant un ban."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s a changé vos modes utilisateur en %s."
@@ -200,12 +200,12 @@ msgstr "%s a changé vos modes utilisateur en %s."
msgid "%s channel list:"
msgstr "Liste de canaux de %s :"
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:350
#, c-format
msgid "%s deleted from %s %s list."
msgstr "%1$s supprimé de la liste des %3$s de %2$s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:324
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s supprimé de la liste d'accès de %s."
@@ -240,12 +240,12 @@ msgstr "%s supprimé de la liste des exceptions à la limitation de sessions."
msgid "%s deleted from the %s list."
msgstr "%s supprimé de la liste des %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s supprimé de la liste d'AKILL."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:683
#, c-format
msgid "%s disabled on channel %s."
msgstr "Le niveau %s est maintenant désactivé sur le canal %s."
@@ -328,7 +328,7 @@ msgstr "%s ajouté à votre liste d'ignore."
msgid "%s is already suspended."
msgstr "%s est déjà suspendu."
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:55
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s n'est pas un pseudo ou canal enregistré qui n'est pas interdit."
@@ -392,12 +392,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s correspond à l'entrée d'auto kick %s sur %s (%s)."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:360
#, c-format
msgid "%s not found on %s %s list."
msgstr "%1$s introuvable sur la liste des %3$s de %2$s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:336 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s introuvable sur la liste d'accès de %s."
@@ -446,12 +446,12 @@ msgstr "%s non trouvé sur la liste des exceptions à la limitation de session
msgid "%s not found on the %s list."
msgstr "%s introuvable sur la liste des %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s introuvable sur la liste d'AKILL."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "%s supprimé de la liste d'accès de %s."
@@ -486,20 +486,19 @@ msgstr "%s est ignoré définitivement."
msgid "%s%s HELP %s for more information."
msgstr "%s%s HELP %s pour plus d'informations."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr "ADD pseudo user host realname"
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr "CHANGE ancien-nick nouveau-nick [user [host [realname]]]"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL pseudo"
-#: modules/commands/os_session.cpp:560
-#, fuzzy
+#: modules/commands/os_session.cpp:601
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
"Note that nick!user@host and user@host masks are invalid!\n"
@@ -513,6 +512,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -561,7 +563,7 @@ msgstr ""
"et empêche les opérateurs d'opérer sur le serveur indiqué.\n"
"REVOKE supprime cette restriction."
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:609
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -581,7 +583,7 @@ msgstr "[auto-memo] Le mémo que vous avez envoyé a %s a été vu."
msgid "[target] [password]"
msgstr "[cible] [motdepasse]"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr "adresse"
@@ -589,11 +591,11 @@ msgstr "adresse"
msgid "botname {ON|OFF}"
msgstr "nom-du-bot {ON|OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
-#: modules/extra/stats/cs_fantasy_top.cpp:51
+#: modules/extra/stats/cs_fantasy_top.cpp:51 modules/commands/cs_info.cpp:20
+#: modules/commands/cs_sync.cpp:20 modules/commands/cs_suspend.cpp:152
+#: modules/commands/cs_log.cpp:106 modules/commands/bs_assign.cpp:91
+#: modules/commands/cs_getkey.cpp:20
msgid "channel"
msgstr "canal"
@@ -617,8 +619,8 @@ msgstr "canal masque [raison]"
msgid "channel modes"
msgstr "canal modes"
-#: modules/commands/bs_assign.cpp:20 modules/commands/cs_set.cpp:264
-#: modules/commands/cs_set.cpp:962
+#: modules/commands/cs_set.cpp:264 modules/commands/cs_set.cpp:962
+#: modules/commands/bs_assign.cpp:20
msgid "channel nick"
msgstr "canal pseudo"
@@ -626,7 +628,7 @@ msgstr "canal pseudo"
msgid "channel nick [reason]"
msgstr "canal pseudo [raison]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr "canal cible [quoi]"
@@ -646,11 +648,11 @@ msgstr "canal utilisateur raison"
msgid "channel what"
msgstr "canal [quoi]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:488
msgid "channel ADD mask"
msgstr "canal ADD masque"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:497
msgid "channel ADD mask level"
msgstr "canal ADD masque niveau"
@@ -670,13 +672,13 @@ msgstr "canal ADD {pseudo | masque} [raison]"
msgid "channel APPEND topic"
msgstr "canal APPEND sujet"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:501 modules/commands/cs_xop.cpp:491
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_entrymsg.cpp:197 modules/commands/bs_badwords.cpp:374
msgid "channel CLEAR"
msgstr "canal CLEAR"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:678
msgid "channel CLEAR [what]"
msgstr "canal CLEAR [quoi]"
@@ -688,7 +690,7 @@ msgstr "canal CLEAR [ALL]"
msgid "channel DEL num"
msgstr "canal DEL num"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:498 modules/commands/cs_xop.cpp:489
msgid "channel DEL {mask | entry-num | list}"
msgstr "canal DEL {masque | numéro-entrée | liste}"
@@ -704,7 +706,7 @@ msgstr "canal DEL {mot | numéro-entrée | liste}"
msgid "channel ENFORCE"
msgstr "canal ENFORCE"
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:742 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr "canal LIST"
@@ -712,28 +714,28 @@ msgstr "canal LIST"
msgid "channel LIST [mask | entry-num | list]"
msgstr "canal LIST [masque | numéro-entrée | liste]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:499 modules/commands/cs_xop.cpp:490
+#: modules/commands/bs_badwords.cpp:373
msgid "channel LIST [mask | list]"
msgstr "canal LIST [masque | liste]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr "canal LIST [masque | +flags]"
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:676
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "canal LOCK {ADD|DEL|SET|LIST} [quoi]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_access.cpp:743
msgid "channel RESET"
msgstr "canal RESET"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:677
msgid "channel SET modes"
msgstr "canal SET modes"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:740
msgid "channel SET type level"
msgstr "canal SET type niveau"
@@ -741,7 +743,7 @@ msgstr "canal SET type niveau"
msgid "channel VIEW [mask | entry-num | list]"
msgstr "canal VIEW [masque | numéro-entrée | liste]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:500
msgid "channel VIEW [mask | list]"
msgstr "canal VIEW [masque | liste]"
@@ -757,7 +759,7 @@ msgstr "canal [pseudo]"
msgid "channel [parameters]"
msgstr "canal [paramètres]"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_mode.cpp:749 modules/commands/cs_status.cpp:20
msgid "channel [user]"
msgstr "canal [user]"
@@ -769,7 +771,7 @@ msgstr "canal [+expiration] [raison]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "canal [+expiration] {pseudo | masque} [raison]"
-#: modules/commands/cs_flags.cpp:374
+#: modules/commands/cs_flags.cpp:373
msgid "channel [MODIFY] mask changes"
msgstr "canal [MODIFY] masque modifications"
@@ -781,7 +783,7 @@ msgstr "canal [SET] [sujet]"
msgid "channel [UNLOCK|LOCK]"
msgstr "canal [UNLOCK|LOCK]"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
+#: modules/commands/greet.cpp:20 modules/commands/bs_assign.cpp:154
#: modules/fantasy.cpp:20
msgid "channel {ON|OFF}"
msgstr "canal {ON|OFF}"
@@ -805,7 +807,7 @@ msgstr "canal {ON|OFF} [ttb [num]]"
msgid "channel {ON|OFF} [ttb]"
msgstr "canal {ON|OFF} [ttb]"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:741
msgid "channel {DIS | DISABLE} type"
msgstr "canal {DIS | DISABLE} type"
@@ -813,13 +815,13 @@ msgstr "canal {DIS | DISABLE} type"
msgid "channel {ON | LEVEL | OFF}"
msgstr "canal {ON | LEVEL | OFF}"
+#: modules/extra/stats/m_chanstats.cpp:10 modules/commands/cs_set.cpp:72
+#: modules/commands/cs_set.cpp:333 modules/commands/cs_set.cpp:398
+#: modules/commands/cs_set.cpp:470 modules/commands/cs_set.cpp:633
+#: modules/commands/cs_set.cpp:695 modules/commands/cs_set.cpp:759
+#: modules/commands/cs_set.cpp:823 modules/commands/cs_set.cpp:1048
#: modules/commands/cs_list.cpp:181 modules/commands/bs_kick.cpp:781
#: modules/commands/bs_kick.cpp:846 modules/commands/cs_topic.cpp:21
-#: modules/commands/cs_set.cpp:72 modules/commands/cs_set.cpp:333
-#: modules/commands/cs_set.cpp:398 modules/commands/cs_set.cpp:470
-#: modules/commands/cs_set.cpp:633 modules/commands/cs_set.cpp:695
-#: modules/commands/cs_set.cpp:759 modules/commands/cs_set.cpp:823
-#: modules/commands/cs_set.cpp:1048 modules/extra/stats/m_chanstats.cpp:10
msgid "channel {ON | OFF}"
msgstr "canal XOP {ON | OFF}"
@@ -827,7 +829,7 @@ msgstr "canal XOP {ON | OFF}"
msgid "email"
msgstr "email"
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr "langue"
@@ -844,7 +846,7 @@ msgstr "message"
msgid "modname"
msgstr "nom-module"
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr "nouvel-affichage"
@@ -852,9 +854,10 @@ msgstr "nouvel-affichage"
msgid "new-password"
msgstr "nouveau-motdepasse"
-#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/cs_seen.cpp:258 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_del.cpp:20 modules/commands/hs_del.cpp:60
+#: modules/commands/hs_request.cpp:193
msgid "nick"
msgstr "pseudo"
@@ -882,12 +885,12 @@ msgstr "pseudo nouveau-pseudo "
msgid "nick [reason]"
msgstr "pseudo [raison]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
+#: modules/commands/ns_suspend.cpp:161 modules/commands/ns_getpass.cpp:20
#: modules/commands/ns_drop.cpp:19
msgid "nickname"
msgstr "pseudo"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr "pseudo adresse"
@@ -895,7 +898,7 @@ msgstr "pseudo adresse"
msgid "nickname email"
msgstr "pseudo email"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr "pseudo langue"
@@ -903,11 +906,11 @@ msgstr "pseudo langue"
msgid "nickname message"
msgstr "pseudo message"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr "pseudo nouvel-affichage"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "pseudo nouveau-motdepasse"
@@ -915,7 +918,7 @@ msgstr "pseudo nouveau-motdepasse"
msgid "nickname [parameter]"
msgstr "pseudo [paramètre]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:132
msgid "nickname [password]"
msgstr "pseudo [motdepasse]"
@@ -927,14 +930,14 @@ msgstr "pseudo [+expiration] [raison]"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "pseudo {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
-#: modules/extra/stats/m_chanstats.cpp:122
+#: modules/extra/stats/m_chanstats.cpp:122 modules/commands/ns_set.cpp:294
+#: modules/commands/ns_set.cpp:610 modules/commands/ns_set.cpp:961
+#: modules/commands/ns_set.cpp:1052 modules/commands/ns_set.cpp:1081
+#: modules/commands/ns_list.cpp:252
msgid "nickname {ON | OFF}"
msgstr "pseudo {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "pseudo {ON | QUICK | IMMED | OFF}"
@@ -990,7 +993,7 @@ msgstr "modèle [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "nom-du-serveur [raison]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr "pseudo modes"
@@ -998,7 +1001,7 @@ msgstr "pseudo modes"
msgid "user [reason]"
msgstr "user [raison]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:492
#, c-format
msgid ""
" \n"
@@ -1016,7 +1019,7 @@ msgstr ""
"autres choses de ce genre. L'abus de %s entraînera, au minimum,\n"
"la perte du(des) pseudo(s) concernés."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
msgid ""
" \n"
"SNLINE ADD adds the given realname mask to the SNLINE\n"
@@ -1050,7 +1053,7 @@ msgstr ""
"Note : Puisque le masque de realname peut contenir des espaces, le\n"
"séparateur entre le masque et la raison est le caractère ':'."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1078,7 +1081,7 @@ msgstr ""
"L'échéance de SQLINE par défaut peut être trouvée avec la commande\n"
"STATS AKILL."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:488
#, c-format
msgid ""
" \n"
@@ -1194,7 +1197,7 @@ msgstr ""
"Note : pour enregistrer un canal, vous devez d'abord\n"
"enregistrer votre pseudo."
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1221,7 +1224,7 @@ msgstr ""
"plus d'informations sur comment donner des privilèges\n"
"à d'autres utilisateurs du canal.\n"
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:482
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1232,7 +1235,7 @@ msgstr ""
"Les Opérateurs des Services peuvent également effacer n'importe quel\n"
"pseudo et peuvent voir la liste d'accès pour n'importe quel pseudo."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1261,7 +1264,7 @@ msgstr ""
"supprimés après le délai donné. Le définir à 0 désactive l'expiration "
"automatique des bans."
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:549
#, c-format
msgid ""
" \n"
@@ -1345,7 +1348,7 @@ msgstr ""
"La commande AKICK CLEAR vide la liste des kicks\n"
"automatiques."
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
msgid ""
" \n"
"The AKILL DEL command removes the given mask from the\n"
@@ -1387,7 +1390,7 @@ msgstr ""
" \n"
"La commande AKILL CLEAR vide la liste des AKILL."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
msgid ""
" \n"
"The SNLINE DEL command removes the given mask from the\n"
@@ -1429,7 +1432,7 @@ msgstr ""
" \n"
"SNLINE CLEAR vide toutes les entrées de la liste des SNLINE."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1505,7 +1508,7 @@ msgstr ""
"Tapez %s%s HELP command pour obtenir de l'aide sur\n"
"les commandes ci-dessus."
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:165
#, c-format
msgid " %s is online using this oper block."
msgstr " %s est connecté en utilisant ce bloc oper."
@@ -1520,7 +1523,7 @@ msgstr " La commande %s de %s est liée à %s"
msgid " Providing service: %s"
msgstr " Fournit le service : %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:161
msgid " This oper is configured in the configuration file."
msgstr " Cet oper est configuré dans le fichier de configuration."
@@ -1534,7 +1537,7 @@ msgstr " Chargé à : %p"
msgid " but %s mysteriously dematerialized."
msgstr " mais %s s'est mystérieusement dématérialisé."
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1546,7 +1549,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr "\"Jupiter\" un serveur"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:159
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1566,17 +1569,17 @@ msgstr "%d %b %Y %H:%M:%S %Z"
msgid "%c is an unknown status mode."
msgstr "%c est un mode de statut inconnu."
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:415
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c n'est pas verrouillé sur %s."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:411
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s a été déverrouillé sur %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "%d accès de %s ont été clonés sur %s."
@@ -1603,8 +1606,8 @@ msgstr ""
"%lu pseudos sont stockés dans la base de données, utilisant %.2Lf ko de "
"mémoire."
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:244 modules/commands/cs_xop.cpp:379
+#: modules/commands/cs_xop.cpp:457
#, c-format
msgid "%s %s list is empty."
msgstr "La liste des %2$s de %1$s est vide."
@@ -1705,9 +1708,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr "%s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:243 modules/commands/cs_access.cpp:347
+#: modules/commands/cs_access.cpp:452 modules/commands/cs_access.cpp:465
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "La liste d'accès de %s est vide."
@@ -1717,7 +1720,7 @@ msgstr "La liste d'accès de %s est vide."
msgid "%s added to %s's auto join list."
msgstr "%s ajouté à la liste de JOIN automatiques de %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s existe déjà."
@@ -1738,7 +1741,7 @@ msgstr "La liste des mots interdits de %s est vide."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s ne peut être successeur du canal %s car il en est le fondateur."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
+#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:272
#: modules/pseudoclients/hostserv.cpp:78
#, c-format
msgid "%s commands:"
@@ -1841,7 +1844,7 @@ msgstr "%s est un client des services."
msgid "%s is a network service."
msgstr "%s est un service du réseau."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s est déjà couvert par %s."
@@ -1856,7 +1859,7 @@ msgstr "%s est déjà sur la liste de JOIN automatiques de %s."
msgid "%s is an unconfirmed nickname."
msgstr "%s est un pseudo non confirmé."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:431
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1882,7 +1885,7 @@ msgstr "%s est désactivé"
msgid "%s is enabled"
msgstr "%s est activé"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, c-format
msgid "%s is not a valid IP address."
msgstr "%s n'est pas une adresse IP valide."
@@ -1928,7 +1931,7 @@ msgstr "%s est sur le canal en ce moment (en tant que %s) !"
msgid "%s is on the channel right now!"
msgstr "%s est sur le canal en ce moment même !"
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:441
#, c-format
msgid "%s list for %s"
msgstr "Liste de %s pour %s"
@@ -1938,7 +1941,7 @@ msgstr "Liste de %s pour %s"
msgid "%s list is empty."
msgstr "La liste des %s est vide."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:360
#, c-format
msgid "%s locked on %s."
msgstr "%s est verrouillé sur %s."
@@ -1994,7 +1997,7 @@ msgstr ""
"%s vous notifiera désormais des mémos quand vous vous connecterez ou "
"enlèverez /AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) ajouté à la liste des bots."
@@ -2048,11 +2051,11 @@ msgstr "(Déconnecté)"
msgid "(by %s on %s) %s"
msgstr "(par %s sur %s) %s"
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:708
msgid "(disabled)"
msgstr "(désactivé)"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:710
msgid "(founder only)"
msgstr "(fondateur seulement)"
@@ -2116,7 +2119,7 @@ msgstr "%s est toujours connecté."
msgid "<unknown>"
msgstr "<inconnu>"
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2172,7 +2175,7 @@ msgstr "ADD cible info"
msgid "ADD text"
msgstr "ADD texte"
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr "ADD [+expiration] masque limite raison"
@@ -2188,11 +2191,11 @@ msgstr "ADD [pseudo] masque"
msgid "ADD [nickname] [fingerprint]"
msgstr "ADD [pseudo] [fingerprint]"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+expiration] masque raison"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+expiration] masque:raison"
@@ -2200,15 +2203,15 @@ msgstr "ADD [+expiration] masque:raison"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiration] entrée raison"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr "ADDIP nom.du.serveur ip"
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr "ADDSERVER nom.du.serveur [nom.de.la.zone]"
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr "ADDZONE nom.de.la.zone"
@@ -2223,8 +2226,8 @@ msgstr ""
msgid "AKILL all users on a specific channel"
msgstr "AKILL tous les utilisateurs d'un canal spécifique."
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "La liste d'AKILL est vide."
@@ -2255,18 +2258,18 @@ msgstr "Le niveau doit être compris entre %d et %d inclus."
msgid "Access level must be non-zero."
msgstr "Le niveau d'accès doit être différent de zéro."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:692
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Configuration des niveaux d'accès du canal %s :"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:732
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr ""
"Les niveaux d'accès de %s ont été réinitialisés à leur valeur par défaut."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:437
#, c-format
msgid "Access list for %s:"
msgstr "Liste d'accès de %s :"
@@ -2280,14 +2283,6 @@ msgstr ""
"L'accès à cette commande requiert que la permission %s soit présente pour "
"votre type d'opérateur."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Active les fonctions de sécurité"
@@ -2296,7 +2291,7 @@ msgstr "Active les fonctions de sécurité"
msgid "Activate the requested vHost for the given nick."
msgstr "Active la demande de vHost pour le pseudo donné."
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -2323,7 +2318,7 @@ msgstr ""
"pseudo ou\n"
"le canal."
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr "Adresse IP %s ajoutée à %s."
@@ -2360,12 +2355,6 @@ msgstr "Serveur %s ajouté."
msgid "Added zone %s."
msgstr "Zone %s ajoutée."
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
#: modules/commands/ns_register.cpp:90
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
@@ -2390,7 +2379,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Toutes les O:lines de %s ont été réinitialisées."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Tous les kicks automatiques de %s ont été clonés sur %s."
@@ -2400,16 +2389,11 @@ msgstr "Tous les kicks automatiques de %s ont été clonés sur %s."
msgid "All available commands for %s:"
msgstr "Toutes les commandes disponibles pour %s :"
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Tous les mots interdits de %s ont été clonés sur %s."
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Tous les kicks automatiques de %s ont été clonés sur %s."
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Toutes les news de connexion ont été supprimées."
@@ -2419,12 +2403,12 @@ msgstr "Toutes les news de connexion ont été supprimées."
msgid "All memos for channel %s have been deleted."
msgstr "Tous les mémos du canal %s ont été supprimés."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr "Tous les modes ont été retirés de %s."
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:360
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2449,7 +2433,7 @@ msgstr "Tous les opérateurs de %s ont été supprimés."
msgid "All random news items deleted."
msgstr "Toutes les news aléatoires ont été supprimées."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Tous les paramètres de %s ont été clonés sur %s."
@@ -2460,13 +2444,13 @@ msgid "All user modes on %s have been synced."
msgstr "Tous les modes utilisateurs de %s ont été synchronisés."
#: modules/commands/hs_group.cpp:60
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Tous les vhosts du groupe %s ont été changés en %s"
#: modules/commands/hs_group.cpp:58
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Tous les vhosts du groupe %s ont été changés en %s@%s"
#: src/access.cpp:41
@@ -2591,7 +2575,7 @@ msgstr ""
"les utilisateurs connectés au réseau. Le message sera envoyé\n"
"avec le pseudo %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
msgid ""
"Allows Services Operators to change modes for any channel.\n"
"Parameters are the same as for the standard /MODE command.\n"
@@ -2604,7 +2588,7 @@ msgstr ""
"canal. Si CLEAR ALL est indiqué, alors tous les modes et statuts des\n"
"utilisateurs sont supprimés."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
msgid ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
@@ -2613,7 +2597,7 @@ msgstr ""
"quel utilisateur. Les paramètres sont les mêmes que pour la commande\n"
"/MODE normale."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
msgid ""
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
@@ -2689,7 +2673,7 @@ msgstr ""
" \n"
"Cette commande ne fonctionnera pas sur les Opérateurs IRC."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
"a user matching an AKILL mask attempts to connect, Services\n"
@@ -2730,7 +2714,7 @@ msgstr ""
"celle par défaut. L'échéance par défaut pour les AKILLs peut \n"
"être consultée par la commande STATS AKILL."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2742,17 +2726,14 @@ msgstr ""
"de se connecter, les Services n'autoriseront pas la session IRC\n"
"à se poursuivre."
-#: modules/commands/os_sxline.cpp:670
-#, fuzzy
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
"Permet aux Opérateurs des Services de manipuler la liste de SQLINE.\n"
"Si un utilisateur avec un pseudo correspondant à un masque SQLINE\n"
@@ -2761,7 +2742,7 @@ msgstr ""
"Si le premier caractère du masque est #, les services empêcheront\n"
"d'utiliser les canaux correspondants au masque."
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2815,7 +2796,6 @@ msgstr ""
"sessions pour certains hôtes et groupes d'hôtes."
#: modules/commands/cs_topic.cpp:193
-#, fuzzy
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2823,9 +2803,8 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
"Permet de manipuler le topic du canal indiqué.\n"
"La commande SET définit le topic du canal avec le topic donné\n"
@@ -2837,7 +2816,7 @@ msgstr ""
"modifiable,\n"
"sauf via cette commande."
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -2866,7 +2845,7 @@ msgstr ""
" \n"
"Options disponibles :"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:248
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2896,7 +2875,7 @@ msgstr ""
"Exemple :\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2906,7 +2885,7 @@ msgstr ""
"le pseudo donné. Si MSG est activé, ils utiliseront des messages,\n"
"sinon ils utiliseront des notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3000,7 +2979,7 @@ msgstr ""
"création ou le nombre de canaux auxquels il a été\n"
"assigné."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:574
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
@@ -3032,15 +3011,15 @@ msgstr ""
"ensuite configurer le bot pour qu'il convienne à\n"
"vos besoins sur ce canal."
-#: data/chanserv.example.conf:1200
+#: data/chanserv.example.conf:1193
msgid "Associate a URL with the channel"
msgstr "Associe un URL à un canal"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr "Associe un URL avec ce compte"
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
msgid "Associate a URL with your account"
msgstr "Attribue un URL à votre compte"
@@ -3048,11 +3027,11 @@ msgstr "Attribue un URL à votre compte"
msgid "Associate a greet message with your nickname"
msgstr "Associe un message d'accueil à votre pseudo"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1194
msgid "Associate an E-mail address with the channel"
msgstr "Associe une adresse email au canal"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Associe une adresse email à votre pseudo"
@@ -3060,11 +3039,11 @@ msgstr "Associe une adresse email à votre pseudo"
msgid "Associate oper info with a nick or channel"
msgstr "Associe une info oper à un pseudo ou un canal"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Associe une adresse email donnée à un pseudo"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3074,7 +3053,7 @@ msgstr ""
"sera affichée lorsque quelqu'un demandera des informations \n"
"sur votre pseudo avec la commande INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3103,16 +3082,16 @@ msgstr "Protect automatique lors du join"
msgid "Automatic voice on join"
msgstr "Voice automatique lors du join"
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:194
#, c-format
msgid "Available commands for %s:"
msgstr "Aide disponible pour %s :"
-#: modules/commands/os_oper.cpp:176
+#: modules/commands/os_oper.cpp:173
msgid "Available opertypes:"
msgstr "Types d'opérateurs disponibles :"
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:216
#, c-format
msgid "Available privileges for %s:"
msgstr "Privilèges disponibles pour %s :"
@@ -3139,7 +3118,7 @@ msgstr "La liste des mots interdits est maintenant vide."
msgid "Ban expiry may not be longer than 1 day."
msgstr "Le délai d'expiration ne peut pas être plus d'un jour."
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, c-format
msgid "Ban on %s expires in %s."
msgstr "Le ban sur %s expire dans %s."
@@ -3157,7 +3136,7 @@ msgstr "Le type de ban du canal %s est maintenant le numéro %d."
msgid "Bans a given nick or mask on a channel"
msgstr "Bannit un pseudo ou un masque sur un canal"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3184,7 +3163,7 @@ msgstr "Bans appliqués sur %s."
msgid "Bolds kicker"
msgstr "Kicker de caractères gras"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Le bot %s existe déjà."
@@ -3199,12 +3178,12 @@ msgstr "Le bot %s n'existe pas."
msgid "Bot %s has been assigned to %s."
msgstr "Le bot %s a été assigné à %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Le bot %s a été changé en %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Le bot %s a été supprimé."
@@ -3234,12 +3213,12 @@ msgstr "Le bot ne kickera pas les OPs du canal %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Le bot ne kickera pas les voices du canal %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, c-format
msgid "Bot %s is not changeable."
msgstr "Le bot %s n'est pas modifiable."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, c-format
msgid "Bot %s is not deletable."
msgstr "Le bot %s ne peut pas être supprimé."
@@ -3253,23 +3232,23 @@ msgstr "Les bans du bot expireront automatiquement après %s."
msgid "Bot bans will no longer automatically expire."
msgstr "Le bans du bot n'expireront plus automatiquement."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Les hosts des bots ne doivent contenir que %d caractères."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
msgid "Bot hosts may only contain valid host characters."
msgstr ""
"Les hosts des bots ne doivent contenir que des caractères valides pour un "
"host."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Les ident des bots ne doivent contenir que %d caractères."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
msgid "Bot idents may only contain valid ident characters."
msgstr ""
"Les ident des bots ne doivent contenir que des caractères valides pour un "
@@ -3288,12 +3267,12 @@ msgstr "Liste des bots :"
msgid "Bot nick"
msgstr "Pseudo du bot"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Les pseudos des bots ne doivent contenir que %d caractères."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
msgid "Bot nicks may only contain valid nick characters."
msgstr "Les pseudos des bots ne peuvent contenir que des caractères valides."
@@ -3385,8 +3364,8 @@ msgstr "Le bot ne kickera plus le flood."
msgid "Bot won't kick for repeats anymore."
msgstr "Le bot ne kickera plus les répétitions."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:470 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr "Par"
@@ -3419,12 +3398,12 @@ msgstr ""
"canal donné, à condition qu'il n'ait pas déjà été lu lorsque vous\n"
"utilisez la commande."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Impossible de cloner le canal %s sur lui-même !"
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:303
msgid "Cannot send mail now; please retry a little later."
msgstr ""
"Impossible d'envoyer un email maintenant, veuillez réessayez un peu\n"
@@ -3496,20 +3475,20 @@ msgstr "ChanServ est requis pour activer les canaux persistants sur ce réseau."
msgid "Change channel modes"
msgstr "Modifie les modes des canaux"
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Change le mode de communication des Services"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
msgid "Change user modes"
msgstr "Modifie les modes des utilisateurs."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Modes utilisateurs de %s changés en %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3518,7 +3497,7 @@ msgstr ""
"pseudos dans les Services. Le nouvel affichage DOIT être un\n"
"pseudo de ce groupe."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3535,7 +3514,7 @@ msgstr ""
"Change le fondateur d'un canal. Le nouveau pseudo doit être\n"
"enregistré."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3547,7 +3526,7 @@ msgstr ""
"commande qu'il a envoyé). La langue doit être choisie\n"
"dans la liste suivante des langues supportées :"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3559,13 +3538,13 @@ msgstr ""
"commande que vous avez envoyé). La langue doit être choisi\n"
"dans la liste suivante des langues supportées :"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
"Change le mot de passe utilisé pour s'identifier en tant\n"
"que propriétaire du pseudo."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3664,12 +3643,12 @@ msgstr "Le canal %s expirera."
msgid "Channel %s will not expire."
msgstr "Le canal %s n'expirera pas."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:482
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "La liste %2$s de %1$s est maintenant vide."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:484 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "La liste d'accès de %s est maintenant vide."
@@ -3679,7 +3658,7 @@ msgstr "La liste d'accès de %s est maintenant vide."
msgid "Channel %s akick list has been cleared."
msgstr "La liste de kicks automatiques de %s est maintenant vide."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:428
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Le canal %s n'a pas de modes verrouillés."
@@ -3703,8 +3682,8 @@ msgstr "Liste des canaux :"
msgid "Channel stats for %s on %s:"
msgstr "Statistiques de canal pour %s sur %s :"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:96
msgid "Channels may not be on access lists."
msgstr "Les canaux ne peuvent pas ajoutés aux listes d'accès."
@@ -3862,7 +3841,7 @@ msgstr "Configure les kickers pour les caractères soulignés"
msgid "Confirm a passcode"
msgstr "Confirme un mot-code"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:675
msgid "Control modes and mode locks on a channel"
msgstr "Contrôle les modes et les modes verrouillés sur un canal"
@@ -3873,12 +3852,11 @@ msgstr ""
"Contrôle quels messages sont envoyés aux utilisateurs lorsqu'ils joignent le "
"canal."
-#: modules/commands/cs_clone.cpp:241
-#, fuzzy
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Copie tous les paramètres, accès, akicks, etc. de canal sur le canal\n"
@@ -3886,37 +3864,37 @@ msgstr ""
"alors seuls ces paramètres sont clonés.\n"
"Vous devez être fondateur de canal et cible."
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "Copie tous les paramètres d'un canal à un autre"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/cs_mode.cpp:433 modules/commands/os_session.cpp:552
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_news.cpp:156
+#: modules/commands/bs_info.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_sxline.cpp:199
msgid "Created"
msgstr "Créé"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/cs_mode.cpp:433 modules/commands/os_ignore.cpp:266
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_news.cpp:156
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_forbid.cpp:346
msgid "Creator"
msgstr "Créateur"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Liste de %s actuelle :"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
msgid "Current AKILL list:"
msgstr "Liste d'AKILL actuelle :"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Liste actuelle des exceptions à la limitation de sessions :"
@@ -3964,12 +3942,12 @@ msgstr "DEL [pseudo] fingerprint"
msgid "DEL [nickname] mask"
msgstr "DEL [pseudo] masque"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {masque | num | liste | id}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
msgid "DEL {mask | entry-num | list}"
msgstr "DEL {masque | num | liste}"
@@ -3985,19 +3963,19 @@ msgstr "DEL {num | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} entrée"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr "DELIP nom.du.serveur ip"
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr "DELSERVER nom.du.serveur [nom.de.la.zone]"
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr "DELZONE nom.de.la.zone"
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
msgid "DEPOOL server.name"
msgstr "DEPOOL nom.du.serveur"
@@ -4012,7 +3990,7 @@ msgstr ""
msgid "Date/Time"
msgstr "Date/Heure"
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4141,12 +4119,12 @@ msgstr "Efface un ou des mémos"
msgid "Delete the vhost of another user"
msgstr "Supprime le vhost d'un autre pseudo"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:309
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "%1$d entrées supprimées de la liste des %3$s de %2$s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:275
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "%d entrées supprimées de la liste d'accès de %s."
@@ -4177,7 +4155,7 @@ msgstr "%d entrées supprimées de la liste de %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "%d entrées supprimées de la liste d'AKILL."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:273
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "1 entrée supprimée de la liste d'accès de %s."
@@ -4211,7 +4189,7 @@ msgstr "1 entrée supprimée de la liste d'AKILL."
msgid "Deleted info from %s."
msgstr "Information supprimée de %s."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:307
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Une entrée a été supprimée de la liste %2$s de %1$s."
@@ -4269,13 +4247,13 @@ msgstr ""
"Supprime tous les vhosts pour tous les pseudos du même\n"
"groupe que le pseudo donné."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr "%s retiré de la pool."
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
+#: modules/commands/cs_access.cpp:789 modules/commands/cs_list.cpp:75
msgid "Description"
msgstr "Description"
@@ -4427,12 +4405,12 @@ msgstr ""
"est effacé, vous perdez tous les accès et les canaux que vous possédez.\n"
"N'importe quel utilisateur pourra prendre le contrôle de ce pseudo."
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "L'adresse email pour %s a été changée en %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "L'adresse email pour %s a été effacée."
@@ -4487,8 +4465,8 @@ msgid "Email address"
msgstr "Adresse email"
#: modules/commands/ns_getemail.cpp:41
-#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+#, c-format
+msgid "Email matched: %s to %s."
msgstr "Email trouvé : %s pour %s."
#: modules/fantasy.cpp:19
@@ -4499,7 +4477,7 @@ msgstr "Active les commandes fantaisistes"
msgid "Enable greet messages"
msgstr "Active les messages d'accueil"
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr "Active ou désactive le maintien des modes"
@@ -4530,7 +4508,7 @@ msgstr ""
"canal\n"
"et tenteront de les remettre la prochaine fois que le canal sera créé."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4543,7 +4521,7 @@ msgstr ""
"et tenteront de les remettre la prochaine fois que cet utilisateur se "
"connectera."
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4633,11 +4611,10 @@ msgstr ""
"en utilisant l'accès/la commande qop."
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Active ou désactive le contrôle des OPs sur un canal.\n"
"Lorsque le contrôle des OPs est actif, les utilisateurs \n"
@@ -4659,7 +4636,7 @@ msgstr ""
"la prochaine fois que le canal sera créé. "
#: modules/commands/cs_set.cpp:603
-#, fuzzy, c-format
+#, c-format
msgid ""
"Enables or disables the persistent channel setting.\n"
"When persistent is set, the service bot will remain\n"
@@ -4677,7 +4654,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -4700,20 +4677,20 @@ msgstr ""
"activée et désactivée pour le canal. De plus les services activeront\n"
"ou désactiveront ce mode lorsque la persistance est modifiée."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
msgid "End of AKILL list."
msgstr "Fin de la liste des AKILL."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:442
msgid "End of access list"
msgstr "Fin de la liste d'accès."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Fin de la liste d'accès - %d/%d correspondances affichées."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Fin de la liste d'accès."
@@ -4751,7 +4728,7 @@ msgstr "Fin de la liste des interdits."
msgid "End of list - %d channels shown."
msgstr "Fin de la liste - %d canaux affichés."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Fin de la liste - %d/%d correspondances affichées."
@@ -4802,8 +4779,8 @@ msgstr ""
"jusqu'à ce que leur nombre ne dépasse plus la limite du canal, si elle est "
"définie."
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Français"
@@ -4888,31 +4865,36 @@ msgstr ""
" CERT LIST\n"
" Affiche votre liste actuelle de certificats."
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "L'exception pour %s (#%d) a été déplacée à la position %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "L'exception pour %s a été changée pour %d sessions."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/chanserv.cpp:460
+#: modules/pseudoclients/nickserv.cpp:560
+#: modules/pseudoclients/nickserv.cpp:565 modules/commands/ns_group.cpp:315
+#: modules/commands/os_session.cpp:552 modules/commands/os_ignore.cpp:266
+#: modules/commands/os_akill.cpp:355 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_sxline.cpp:199
msgid "Expires"
msgstr "Expire"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Expiration et raison mises à jour pour %s."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "L'expiration de %s a été changée."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantaisie"
@@ -4940,16 +4922,16 @@ msgstr "Le fingerprint %s existe déjà dans la liste de certificats de %s."
msgid "Fingerprint %s is already in use."
msgstr "L'empreinte %s est déjà utilisée."
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr "Flags"
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Les flags pour %s sur %s sont maintenant +%s"
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Liste de flags pour %s"
@@ -5027,7 +5009,7 @@ msgstr "Le fondateur de %s est maintenant %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "La commande GETPASS est indisponible car le chiffrement est utilisé."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "L'utilisateur fantôme utilisant votre pseudo a été déconnecté."
@@ -5035,7 +5017,7 @@ msgstr "L'utilisateur fantôme utilisant votre pseudo a été déconnecté."
msgid "Give Operflags to a certain user"
msgstr "Donne certains Operflags à un utilisateur"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:847
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -5044,7 +5026,7 @@ msgstr ""
"Donne le statut %s au pseudo choisi sur un canal. Si pseudo n'est\n"
"pas précisé vous aurez le statut %s."
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:830
#, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Vous donne à vous ou à un nick spécifié, un accès %s sur un canal"
@@ -5119,10 +5101,6 @@ msgstr "Je ne sais pas qui est %s."
msgid "I've never seen %s on this channel."
msgstr "Je n'ai jamais vu %s sur ce canal."
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
msgid "INFO [type]"
msgstr "INFO [type]"
@@ -5131,12 +5109,12 @@ msgstr "INFO [type]"
msgid "IP"
msgstr "IP"
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, c-format
msgid "IP %s already exists for %s."
msgstr "L'adresse IP %s existe déjà pour %s."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, c-format
msgid "IP %s does not exist for %s."
msgstr "L'adresse IP %s n'existe pas pour %s."
@@ -5145,8 +5123,8 @@ msgstr "L'adresse IP %s n'existe pas pour %s."
msgid "Identify yourself with your password"
msgstr "Vous identifie avec votre mot de passe"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:200
+#: modules/pseudoclients/nickserv.cpp:206
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Si vous n'en changez pas d'ici %s, je changerais votre pseudo."
@@ -5163,7 +5141,7 @@ msgstr "La liste des ignorés est vide."
msgid "Ignore list:"
msgstr "Liste des ignorés :"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
msgid "Immediate protection"
msgstr "Protection immédiate"
@@ -5235,7 +5213,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Valeur minimale invalide. Elle doit être un entier supérieur à 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr "Valeur pour LIMIT invalide. Cette valeur doit être un nombre."
@@ -5252,16 +5230,16 @@ msgstr "Kicker d'italique"
msgid "Join a group"
msgstr "Rejoint un groupe"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/cs_set.cpp:1358 modules/commands/ns_set.cpp:1294
msgid "Keep modes"
msgstr "Maintien des modes"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:582
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Le maintien des modes pour %s est maintenant inactif."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:576
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Le maintien des modes pour %s est maintenant actif."
@@ -5279,7 +5257,7 @@ msgstr "La clé du canal %s est %s."
msgid "Kick a user from a channel"
msgstr "Expulse un utilisateur d'un canal"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr "A kické %d/%d utilisateurs correspondant à %s sur %s."
@@ -5288,7 +5266,7 @@ msgstr "A kické %d/%d utilisateurs correspondant à %s sur %s."
msgid "Kicks a specified nick from a channel"
msgstr "Expulse le pseudo spécifié d'un canal"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
@@ -5318,17 +5296,17 @@ msgstr "LIMIT appliquée sur %s, %d utilisateurs supprimés."
msgid "LIST threshold"
msgstr "LIST seuil"
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
msgid "LIST [mask | list | id]"
msgstr "LIST [masque | liste | id]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr "LIST [masque] [liste]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_access.cpp:104 modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_cert.cpp:260
msgid "LIST [nickname]"
msgstr "LIST [pseudo]"
@@ -5336,15 +5314,10 @@ msgstr "LIST [pseudo]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [texte|numéro]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Votre langue est maintenant le Français."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Le successeur de %s est désormais %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5354,7 +5327,7 @@ msgstr "Le dernier mémo envoyé à %s a été supprimé."
msgid "Last quit message"
msgstr "Dernier message de quit"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:470 modules/commands/ns_info.cpp:92
msgid "Last seen"
msgstr "Dernière connexion"
@@ -5362,7 +5335,7 @@ msgstr "Dernière connexion"
msgid "Last seen address"
msgstr "Dernière adresse vue"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:263
msgid "Last topic"
msgstr "Dernier topic"
@@ -5374,28 +5347,28 @@ msgstr "Utilisé dernièrement"
msgid "Last usermask"
msgstr "Dernier usermask"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:457 modules/commands/cs_access.cpp:470
+#: modules/commands/cs_access.cpp:695
msgid "Level"
msgstr "Niveau"
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:658
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Le niveau pour %s du channel %s est maintenant de %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:656
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr ""
"Le niveau pour %s sur le canal %s est désormais restreint au fondateur."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:641
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Le niveau doit être compris entre %d et %d inclus."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr "Limite"
@@ -5408,7 +5381,7 @@ msgstr "Liste tous les pseudos enregistrés en rapport avec la recherche"
msgid "List channels you have access on"
msgstr "Liste tous les canaux auxquels vous avez accès"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr "La liste pour le mode %c est pleine."
@@ -5417,7 +5390,7 @@ msgstr "La liste pour le mode %c est pleine."
msgid "List loaded modules"
msgstr "Liste les modules chargés"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr "Liste des entrées correspondantes à %s :"
@@ -5758,7 +5731,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr "Alors ? On se cherche soi-même, %s ?"
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr "MOVE num position"
+
+#: modules/commands/cs_mode.cpp:715
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5829,11 +5806,11 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr "Gère la liste des kicks automatiques"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
msgid "Maintains network bot list"
msgstr "Gère la liste des bots du réseau"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:529
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -5873,7 +5850,7 @@ msgstr ""
"sera ajouté à la liste des kicks automatiques à la place du masque.\n"
"Tous les utilisateurs de ce groupe seront akick.\n"
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:566
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -5973,7 +5950,7 @@ msgstr ""
"GREET active, à condition d'avoir un niveau d'accès\n"
"suffisant."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
msgid "Manage DNS zones for this network"
msgstr "Gère les zones DNS pour ce réseau"
@@ -5989,12 +5966,12 @@ msgstr "Gère la liste d'ignore de mémos"
msgid "Manage your auto join list"
msgstr "Gère la liste des JOIN automatiques"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, c-format
msgid "Manipulate the %s list"
msgstr "Contrôle la liste des %s"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "Contrôle la liste des AKILLs"
@@ -6006,15 +5983,15 @@ msgstr "Active/Désactive DefCon"
msgid "Manipulate the topic of the specified channel"
msgstr "Change le sujet sur un canal spécifié"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:457 modules/commands/cs_access.cpp:470
+#: modules/commands/cs_xop.cpp:384 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_ignore.cpp:266
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
+#: modules/commands/cs_flags.cpp:300 modules/commands/bs_info.cpp:56
+#: modules/commands/ms_ignore.cpp:86 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/bs_botlist.cpp:27
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_list.cpp:147
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
msgid "Mask"
msgstr "Masque"
@@ -6027,8 +6004,8 @@ msgstr "Le masque %s existe déjà dans la liste d'accès de %s."
msgid "Mask must be in the form user@host."
msgstr "Le masque doit être de la forme user@host."
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:119
msgid "Masks and unregistered users may not be on access lists."
msgstr ""
"Les masques et les utilisateurs non enregistrés ne peuvent pas être dans la "
@@ -6078,7 +6055,7 @@ msgstr "La limite de mémos de %s a été définie à %d."
msgid "Memo limit for %s set to 0."
msgstr "La limite de mémos de %s a été définie à 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:51
#, c-format
msgid "Memo sent to %s."
msgstr "Mémo envoyé à %s."
@@ -6092,7 +6069,7 @@ msgstr "Mémos pour %s :"
msgid "Message"
msgstr "Message"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Mode message"
@@ -6100,25 +6077,25 @@ msgstr "Mode message"
msgid "Method"
msgstr "Méthode"
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:404
#, c-format
msgid "Missing parameter for mode %c."
msgstr "Paramètre manquant pour le mode %c."
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:433
msgid "Mode"
msgstr "Mode"
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:660
#, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Le mode %s n'est pas un mode de statut ou de liste."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:983
msgid "Mode lock"
msgstr "Modes verrouillés"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:450
#, c-format
msgid "Mode locks for %s:"
msgstr "Modes verrouillés pour %s :"
@@ -6127,11 +6104,6 @@ msgstr "Modes verrouillés pour %s :"
msgid "Modes"
msgstr "Modes"
-#: modules/commands/os_mode.cpp:44
-#, fuzzy, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr "%d canau(x) vidé(s) et %d canau(x) supprimé(s)."
-
#: modules/commands/ns_access.cpp:166
#, c-format
msgid ""
@@ -6196,7 +6168,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr "Modifie la liste d'ignore des Services"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:496
#, c-format
msgid "Modify the list of %s users"
msgstr "Modifie la liste des utilisateurs %s"
@@ -6205,7 +6177,7 @@ msgstr "Modifie la liste des utilisateurs %s"
msgid "Modify the list of authorized addresses"
msgstr "Modifie la liste des adresses autorisées"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:496 modules/commands/cs_flags.cpp:372
msgid "Modify the list of privileged users"
msgstr "Modifie la liste des utilisateurs privilégiés"
@@ -6213,7 +6185,7 @@ msgstr "Modifie la liste des utilisateurs privilégiés"
msgid "Modify the nickname client certificate list"
msgstr "Modifie la liste de certificats du pseudo"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
msgid "Modify the session-limit exception list"
msgstr "Modifie la liste d'exceptions à la limite de sessions"
@@ -6260,14 +6232,14 @@ msgstr "Module : %s Version : %s Auteur : %s Chargé : %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module : %s [%s] [%s]"
-#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/cs_access.cpp:695 modules/commands/cs_access.cpp:789
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75 modules/commands/os_list.cpp:42
+#: modules/commands/os_list.cpp:147
msgid "Name"
msgstr "Nom"
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:151
msgid "Name Type"
msgstr "Nom Type"
@@ -6280,9 +6252,9 @@ msgstr "Statistiques de réseau pour %s :"
msgid "Never"
msgstr "Jamais"
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
-#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/ns_group.cpp:315 modules/commands/ns_list.cpp:75
+#: modules/commands/hs_request.cpp:306 modules/commands/hs_list.cpp:58
+#: modules/commands/bs_botlist.cpp:27
msgid "Nick"
msgstr "Pseudo"
@@ -6306,7 +6278,6 @@ msgstr "Le pseudo %s a déjà été confirmé."
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Le pseudo %s est un pseudo illégal et ne peut pas être utilisé."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6322,7 +6293,7 @@ msgstr "Le pseudo %s est interdit par %s : %s"
msgid "Nick %s is forbidden."
msgstr "Le pseudo %s est interdit."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s n'est pas un Opérateur des Services."
@@ -6347,12 +6318,12 @@ msgstr "Le pseudo %s n'est pas enregistré."
msgid "Nick %s was truncated to %d characters."
msgstr "Le pseudo %s a été tronqué à %d caractères."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Le pseudo %s expirera."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Le pseudo %s n'expirera pas."
@@ -6417,17 +6388,17 @@ msgstr "Le pseudo %s est déjà enregistré !"
msgid "Nickname %s may not be registered."
msgstr "Le pseudo %s ne peut pas être enregistré."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Le pseudo %s est maintenant enregistré sous votre masque : %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, c-format
msgid "Nickname %s registered."
msgstr "Le pseudo %s est maintenant enregistré."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
msgid "No auto-op"
msgstr "Pas d'auto-op"
@@ -6435,7 +6406,7 @@ msgstr "Pas d'auto-op"
msgid "No bot"
msgstr "Pas de bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/cs_set.cpp:1356 modules/commands/ns_set.cpp:1292
msgid "No expire"
msgstr "N'expire pas"
@@ -6463,13 +6434,13 @@ msgstr "Aucune news de connexion à supprimer !"
msgid "No matches for %s found."
msgstr "Aucune correspondance pour %s trouvée."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:301
#, c-format
msgid "No matching entries on %s %s list."
msgstr "Aucune entrée correspondante sur la liste des %2$s de %1$s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:267 modules/commands/cs_access.cpp:431
+#: modules/commands/cs_xop.cpp:435 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Aucune entrée correspondante sur la liste d'accès de %s."
@@ -6486,18 +6457,18 @@ msgstr ""
"Aucune entrée correspondante sur la liste des mots interdits \n"
"de %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr ""
"Aucune entrée correspondante sur la liste des exceptions à la limite de "
"sessions."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, c-format
msgid "No matching entries on the %s list."
msgstr "Aucune entrée correspondante sur la liste de %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Aucune entrée correspondante sur la liste d'AKILL."
@@ -6509,7 +6480,12 @@ msgstr "Aucun mémo n'était annulable."
msgid "No modules currently loaded matching that criteria."
msgstr "Aucun module actuellement chargé ne correspond à ce critère."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, c-format
+msgid "No nick registrations matching %s found."
+msgstr "Pas d'enregistrement de pseudo correspondant à %s."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr "Personne n'utilise votre pseudo et les services ne l'ont pas suspendu."
@@ -6529,11 +6505,6 @@ msgstr "Aucune news aléatoire à supprimer !"
msgid "No records to display."
msgstr "Pas d'enregistrement à afficher."
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "Pas d'enregistrement de pseudo correspondant à %s."
-
#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
#, c-format
msgid "No request for nick %s found."
@@ -6543,8 +6514,8 @@ msgstr "Pas de requête trouvée pour le pseudo %s."
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr "Pas de kick signés lorsque SIGNKICK LEVEL est utilisé."
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, c-format
msgid "No stats for %s."
msgstr "Aucune statistique pour %s."
@@ -6554,7 +6525,7 @@ msgstr "Aucune statistique pour %s."
msgid "No such info \"%s\" on %s."
msgstr "Aucune informations \"%s\" sur %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, c-format
msgid "No users on %s match %s."
msgstr "Aucun utilisateur sur %s ne correspond à %s."
@@ -6569,30 +6540,30 @@ msgstr "Le mode sans bot est maintenant désactivé sur le canal %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Le mode sans bot est maintenant activé sur le canal %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr "Les modes, sauf ceux de statut, ont été vidés sur %s."
-#: modules/commands/bs_info.cpp:59 modules/commands/os_dns.cpp:225
+#: modules/commands/os_dns.cpp:225 modules/commands/bs_info.cpp:59
msgid "None"
msgstr "Aucune"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:364 modules/commands/cs_mode.cpp:421
msgid "Nothing to do."
msgstr "Rien à faire."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:457
+#: modules/commands/cs_access.cpp:470 modules/commands/cs_xop.cpp:384
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ms_list.cpp:64
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_log.cpp:127
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_news.cpp:156
+#: modules/commands/bs_badwords.cpp:194 modules/commands/hs_request.cpp:306
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/hs_list.cpp:58 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199
msgid "Number"
msgstr "Numéro"
@@ -6604,13 +6575,6 @@ msgstr "OPERNEWS {ADD|DEL|LIST} [texte|numéro]"
msgid "Online from"
msgstr "Connecté depuis"
-#: modules/commands/os_oper.cpp:139
-#, fuzzy, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr " Cet oper est configuré dans le fichier de configuration."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr "Info oper"
@@ -6634,12 +6598,12 @@ msgstr "News d'oper n°%s non trouvée !"
msgid "Oper news items:"
msgstr "News d'oper :"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:146
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr "Privilèges d'oper retirés de %s (%s)."
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:187
#, c-format
msgid "Oper type %s has not been configured."
msgstr "Le type d'opérateur %s n'a pas été configuré."
@@ -6654,17 +6618,17 @@ msgstr "Les operflags %s ont été ajoutés à %s."
msgid "Operflags %s have been removed from %s."
msgstr "Les operflags %s ont été retirés de %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:191
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr "Le type d'opérateur %s n'a aucune commande autorisée."
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:213
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr "Le type d'opérateur %s n'a aucun privilège autorisé."
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:235
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr "Le type d'opérateur %s reçoit les modes %s une fois identifié."
@@ -6677,11 +6641,11 @@ msgstr "Protection des OPs"
msgid "Options"
msgstr "Options"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
msgid "POOL server.name"
msgstr "POOL nom.du.serveur"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:433
msgid "Param"
msgstr "Paramètre"
@@ -6697,12 +6661,12 @@ msgstr "Mot de passe accepté."
msgid "Password authentication required for that command."
msgstr "Authentification par mot de passe requise pour cette commande."
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, c-format
msgid "Password for %s changed to %s."
msgstr "Le mot de passe de %s a été changé en %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, c-format
msgid "Password for %s changed."
msgstr "Le mot de passe de %s a été changé."
@@ -6721,7 +6685,7 @@ msgstr "Mot de passe incorrect."
msgid "Password reset email for %s has been sent."
msgstr "Un email de réinitialisation de mot de passe pour %s a été envoyé."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Paix"
@@ -6735,7 +6699,7 @@ msgstr "Le mode 'paix' est désormais INACTIF pour %s."
msgid "Peace option for %s is now on."
msgstr "Le mode 'paix' est désormais ACTIF pour %s."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
msgid "Persistent"
msgstr "Persistant"
@@ -6777,7 +6741,7 @@ msgstr "Attendez %d secondes et réessayez."
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Veuillez patienter %d secondes avant de redemander un nouveau vHost."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:57
#, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr ""
@@ -6789,14 +6753,14 @@ msgid "Please wait %d seconds before using the GROUP command again."
msgstr ""
"Veuillez patienter %d secondes avant d'utiliser la commande GROUP à nouveau."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:176
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Veuillez patienter %d secondes avant d'utiliser la commande REGISTER à "
"nouveau."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr "%s a été ajouté à la pool."
@@ -6831,7 +6795,7 @@ msgstr "Empêche le canal d'expirer"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Empêche le pseudo d'apparaître dans la commande LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
msgid "Prevent the nickname from expiring"
msgstr "Empêche le pseudo d'expirer"
@@ -6839,8 +6803,8 @@ msgstr "Empêche le pseudo d'expirer"
msgid "Prevents users being kicked by Services"
msgstr "Empêche des utilisateurs d'être kickés par les services"
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/ns_list.cpp:297 modules/commands/cs_list.cpp:262
+#: modules/commands/bs_info.cpp:59
msgid "Private"
msgstr "Privé"
@@ -6874,36 +6838,36 @@ msgstr "L'option privé est maintenant INACTIVE pour %s."
msgid "Private option is now on for %s."
msgstr "L'option privé est maintenant ACTIVE pour %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr "Privilège %s ajouté à %s sur %s, les nouveaux flags sont +%s"
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Privilège %s supprimé de %s sur %s, les nouveaux flags sont +%s"
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Protection"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, c-format
msgid "Protection is now off for %s."
msgstr "La protection est maintenant INACTIVE pour %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "La protection est maintenant ACTIVE pour %s, avec un délai réduit."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "La protection est maintenant ACTIVE pour %s, sans aucun délai."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, c-format
msgid "Protection is now on for %s."
msgstr "La protection est maintenant ACTIVE pour %s."
@@ -6918,7 +6882,7 @@ msgstr ""
"Ceci utilise le masque ident@host réel de tous les pseudos et\n"
"applique le AKILL. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
msgid "Quick protection"
msgstr "Protection rapide"
@@ -6960,20 +6924,20 @@ msgstr "Lit un ou plusieurs mémos"
msgid "Real name"
msgstr "Vrai nom"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_ignore.cpp:266
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199
msgid "Reason"
msgstr "Raison"
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, c-format
msgid "Reason for %s updated."
msgstr "Raison mise à jour pour %s."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:193
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -6989,21 +6953,21 @@ msgstr ""
"avec l'ancienne commande GHOST). S'il n'est pas identifié, son\n"
"pseudo sera changé de force."
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:739
msgid "Redefine the meanings of access levels"
msgstr "Redéfinit la signification des niveaux d'accès"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:131
msgid "Regains control of your nick"
msgstr "Reprendre le contrôle de votre pseudo"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
msgid "Regex is disabled."
msgstr "Les expressions régulières (regex) sont désactivées."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7013,9 +6977,9 @@ msgstr ""
"utilisant\n"
"le moteur de regex %s. Mettez le masque entre // pour l'utiliser."
+#: modules/commands/ns_list.cpp:172 modules/commands/cs_list.cpp:167
+#: modules/commands/os_ignore.cpp:386 modules/commands/os_forbid.cpp:416
#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7033,7 +6997,7 @@ msgstr "Enregistre un canal"
msgid "Register a nickname"
msgstr "Enregistre un pseudo"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
msgid "Registered"
msgstr "Enregistré"
@@ -7086,7 +7050,7 @@ msgstr ""
"%s lui donnera automatiquement les privilèges de propriétaire\n"
"du canal lorsqu'il joindra le canal."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:240
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7178,22 +7142,22 @@ msgstr ""
msgid "Remove all operators from a server remotely"
msgstr "Supprime tous les Opérateurs d'un serveur"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, c-format
msgid "Removed IP %s from %s."
msgstr "Adresse IP %s supprimée de %s."
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr "Serveur %s supprimé de la zone %s."
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr "Serveur %s supprimé."
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:851
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7202,7 +7166,7 @@ msgstr ""
"Retire le statut %s du pseudo désigné sur un canal. Si pseudo n'est\n"
"pas donné, votre statut %s vous sera retiré."
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:832
#, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Retire le statut %s au pseudo spécifié ou à vous-même sur un canal"
@@ -7212,17 +7176,16 @@ msgid "Removes a selected nicks status from a channel"
msgstr "Retire les modes de statut d'un pseudo spécifié sur un canal"
#: modules/commands/cs_updown.cpp:223
-#, fuzzy
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
"Retire les modes de statut au pseudo spécifié sur un canal. Si pseudo est\n"
"omis, alors votre propre statut est retiré. Si canal est omis, alors votre\n"
"statut de canal est supprimé sur tous les canaux sur lesquels vous êtes."
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr "Supprime %s parce que %s le couvre."
@@ -7246,7 +7209,7 @@ msgstr ""
"administrateurs du réseau. Merci d'être patient pendant que votre\n"
"requête est examinée."
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:283
msgid "Resend registration confirmation email"
msgstr "Renvoyer l'email de confirmation d'enregistrement"
@@ -7254,7 +7217,7 @@ msgstr "Renvoyer l'email de confirmation d'enregistrement"
msgid "Restrict access to the channel"
msgstr "Restreindre l'accès au canal"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
msgid "Restricted access"
msgstr "Accès restreint"
@@ -7298,9 +7261,17 @@ msgid "Returns the key of the given channel."
msgstr "Retourne la clé du canal spécifié"
#: modules/commands/ns_getemail.cpp:58
-#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr "Retourne la clé du canal spécifié"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Retourne la liste des pseudos enregistrés avec l'adresse email donnée.\n"
+"Note : vous ne pouvez pas utiliser de caractères joker.\n"
+"Lorsque cette commande est utilisée, un message indiquant\n"
+"la personne qui a utilisé la commande et l'adresse email recherchée\n"
+"est ajouté dans les logs."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7368,18 +7339,18 @@ msgstr "Inverse les effets de la commande IDENTIFY"
msgid "SET server"
msgstr "SET serveur"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr "SET nom.du.serveur option valeur"
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr ""
"Empreinte de certificat SSL acceptée, vous êtes maintenant identifié(e) en "
"tant que %s."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr ""
"Empreinte de certificat SSL acceptée, vous êtes maintenant identifié(e)."
@@ -7402,7 +7373,7 @@ msgstr "Sauvegarde les bases de données et relance les services."
msgid "Searches logs for a matching pattern"
msgstr "Recherche les correspondances au modèle dans le fichier de logs."
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
msgid "Secure founder"
msgstr "Sécurité du fondateur"
@@ -7416,7 +7387,7 @@ msgstr "L'option de sécurité du fondateur sur %s est INACTIVE."
msgid "Secure founder option for %s is now on."
msgstr "L'option de sécurité du fondateur sur %s est ACTIVE."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
msgid "Secure ops"
msgstr "Sécurité des OPs"
@@ -7440,12 +7411,12 @@ msgstr "L'option de sécurité sur %s est INACTIVE."
msgid "Secure option for %s is now on."
msgstr "L'option de sécurité sur %s est ACTIVE."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, c-format
msgid "Secure option is now off for %s."
msgstr "L'option de sécurité est maintenant INACTIVE pour %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, c-format
msgid "Secure option is now on for %s."
msgstr "L'option de sécurité est maintenant ACTIVE pour %s."
@@ -7455,11 +7426,11 @@ msgstr "L'option de sécurité est maintenant ACTIVE pour %s."
msgid "Secureops enforced on %s."
msgstr "Application sur %s de la sécurité des OPs."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/cs_set.cpp:1346 modules/commands/ns_set.cpp:1286
msgid "Security"
msgstr "Sécurité"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:577
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7468,7 +7439,7 @@ msgstr ""
"Tapez %s%s HELP %s pour plus d'informations sur\n"
"la liste d'accès."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:580
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7587,14 +7558,14 @@ msgid "Server %s already exists."
msgstr "Le serveur %s existe déjà."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, c-format
msgid "Server %s does not exist."
msgstr "Le serveur %s n'existe pas."
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, c-format
msgid "Server %s has no configured IPs."
msgstr "Le serveur %s n'a pas d'adresse IP configurée."
@@ -7604,12 +7575,12 @@ msgstr "Le serveur %s n'a pas d'adresse IP configurée."
msgid "Server %s is already in zone %s."
msgstr "Le serveur %s est déjà dans la zone %s "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, c-format
msgid "Server %s is already pooled."
msgstr "Le serveur %s est déjà dans la pool."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, c-format
msgid "Server %s is not currently linked."
msgstr "Le serveur %s n'est pas actuellement linké."
@@ -7624,12 +7595,12 @@ msgstr "Le serveur %s n'est pas dans la zone %s."
msgid "Server %s is not linked to the network."
msgstr "Le serveur %s n'est pas linké au réseau."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, c-format
msgid "Server %s is not pooled."
msgstr "Le serveur %s n'est pas dans la pool."
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr "Le serveur %s doit être quitté avant de pouvoir être supprimé."
@@ -7647,12 +7618,12 @@ msgstr "Serveurs trouvés : %d"
msgid "Service"
msgstr "Service"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, c-format
msgid "Service's hold on %s has been released."
msgstr "La tutelle des Services sur %s a été enlevée."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/chanserv.example.conf:820 data/nickserv.example.conf:234
msgid "Services Operator commands"
msgstr "Commandes pour Opérateur des Services"
@@ -7708,7 +7679,7 @@ msgstr "Les Services ont été configurés pour ne pas envoyer de mail."
msgid "Services ignore list:"
msgstr "Liste d'ignore des services :"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:38
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
"correctly?"
@@ -7721,7 +7692,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Services actifs depuis %s"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr ""
@@ -7735,7 +7706,7 @@ msgstr ""
"Les services n'appliqueront plus automatiquement de modes utilisateurs sur"
" %s."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr ""
@@ -7747,12 +7718,12 @@ msgid "Services will now automatically give modes to users in %s."
msgstr ""
"Les services appliqueront automatiquement des modes utilisateurs sur %s."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Les services répondront à %s par des messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Les services répondront à %s par des notices."
@@ -7770,7 +7741,7 @@ msgstr "Session"
msgid "Session limit for %s set to %d."
msgstr "La limite de sessions de %s est maintenant de %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "La limitation de sessions est désactivée."
@@ -7807,7 +7778,7 @@ msgstr "Définit le canal comme permanent"
msgid "Set the channel description"
msgstr "Définit la description du canal"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
msgid "Set the display of your group in Services"
msgstr "Change l'affichage de votre groupe dans les services"
@@ -7815,12 +7786,12 @@ msgstr "Change l'affichage de votre groupe dans les services"
msgid "Set the founder of a channel"
msgstr "Définit le fondateur d'un canal"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
msgid "Set the language Services will use when messaging you"
msgstr ""
"Change la langue dans laquelle les Services vous envoient leurs messages"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
msgid "Set the nickname password"
msgstr "Change le mot de passe du pseudo donné"
@@ -8149,7 +8120,7 @@ msgstr ""
msgid "Sets various nickname options. option can be one of:"
msgstr "Configure diverses options du pseudo. option peut être :"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8164,7 +8135,7 @@ msgstr ""
"Définit si le canal donné expirera. Mettre ceci sur ON\n"
"empêche le canal d'expirer."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8180,7 +8151,7 @@ msgstr ""
"les paramètres du canal, certains modes pourraient ne\n"
"pas être appliqués automatiquement."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8188,7 +8159,7 @@ msgstr ""
"Configurez ce paramètre sur ON pour que le \n"
"pseudo n'expire pas."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8203,7 +8174,7 @@ msgstr ""
"les paramètres du canal, certains modes pourraient ne\n"
"pas être appliqués automatiquement."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:646 modules/commands/cs_access.cpp:687
#, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8263,11 +8234,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Les kicks seront maintenant signés sur %s."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Kicks signés"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:59
#, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "Désolé, %s a trop de mémos et ne peut en recevoir plus."
@@ -8287,7 +8258,7 @@ msgstr ""
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Désolé, l'assignation du bot est temporairement désactivée."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Désolé, la modification des bots est temporairement désactivée."
@@ -8304,15 +8275,15 @@ msgstr ""
"Désolé, la configuration des options du bot est \n"
"temporairement désactivée."
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:238
+#: modules/commands/cs_xop.cpp:451
#, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Désolé, la modification des listes des %s des canaux est temporairement "
"désactivée."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:545 modules/commands/cs_flags.cpp:404
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr ""
"Désolé, la modification des listes d'accès des canaux est temporairement "
@@ -8380,8 +8351,8 @@ msgstr ""
"Désolé, la liste de pseudos ignorés pour les mémos\n"
"de %s est pleine."
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:202 modules/commands/cs_xop.cpp:204
+#: modules/commands/cs_flags.cpp:173
#, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8666,7 +8637,6 @@ msgstr ""
"--noexpire."
#: modules/commands/ms_set.cpp:246
-#, fuzzy
msgid ""
"Syntax: NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\n"
" \n"
@@ -8679,7 +8649,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -8759,7 +8729,7 @@ msgstr ""
"Cette option n'est pas persistante et ne devrait être utilisée que lorsque\n"
"vraiment nécessaire, puis remise à OFF quand elle n'est plus nécessaire."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -8845,7 +8815,7 @@ msgstr "Arrête les Services avec sauvegarde"
msgid "Text"
msgstr "Texte"
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:574
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -8864,7 +8834,7 @@ msgstr ""
"grand\n"
"présent dans la liste d'accès."
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:585
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -8879,7 +8849,7 @@ msgstr ""
"Vous pouvez vous supprimer vous-même de la liste d'accès même si\n"
"vous n'avez pas l'accès pour modifier la liste."
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:591
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -8910,7 +8880,7 @@ msgstr ""
"La commande ACCESS CLEAR vide toutes les entrées de la liste\n"
"d'accès."
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:446
msgid ""
"The CLEAR command clears the channel access list. This requires channel "
"founder access."
@@ -9012,11 +8982,11 @@ msgstr ""
"La commande ENTRYMSG LIST affiche la liste des messages qui seront\n"
"montrés aux utilisateurs lorsqu'ils joignent le canal."
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "L'option IMMED n'est pas disponible sur ce réseau."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:811
#, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9060,7 +9030,7 @@ msgstr ""
"Pour une liste de caractéristiques et fonctions pour lesquelles\n"
"des niveaux peuvent être définis, consultez HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:441
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9077,7 +9047,7 @@ msgstr ""
"Si une suite de flags est donnée, alors seuls les accès avec les flags "
"spécifiés sont retournés."
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:434
msgid ""
"The MODIFY command allows you to modify the access list. If the mask is\n"
"not already on the access list it is added, then the changes are applied.\n"
@@ -9110,7 +9080,7 @@ msgstr ""
"La commande STATS affiche des statistiques à propos des pseudos stockés et "
"de la mémoire utilisée."
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:262
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -9173,12 +9143,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "La liste de %s pour %s est pleine."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, c-format
msgid "The %s list has been cleared."
msgstr "La liste des %s a été vidée."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "La liste d'AKILL a été vidée."
@@ -9199,7 +9169,7 @@ msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr ""
"L'adresse email de %s sera désormais affichée dans la commande INFO de %s."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:448
msgid "The available flags are:"
msgstr "Les flags disponibles sont :"
@@ -9229,11 +9199,11 @@ msgstr "L'adresse email %s a atteint sa limite d'utilisation d'un utilisateur.
msgid "The entry message list for %s is full."
msgstr "La liste de messages d'accueil de %s est pleine."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:786
msgid "The following feature/function names are available:"
msgstr "Les fonctionnalités suivantes sont disponibles :"
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:582
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9306,12 +9276,12 @@ msgstr "Le masque doit contenir au moins un caractère non joker."
msgid "The memo limit for %s may not be changed."
msgstr "La limite de mémos pour %s ne peut être changée."
-#: modules/commands/cs_mode.cpp:332
+#: modules/commands/cs_mode.cpp:331
#, c-format
msgid "The mode lock list of %s is full."
msgstr "La liste des modes verrouillés pour %s est pleine."
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr "Le nouvel affichage DOIT être un pseudo du groupe %s."
@@ -9326,7 +9296,7 @@ msgstr "Le nouvel affichage est maintenant %s."
msgid "The nick %s is now being changed to %s."
msgstr "Le pseudo de %s a été changé en %s."
-#: modules/commands/bs_bot.cpp:149
+#: modules/commands/bs_bot.cpp:142
msgid "The old information is the same as the new information specified."
msgstr "Les anciennes informations sont les mêmes que les nouvelles indiquées."
@@ -9355,11 +9325,11 @@ msgstr ""
"Les accès aux services de %s seront maintenant affichés dans la commande "
"INFO de %s."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
msgid "The session exception list is empty."
msgstr "La liste d'exceptions est vide."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:104
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9435,7 +9405,7 @@ msgstr "Il n'y a pas de news aléatoires."
msgid "There is no such configuration block %s."
msgstr "Il n'y a pas de bloc de configuration %s."
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:654
#, c-format
msgid "There is no such mode %s."
msgstr "Il n'y a pas de mode %s."
@@ -9461,7 +9431,7 @@ msgstr "Ce canal est suspendu."
msgid "This channel may not be used."
msgstr "Ce canal ne peut pas être utilisé."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9516,7 +9486,7 @@ msgstr ""
"Permet aux utilisateurs d'appliquer le vhost de leur pseudo\n"
"actuellement utilisé à tous les pseudos de leur groupe de pseudos."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:270
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9651,7 +9621,7 @@ msgstr ""
"Les Opérateurs des Services peuvent fournir un pseudo pour modifier\n"
"la liste d'auto join d'autres utilisateurs."
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9725,7 +9695,7 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "Cette commande décharge le module nommé nom-module."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:324
msgid "This command will resend you the registration confirmation email."
msgstr "Cette commande vous renverra l'email de confirmation d'enregistrement."
@@ -9743,12 +9713,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Ce pseudo a été interdit : %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "Ce pseudo a été récupéré par %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -9811,7 +9781,7 @@ msgstr "Top %i de %s"
msgid "Topic"
msgstr "Topic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:257
msgid "Topic lock"
msgstr "Verrouillage du topic"
@@ -9825,7 +9795,7 @@ msgstr "Le verrouillage du sujet pour %s est maintenant INACTIF."
msgid "Topic lock option for %s is now on."
msgstr "Le verrouillage du sujet pour %s est maintenant ACTIF."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:255
msgid "Topic retention"
msgstr "Maintien du topic"
@@ -9839,7 +9809,7 @@ msgstr "Le maintient du topic est maintenant INACTIF sur %s."
msgid "Topic retention option for %s is now on."
msgstr "Le maintient du topic est maintenant ACTIF sur %s."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:264
msgid "Topic set by"
msgstr "Topic défini par"
@@ -9847,15 +9817,16 @@ msgstr "Topic défini par"
msgid "Turn caps lock OFF!"
msgstr "Cessez d'utiliser tant de majuscules !"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
msgid "Turn chanstats statistics on or off"
msgstr "Active ou désactive les statistiques de ChanStats."
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
msgid "Turn nickname security on or off"
msgstr "Active ou désactive la sécurité du pseudo"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
msgid "Turn protection on or off"
msgstr "Active ou désactive la protection"
@@ -9891,7 +9862,7 @@ msgstr ""
"tout de même avoir des informations en utilisant la commande\n"
"INFO)."
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9919,7 +9890,7 @@ msgstr ""
"Active ou désactive les statistiques de canal de ChanStats pour cet "
"utilisateur."
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9947,7 +9918,7 @@ msgstr ""
"de changer son pseudo, n'utilisez cette option que si nécessaire.\n"
"Les administrateurs de votre réseau peuvent avoir désactivé cette option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10022,7 +9993,7 @@ msgstr ""
"Tapez %s%s HELP %s option pour plus d'informations sur\n"
"une option particulière."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:357
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10037,8 +10008,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Décharge un module"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, c-format
msgid "Unable to find regex engine %s."
msgstr "Impossible de trouver le moteur de regex %s."
@@ -10077,7 +10048,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Kicker de caractères soulignés"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
msgid "Unknown SET option."
msgstr "Option SET inconnue."
@@ -10096,7 +10067,7 @@ msgstr "Commande %s inconnue."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Commande %s inconnue. Tapez \"%s%s HELP\" pour obtenir de l'aide."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:393
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "Mode %c ignoré car inconnu."
@@ -10136,10 +10107,9 @@ msgstr ""
"Relâche un pseudo suspendu, ce qui permet qu'il soit utilisé à nouveau."
#: modules/commands/cs_updown.cpp:126
-#, fuzzy
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
"Met à jour les modes de statut de canal du pseudo choisi. Si pseudo\n"
@@ -10191,29 +10161,29 @@ msgstr ""
msgid "Used on"
msgstr "Utilisé sur"
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
msgid "Used to manage channels"
msgstr "Permet de gérer les canaux"
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
msgid "Used to manage the list of privileged users"
msgstr "Permet de modifier la liste des utilisateurs privilégiés"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
"Permet de modifier votre statut sur le canal ou celui des autres utilisateurs"
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:559
msgid "User has been banned from the channel"
msgstr "L'utilisateur a été banni du canal."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, c-format
msgid "User limit for %s removed."
msgstr "Limite d'utilisateurs pour %s supprimée."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, c-format
msgid "User limit for %s set to %d."
msgstr "Limite d'utilisateurs pour %s fixée à %d utilisateurs."
@@ -10265,12 +10235,12 @@ msgstr "Le vhost pour le groupe %s fixé à %s@%s."
msgid "VIEW host"
msgstr "VIEW host"
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
msgid "VIEW [mask | list | id]"
msgstr "VIEW [masque | liste | id]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr "VIEW [masque | liste]"
@@ -10283,7 +10253,7 @@ msgstr "Valeur"
msgid "Value of %s:%s changed to %s"
msgstr "Valeur de %s:%s changée en %s"
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_request.cpp:306 modules/commands/hs_list.cpp:58
msgid "Vhost"
msgstr "Vhost"
@@ -10321,7 +10291,7 @@ msgstr ""
"Lorsque PRIVATE est défini, le canal n'apparaîtra plus\n"
"dans la commande %s de %s."
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
msgid ""
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
@@ -10411,7 +10381,7 @@ msgstr "Mot"
msgid "You are already a member of the group of %s."
msgstr "Vous êtes déjà membre du groupe de %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Vous êtes déjà identifié."
@@ -10473,7 +10443,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr "Vous ne pouvez pas NOOP les Services."
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:670
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10503,13 +10473,13 @@ msgstr ""
"Vous ne pouvez pas recevoir d'accusé de réception quand vous vous\n"
"êtes envoyé un message à vous-même."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/ns_recover.cpp:145
#, c-format
msgid "You can't %s yourself!"
msgstr "Vous ne pouvez pas utiliser %s sur vous-même !"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:108
msgid "You can't add a channel to its own access list."
msgstr "Vous ne pouvez pas ajouter un canal dans sa propre liste d'accès."
@@ -10518,12 +10488,12 @@ msgstr "Vous ne pouvez pas ajouter un canal dans sa propre liste d'accès."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Vous ne pouvez pas déconnecter %s, car il est Opérateur des Services."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, c-format
msgid "You cannot %s on this network."
msgstr "Vous ne pouvez pas utiliser %s sur ce réseau."
-#: modules/commands/cs_flags.cpp:231
+#: modules/commands/cs_flags.cpp:230
#, c-format
msgid "You cannot set the %c flag."
msgstr "Vous ne pouvez pas définir le flag %c."
@@ -10543,7 +10513,7 @@ msgid "You cannot unassign bots while persist is set on the channel."
msgstr ""
"Vous ne pouvez pas assigner de bot lorsque persist est actif pour ce canal."
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Vous ne pouvez pas effacer votre email sur ce réseau."
@@ -10583,12 +10553,12 @@ msgstr "Vous avez actuellement 1 mémo."
msgid "You currently have no memos."
msgstr "Vous n'avez aucun mémo actuellement."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:543 modules/commands/cs_mode.cpp:580
#, c-format
msgid "You do not have access to set mode %c."
msgstr "Vous n'avez pas les accès pour définir le mode %c."
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:556 modules/commands/cs_mode.cpp:589
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "Vous n'avez pas les accès pour changer les modes de %s."
@@ -10626,7 +10596,7 @@ msgstr "Vous avez été invité à rejoindre %s par %s."
msgid "You have been invited to %s."
msgstr "Vous avez été invité à rejoindre %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "Vous vous êtes identifié en tant que %s."
@@ -10668,30 +10638,31 @@ msgstr ""
"recevoir de nouveaux mémos sauf si vous supprimez quelques-uns de vos mémos "
"actuels. "
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Vous avez été invité à rejoindre %s."
+#: modules/commands/ns_recover.cpp:101
+#, c-format
+msgid "You have regained control of %s and are now identified as %s."
+msgstr ""
+"Vous avez repris le contrôle de %s et êtes désormais identifié comme %s."
#: modules/commands/ns_drop.cpp:66
msgid "You may drop any nick within your group."
msgstr "Vous pouvez supprimer n'importe quel pseudo de votre groupe."
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:398
#, c-format
msgid "You may not (un)lock mode %c."
msgstr "Vous ne pouvez pas (dé)verrouiller le mode %c."
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
msgid "You may not change the e-mail of other Services Operators."
msgstr ""
"Vous ne pouvez pas changer l'adresse email d'autres Opérateurs des Services."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
msgid "You may not change the email of an unconfirmed account."
msgstr "Vous ne pouvez pas changer l'adresse email d'un compte non confirmé."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
msgid "You may not change the password of other Services Operators."
msgstr ""
"Vous ne pouvez pas changer le mot de passe d'autres Opérateurs des Services."
@@ -10772,14 +10743,14 @@ msgstr ""
"Vous devez rester connecté plus de %d secondes avant d'enregistrer votre "
"pseudo."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:855
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
"Vous devez avoir le privilège %s(ME) sur le canal pour utiliser cette "
"commande."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:354
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -10793,39 +10764,17 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "Vous devez être identifié pour utiliser cette commande."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Vous serez notifié quand de nouveaux mémos arrivent."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Vous serez notifié pour les nouveaux mémos à la connexion et quand ils "
-"arrivent."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Vous serez notifié pour les nouveaux mémos à la connexion et quand ils "
"arrivent."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Vous serez notifié pour les nouveaux mémos à la connexion et quand ils "
-"arrivent."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Vous serez notifié pour les nouveaux mémos à la connexion."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Vous serez notifié quand de nouveaux mémos arrivent."
@@ -10837,7 +10786,7 @@ msgstr "Vous ne pourrez désormais plus recevoir de mémos."
msgid "You will no longer be informed via email."
msgstr "Vous ne serez plus averti par mail de l'arrivée de nouveau mémo."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Vous ne serez plus notifié pour les nouveaux mémos."
@@ -10865,22 +10814,22 @@ msgstr ""
"Votre IRCd ne supporte pas les vIdent. Si ceci est incorrect, merci de le "
"reporter, il s'agit peut être d'un bug."
-#: modules/extra/m_ldap_authentication.cpp:102
#: modules/extra/m_sql_authentication.cpp:47
+#: modules/extra/m_ldap_authentication.cpp:110
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Votre compte %s a été créé avec succès."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:299
msgid "Your account is already confirmed."
msgstr "Votre compte est déjà confirmé."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:367
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "En cas de non confirmation, votre compte expirera dans %s."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Votre adresse email a été changée en %s."
@@ -10889,7 +10838,7 @@ msgstr "Votre adresse email a été changée en %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Votre adresse email n'est pas autorisée, merci d'en choisir une autre."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:362
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
@@ -10902,7 +10851,7 @@ msgstr ""
msgid "Your email address of %s has been confirmed."
msgstr "Votre adresse email pour %s a été confirmée."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, c-format
msgid "Your email has been updated to %s"
msgstr "Votre adresse email a été changée en %s."
@@ -10940,8 +10889,8 @@ msgid ""
"Your memo limit is 0; you will not receive any new memos. You cannot change "
"this limit."
msgstr ""
-"Votre limite de mémos est de 0, vous ne recevrez aucun nouveau mémo. Vous ne "
-"pouvez pas changer cette limite."
+"Votre limite de mémos est de 0, vous ne recevrez aucun nouveau mémo. Vous "
+"ne pouvez pas changer cette limite."
#: modules/commands/ns_logout.cpp:50
msgid "Your nick has been logged out."
@@ -10961,7 +10910,7 @@ msgstr ""
msgid "Your nick isn't registered."
msgstr "Votre pseudo n'est pas enregistré."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:250
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Votre pseudo est maintenant changé en %s."
@@ -10970,19 +10919,18 @@ msgstr "Votre pseudo est maintenant changé en %s."
msgid "Your oper block doesn't require logging in."
msgstr "Votre bloc oper ne nécessite pas de s'authentifier."
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:307
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Votre mot-code a été renvoyé à %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Votre mot de passe est %s - notez-le pour une utilisation ultérieure."
#: include/language.h:77
-#, fuzzy, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr "Votre mot de passe est trop long. Merci d'en choisir un plus court."
#: modules/commands/ns_resetpass.cpp:96
@@ -10993,19 +10941,19 @@ msgstr "Votre demande de réinitialisation de mot de passe a expiré."
msgid "Your vHost has been requested."
msgstr "Votre demande de vHost a été enregistrée."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Votre vhost %s est activé."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Votre vhost %s@%s est activé."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Votre vhost a été supprimé et le masquage normal a été restauré."
@@ -11100,8 +11048,8 @@ msgstr "[pseudo]"
msgid "[nickname [REVALIDATE]]"
msgstr "[pseudo [REVALIDATE]]"
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_alist.cpp:25 modules/commands/ns_info.cpp:20
+#: modules/commands/ns_status.cpp:20
msgid "[nickname]"
msgstr "[pseudo]"
@@ -11121,7 +11069,7 @@ msgstr "[+expiration] canal raison"
msgid "[Hostname hidden]"
msgstr "[Nom d'hôte caché]"
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr "[Suspendu]"
@@ -11142,7 +11090,7 @@ msgstr "[auto memo] Votre requête de vHost a été rejetée."
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[auto memo] Votre requête de vHost a été rejetée. Raison : %s"
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:390
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] Le vHost %s a été demandé par %s."
@@ -11283,28 +11231,6 @@ msgstr "{canal | pseudo}"
msgid "{nick | channel}"
msgstr "{pseudo | canal}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
msgid "{nick | channel} memo-text"
msgstr "{pseudo | canal} texte"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "L'exception pour %s (#%d) a été déplacée à la position %d."
-
-#~ msgid "MOVE num position"
-#~ msgstr "MOVE num position"
-
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Retourne la liste des pseudos enregistrés avec l'adresse email donnée.\n"
-#~ "Note : vous ne pouvez pas utiliser de caractères joker.\n"
-#~ "Lorsque cette commande est utilisée, un message indiquant\n"
-#~ "la personne qui a utilisé la commande et l'adresse email recherchée\n"
-#~ "est ajouté dans les logs."
-
-#~ msgid "You have regained control of %s and are now identified as %s."
-#~ msgstr ""
-#~ "Vous avez repris le contrôle de %s et êtes désormais identifié comme %s."
diff --git a/language/anope.hu_HU.po b/language/anope.hu_HU.po
index f7b43f70f..5e4dd3f7f 100644
--- a/language/anope.hu_HU.po
+++ b/language/anope.hu_HU.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 20:37-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Hungarian\n"
@@ -27,19 +27,19 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "A nickneved dropolva lett,"
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "%s hozzáadva az AKILL listához."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr ""
"%s hozzáadva a %s hozzáférési listájához.\n"
"A hozzáférési szintje a ChanServ parancsokhoz: %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr ""
@@ -51,7 +51,7 @@ msgstr ""
msgid "%s added to %s autokick list."
msgstr "%s hozzáadva a (%s) csatorna autokick listájához"
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "A %s szó hozzáadva a %s tiltott szavak listájához."
@@ -66,17 +66,17 @@ msgstr "%s hozzáadva a hozzáférési listádhoz."
msgid "%s added to %s's certificate list."
msgstr "%s hozzáadva a hozzáférési listádhoz."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s hozzáadva a hozzáférési listádhoz."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "%s hozzáadva az AKILL listához."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s hozzáadva az AKILL listához."
@@ -111,7 +111,7 @@ msgstr ""
"Bővebb információt így kaphatsz az adott parancsról:\n"
"/msg %s HELP parancs."
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -128,7 +128,7 @@ msgstr ""
"beírod, hogy: /msg %s parancs, lásd még a\n"
"/msg %s HELP parancs."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -144,7 +144,7 @@ msgstr ""
"beírod, hogy: /msg %s parancs, lásd még a\n"
"/msg %s HELP parancs."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -164,7 +164,7 @@ msgstr ""
"kapcsolatban, akkor írd be: /msg %s HELP parancs.\n"
" "
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "A %s szót már tartalmazza a %s tiltott szavak listája"
@@ -185,7 +185,7 @@ msgstr "%s already exists on the EXCEPTION list."
msgid "%s cannot be taken as times to ban."
msgstr "%s nem fogadható el banolási időnek."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s váltóztatott a módodon."
@@ -195,12 +195,12 @@ msgstr "%s váltóztatott a módodon."
msgid "%s channel list:"
msgstr "Vége a szoba listának."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s törölve lett a %s AOP listáról."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s törölve lett a (%s) csatorna hozzáférési listájáról."
@@ -210,7 +210,7 @@ msgstr "%s törölve lett a (%s) csatorna hozzáférési listájáról."
msgid "%s deleted from %s autokick list."
msgstr "%s törölve a (%s) csatorna autokick listájáról."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "A %s szó törölve %s tiltott szavak listájából."
@@ -235,12 +235,12 @@ msgstr "%s törölve a session-korlát kivétel listáról."
msgid "%s deleted from the %s list."
msgstr "%s törölve lett a %s AOP listáról."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s törölve az AKILL listáról."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s letiltva a (%s) csatornán."
@@ -313,7 +313,7 @@ msgstr "You are already in %s! "
msgid "%s is already in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s hozzáadva a hozzáférési listádhoz."
@@ -323,7 +323,7 @@ msgstr "%s hozzáadva a hozzáférési listádhoz."
msgid "%s is already suspended."
msgstr "You are already in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s nem érvényes bot vagy regisztrált szoba."
@@ -353,7 +353,7 @@ msgstr "%s letiltva a (%s) csatornán."
msgid "%s is not in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "%s nick nem található a mellőzöttek listáján."
@@ -385,12 +385,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s hozzáadva a (%s) csatorna autokick listájához"
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "%s nem találatható a %s AOP listán."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s nem található a (%s) csatorna hozzáférési listáján."
@@ -400,7 +400,7 @@ msgstr "%s nem található a (%s) csatorna hozzáférési listáján."
msgid "%s not found on %s autokick list."
msgstr "%s nem szerepel a (%s) csatorna autokick listáján."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "A %s szó nem található a %s tiltott szavak listáján."
@@ -437,17 +437,17 @@ msgstr "%s nem található a session-korlát kivétel listán."
msgid "%s not found on the %s list."
msgstr "%s nem találatható a %s AOP listán."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s nem található az AKILL listán."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "%s törölve lett a (%s) csatorna hozzáférési listájáról."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s törölve a hozzáférési listádról."
@@ -479,11 +479,11 @@ msgstr ""
"Ãrd be: /msg %s HELP SET opció bÅ‘vebb információért az\n"
"adott opcióról."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -491,12 +491,12 @@ msgstr ""
"BOT CHANGE réginickújnick [user [hoszt [valósnév]]]\n"
"BOT DEL nick"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <nick>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -511,6 +511,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -573,7 +576,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -591,18 +594,18 @@ msgstr "[auto-memo] A memo, amit %s számára küldtél meg lett tekintve."
msgid "[target] [password]"
msgstr "GROUP célnick jelszó"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -645,7 +648,7 @@ msgstr "UNBAN #szoba [nick]"
msgid "channel nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR #szoba mit?"
@@ -655,7 +658,7 @@ msgstr "CLEAR #szoba mit?"
msgid "channel text"
msgstr "ACT #szoba szöveg"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT #szoba szöveg"
@@ -670,12 +673,12 @@ msgstr "KICK #szoba user indok"
msgid "channel what"
msgstr "TOPIC #szoba [topic]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE szoba mód"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -684,7 +687,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE szoba mód"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -693,19 +696,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC #szoba [topic]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP #szoba"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC #szoba [topic]"
@@ -720,7 +723,7 @@ msgstr "DROP #szoba"
msgid "channel DEL num"
msgstr "MODE szoba mód"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [#szoba] { szám | list | ALL}"
@@ -730,7 +733,7 @@ msgstr "DEL [#szoba] { szám | list | ALL}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP #szoba { ADD | DEL | LIST | CLEAR } [ nick | sorszám ]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [#szoba] { szám | list | ALL}"
@@ -739,7 +742,7 @@ msgstr "DEL [#szoba] { szám | list | ALL}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP #szoba"
@@ -749,41 +752,50 @@ msgstr "DROP #szoba"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP #szoba { ADD | DEL | LIST | CLEAR } [ nick | sorszám ]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP #szoba { ADD | DEL | LIST | CLEAR } [ nick | sorszám ]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP #szoba { ADD | DEL | LIST | CLEAR } [ nick | sorszám ]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET szoba GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE szoba mód"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC #szoba [topic]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP #szoba { ADD | DEL | LIST | CLEAR } [ nick | sorszám ]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [#szoba] { szám | list | ALL}"
@@ -793,7 +805,7 @@ msgstr "DEL [#szoba] { szám | list | ALL}"
msgid "channel [description]"
msgstr "REGISTER #szoba leírás"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN #szoba [nick]"
@@ -803,7 +815,7 @@ msgstr "UNBAN #szoba [nick]"
msgid "channel [parameters]"
msgstr "CLEAR #szoba mit?"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN #szoba [nick]"
@@ -818,23 +830,13 @@ msgstr "BAN #channel nick [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #channel nick [reason]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC #szoba [topic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP #szoba"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET #szoba XOP {ON | OFF}"
@@ -862,7 +864,7 @@ msgstr "KICK #szoba opció {ON|OFF} [beállítások]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET #szoba XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -886,27 +888,27 @@ msgstr "SET #szoba XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE szám"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL üzenet"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -916,8 +918,9 @@ msgid "new-password"
msgstr "GROUP célnick jelszó"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO nick"
@@ -947,18 +950,18 @@ msgstr "SET <nick> <hosztmaszk>."
msgid "nick newnick"
msgstr "SVSNICK nick újnick "
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK nicknév "
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID nicknév indok"
@@ -968,7 +971,7 @@ msgstr "FORBID nicknév indok"
msgid "nickname email"
msgstr "FORBID nicknév indok"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID nicknév indok"
@@ -978,12 +981,12 @@ msgstr "FORBID nicknév indok"
msgid "nickname message"
msgstr "FORBID nicknév indok"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID nicknév indok"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST nicknév [jelszó]"
@@ -993,7 +996,7 @@ msgstr "GHOST nicknév [jelszó]"
msgid "nickname [parameter]"
msgstr "GHOST nicknév [jelszó]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST nicknév [jelszó]"
@@ -1008,15 +1011,15 @@ msgstr "FORBID nicknév indok"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET nickname KILL {ON | QUICK | IMMED | OFF}"
@@ -1060,12 +1063,12 @@ msgstr "REGISTER jelszó email"
msgid "password"
msgstr "GROUP célnick jelszó"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER jelszó email"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER jelszó email"
@@ -1085,7 +1088,7 @@ msgstr "LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE szervernév [leírás]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE szoba mód"
@@ -1095,7 +1098,7 @@ msgstr "MODE szoba mód"
msgid "user [reason]"
msgstr "JUPE szervernév [leírás]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1114,7 +1117,7 @@ msgstr ""
"visszaélés jutalma minimum az visszaélő nickjének\n"
"elvesztése."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1174,7 +1177,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz operatornak."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1231,7 +1234,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz operatornak."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1344,7 +1347,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1365,7 +1368,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1377,7 +1380,7 @@ msgstr ""
"beazonosíttotak a nicknevükre, és megnézhetik a nickek\n"
"hozzáférési listáját. (/msg %s ACCESS LIST nick)"
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1390,7 +1393,7 @@ msgstr ""
"hogy a szoba jelszót használnának, és megnézhetika az\n"
"access, AKICK, és beállitási szint listát a csatornán."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1399,7 +1402,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1463,7 +1476,7 @@ msgstr ""
"és írd be: /msg %s HELP SET XOP hogy megnézd, hogyan \n"
"tudsz váltani az xOP rendszerről access lista rendszerre."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1487,7 +1500,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1552,7 +1565,7 @@ msgstr ""
"és írd be: /msg %s HELP SET XOP hogy megnézd, hogyan \n"
"tudsz váltani az xOP rendszerről access lista rendszerre."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1617,7 +1630,7 @@ msgstr ""
"és írd be: /msg %s HELP SET XOP hogy megnézd, hogyan \n"
"tudsz váltani az xOP rendszerről access lista rendszerre."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1686,9 +1699,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"Syntax: SET #szoba NOBOT {ON|OFF}\n"
"\n"
@@ -1698,7 +1711,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz adminoknak."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1720,7 +1733,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1735,7 +1748,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "Modul parancsai: /msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1749,7 +1762,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1761,7 +1774,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr " JUPE Létrehoz egy \"Jupiter\" álszervert."
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1780,17 +1793,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s nem kért értesítést az üzeneteiről."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
@@ -1815,8 +1828,8 @@ msgstr "%d nicknév van a csoportban."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "%s AOP listája üres."
@@ -1908,9 +1921,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr "\tCaps Lockért kirúgás: %s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "%s hozzáférési listája üres."
@@ -1920,7 +1933,7 @@ msgstr "%s hozzáférési listája üres."
msgid "%s added to %s's auto join list."
msgstr "%s hozzáadva a (%s) csatorna autokick listájához"
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "%s nevű bot már létezik."
@@ -1931,7 +1944,7 @@ msgstr "%s nevű bot már létezik."
msgid "%s autokick list is empty."
msgstr "%s autokick listája üres."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "%s tiltott szavak listája üres."
@@ -1941,8 +1954,8 @@ msgstr "%s tiltott szavak listája üres."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s nem lehet a %s csatorna successora, mert Å‘ a founder is."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "%s parancsok:"
@@ -2042,7 +2055,7 @@ msgstr "%s jelenleg online."
msgid "%s is a network service."
msgstr "%s jelenleg online."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "%s van már %s ilyen bejegyzés."
@@ -2057,7 +2070,7 @@ msgstr "%s hozzáadva a hozzáférési listádhoz."
msgid "%s is an unconfirmed nickname."
msgstr "Ez a nicknév nem fog elévülni."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2081,7 +2094,7 @@ msgstr "%s is disabled"
msgid "%s is enabled"
msgstr "%s is enable"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s nem érvényes ban típus."
@@ -2126,7 +2139,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s letiltva a (%s) csatornán."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "%s hozzáférési listája:"
@@ -2136,7 +2149,7 @@ msgstr "%s hozzáférési listája:"
msgid "%s list is empty."
msgstr "%s AOP listája üres."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s nem kért értesítést az üzeneteiről."
@@ -2188,7 +2201,7 @@ msgstr "%s értesíteni fog az üzenetekről csatlakozáskor."
msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr "%s értesít az üzenetekről csatlakozáskor/AWAY OFF-kor."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) hozzáadva a bot listához."
@@ -2242,12 +2255,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s is enable"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2314,7 +2327,7 @@ msgstr "%s jelenleg online."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2327,13 +2340,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Egy massmemo elküldve minden regisztrált felhasználónak."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2372,7 +2385,7 @@ msgstr "GROUP célnick jelszó"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
@@ -2392,12 +2405,12 @@ msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID nicknév indok"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
@@ -2407,15 +2420,15 @@ msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2431,8 +2444,8 @@ msgstr ""
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL AKILL az összes usert a csatornáról"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "AKILL lista üres."
@@ -2466,17 +2479,17 @@ msgstr "A szintnek kizárólag %d és %d között kell lennie."
msgid "Access level must be non-zero."
msgstr "A hozzáférési szint nem lehet nulla."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "%s hozzáférési szintjeinek beállításai:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "%s szintjei visszaállítva az alapértékekre."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "%s hozzáférési listája:"
@@ -2490,24 +2503,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE Aktiválja a %s biztonsági lehetőségeit"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2532,7 +2537,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2572,13 +2577,7 @@ msgstr "Uplink server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2599,7 +2598,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Összes O:lines %s újra aktív."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
@@ -2609,16 +2608,11 @@ msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
msgid "All available commands for %s:"
msgstr "Nincs ezzel kapcsolatban segítség: %s."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Összes fellépési hír tétel törölve."
@@ -2628,12 +2622,12 @@ msgstr "Összes fellépési hír tétel törölve."
msgid "All memos for channel %s have been deleted."
msgstr "Minden üzenetet töröltem a %s csatornán."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2656,7 +2650,7 @@ msgstr "Összes O:lines %s módosítva."
msgid "All random news items deleted."
msgstr "Összes random news tétel törölve."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
@@ -2668,12 +2662,12 @@ msgstr "Összes O:lines %s újra aktív."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s lett"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Az összes user vhosztja a(z) %s csoportba %s@%s lett"
#: src/access.cpp:41
@@ -2807,7 +2801,7 @@ msgstr ""
"Megengedi, hogy az IRCopok üzenetet küldjenek az összes \n"
"felhasználónak a hálózaton. Üzenetet a %s nickről küldi."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2823,7 +2817,7 @@ msgstr ""
"\t\n"
"Korlátozva Szervíz operatornak."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2837,7 +2831,7 @@ msgstr ""
"\t\n"
"Korlátozva Szervíz operatornak."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2848,13 +2842,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2922,7 +2916,7 @@ msgstr ""
"Ignores will not be enforced on IRC Operators.\n"
"\t"
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2987,7 +2981,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz operatornak."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2995,19 +2989,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3056,7 +3048,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz adminoknak."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3064,12 +3056,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3105,7 +3096,7 @@ msgstr ""
"\n"
"Elérhető opciók:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3123,7 +3114,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3136,7 +3127,7 @@ msgstr ""
"the given user. With MSG set, Services will use messages,\n"
"else they'll use notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3150,7 +3141,7 @@ msgstr ""
"Az MSG beállítással, a szervíz, privát üzeneteket fog\n"
"használni, egyébként pedig noticeokat."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3232,13 +3223,13 @@ msgstr ""
"kapsz információkat, például létrehozás ideje, csatornák\n"
"száma."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Törli egy felhasználónak a vhostját"
@@ -3248,15 +3239,10 @@ msgstr " DEL Törli egy felhasználónak a vhostját"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s is a services operator of type %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr "ASSIGN Társít egy botot a csatornához"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3266,16 +3252,21 @@ msgstr ""
"botodat a csatornád igényeidnek megfelelően.\n"
"Kellemes botozást! :-)"
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr "ASSIGN Társít egy botot a csatornához"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "ASSIGN Társít egy botot a csatornához"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET Köszöntő üzenet társítása a nicknevedhez"
@@ -3285,12 +3276,12 @@ msgstr " GREET Köszöntő üzenet társítása a nicknevedhez"
msgid "Associate a greet message with your nickname"
msgstr " GREET Köszöntő üzenet társítása a nicknevedhez"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL Egy E-mail cím társítása a nicknevedhez"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL Egy E-mail cím társítása a nicknevedhez"
@@ -3300,12 +3291,12 @@ msgstr " EMAIL Egy E-mail cím társítása a nicknevedhez"
msgid "Associate oper info with a nick or channel"
msgstr "ASSIGN Társít egy botot a csatornához"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL Egy E-mail cím társítása a nicknevedhez"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3318,7 +3309,7 @@ msgstr ""
"Ez az E-mail cím szerepelni fog az INFO-id között,\n"
"amit bárki lekérhet az INFO paranccsal."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3347,17 +3338,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "Nincs ezzel kapcsolatban segítség: %s."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Nincs ezzel kapcsolatban segítség: %s."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3372,20 +3358,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr "\tCsúnya szavakért kirúgás: %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "%s hozzáférési listája:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Tiltott szó lista üres."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "%s nevű bot már létezik."
@@ -3404,7 +3390,7 @@ msgstr "A megadott csatorna (%s) új ban típusa: #%d."
msgid "Bans a given nick or mask on a channel"
msgstr " BAN Bans a selected nick on a channel"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3432,7 +3418,7 @@ msgstr "%s nem kért értesítést az üzeneteiről."
msgid "Bolds kicker"
msgstr "\tFélkövér betűkért kirúgás: %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "%s nevű bot már létezik."
@@ -3447,12 +3433,12 @@ msgstr "%s nevű bot már létezik."
msgid "Bot %s has been assigned to %s."
msgstr "A %s nevű bot társítva a %s szobához."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "A %s nevű bot megváltoztatva %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "A %s nevű bot törölve."
@@ -3482,42 +3468,42 @@ msgstr "A Bot nem fog opot kirúgni a %s szobából."
msgid "Bot won't kick voices on channel %s."
msgstr "A Bot nem fogja a hangadókat kirúgni a %s szobában."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Nincs Bot mód most ONa %s szobán."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "A %s nevű bot törölve."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot Hosts may only contain %d characters."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot Hoszt csak érvényes karaktereket tartalmazhat."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot Ident csak érvényes karaktereket tartalmazhat."
@@ -3535,12 +3521,12 @@ msgstr "Botok listája:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot Nick csak érvényes karaktereket tartalmazhat."
@@ -3632,8 +3618,8 @@ msgstr "A Bot nem fog kirúgni flood miatt."
msgid "Bot won't kick for repeats anymore."
msgstr "A Bot nem fog kirúgni ismétlés miatt."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3671,12 +3657,12 @@ msgstr ""
"Visszavonja az utolsó memo üzenetet, amit a nicknek\n"
"vagy csatornának küldtél."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "A Bot most már opot is kirúg a %s szobából."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Nem lehet most levelet küldeni; próbáld újra később."
@@ -3771,22 +3757,22 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s váltóztatott a módodon."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr " MSG Megváltoztatja a szervízzel való kommunikációt"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s váltóztatott a módodon."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "%s usermódjai megváltoztatva."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3798,7 +3784,7 @@ msgstr ""
"szervízben.\tAz új megjelenítésnek a csoport egyik\n"
"nickjének KELL lennie."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3821,7 +3807,7 @@ msgstr ""
"Megváltoztatja a szoba founderjét.\n"
"Az új nicknév regisztrált kell hogy legyen!"
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3834,7 +3820,7 @@ msgstr ""
"írja.(Például: amikor válaszol egy parancsra, amit te \n"
"adtál ki). A sorszám alapján válaszd ki a nyelvezetet:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3847,7 +3833,7 @@ msgstr ""
"írja.(Például: amikor válaszol egy parancsra, amit te \n"
"adtál ki). A sorszám alapján válaszd ki a nyelvezetet:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3855,7 +3841,7 @@ msgstr ""
"\n"
"Megváltoztatja a nicknév tulajdonosának jelszavát."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3883,7 +3869,7 @@ msgstr ""
"is ez történik, ha nem volt megadva successor.\n"
"A nicknek regisztrálnak kell lennie."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP #szoba"
@@ -3963,12 +3949,12 @@ msgstr "A megadott csatorna (%s) el fog évülni."
msgid "Channel %s will not expire."
msgstr "A megadott csatorna (%s) nem fog elévülni."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Channel %s AOP list has been cleared."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Channel %s access list has been cleared."
@@ -3978,7 +3964,7 @@ msgstr "Channel %s access list has been cleared."
msgid "Channel %s akick list has been cleared."
msgstr "Channel %s akick list has been cleared."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "(%s) szoba újra használható."
@@ -4005,8 +3991,8 @@ msgstr ""
"Azon csatornák, ahol %s nicknek hozzáférése van:\n"
" Sorszám Csatorna Szint Meghatározás"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s nem található a (%s) csatorna hozzáférési listáján."
@@ -4072,7 +4058,7 @@ msgstr " CHECK Ellenőrzi, hogy a címzett elolvasta-e már az üzit"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Syntax: CHECK nick\n"
"\n"
@@ -4172,7 +4158,7 @@ msgstr "KICK Konfigurálja a kirúgásokat"
msgid "Configures reverses kicker"
msgstr "KICK Konfigurálja a kirúgásokat"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "SET Konfigurálja a bot opcióit"
@@ -4187,7 +4173,7 @@ msgstr "KICK Konfigurálja a kirúgásokat"
msgid "Confirm a passcode"
msgstr " CONFIRM Confirm a nickserv auth code"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES Törli a szoba módot"
@@ -4197,50 +4183,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr "Született: %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr "Született: %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Aktuális AKILL lista:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Aktuális AKILL lista:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Aktuális Session korlát kivétel lista:"
@@ -4294,13 +4280,13 @@ msgstr "FORBID nicknév indok"
msgid "DEL [nickname] mask"
msgstr "MODE szoba mód"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [#szoba] { szám | list | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [#szoba] { szám | list | ALL}"
@@ -4319,19 +4305,19 @@ msgstr "Syntax: OPERNEWS DEL {szám | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} szerver"
@@ -4345,7 +4331,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4475,17 +4461,22 @@ msgstr " OPERNEWS Operek részére megjelenő üzenetet állít be"
msgid "Delete a memo or memos"
msgstr " DEL Törli a megadott üzenete(ke)t"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Törli a vhosztot a nickekröl a csoportban"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Törli egy felhasználónak a vhostját"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "%d bejegyzés törölve a %s AOP listáról."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "%d bejegyzés törölve (%s) csatorna hozzáférési listájáról."
@@ -4495,7 +4486,7 @@ msgstr "%d bejegyzés törölve (%s) csatorna hozzáférési listájáról."
msgid "Deleted %d entries from %s autokick list."
msgstr "%d bejegyzés törölve a (%s) csatorna autokick listájáról."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Törölve %d bejegyzés %s tiltott szavak listájáról."
@@ -4515,7 +4506,7 @@ msgstr "%d bejegyzés törölve a %s AOP listáról."
msgid "Deleted %d entries from the AKILL list."
msgstr "Törölve %d bejegyzés az AKILL listáról."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "1 bejegyzés törölve a (%s) csatorna hozzáférési listájáról"
@@ -4525,7 +4516,7 @@ msgstr "1 bejegyzés törölve a (%s) csatorna hozzáférési listájáról"
msgid "Deleted 1 entry from %s autokick list."
msgstr "1 bejegyzés törölve a (%s) csatorna autokick listájáról."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Törölve 1 bejegyzés %s tiltott szavak listájáról."
@@ -4548,7 +4539,7 @@ msgstr "Törölve 1 bejegyzés az AKILL listáról."
msgid "Deleted info from %s."
msgstr "Törölve 1 bejegyzés az AKILL listáról."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "1 bejegyzés törölve a %s AOP listáról."
@@ -4598,11 +4589,6 @@ msgstr ""
"A vhost törölve az adott nick adatbázisából.\n"
"Korlátozva Hoszt változtatókra."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Törli a vhosztot a nickekröl a csoportban"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4615,13 +4601,13 @@ msgstr ""
"\n"
"Korlátozva Hoszt változtatókra."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "%s csatorna leírás megváltoztatva: %s."
@@ -4636,7 +4622,7 @@ msgstr "%s csatorna leírás megváltoztatva: %s."
msgid "Description of %s unset."
msgstr "%s csatorna leírás megváltoztatva: %s."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "%s is enable"
@@ -4662,7 +4648,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz adminnak."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Kiírja az összes bejegyzést (Számláló: %d)"
@@ -4784,12 +4770,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail address for %s changed to %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail address for %s unset."
@@ -4817,7 +4803,7 @@ msgstr ""
"to them. (However, no more than %d messages will be\n"
"sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"LOGONNEWS may only be used by Services Operators."
@@ -4839,7 +4825,7 @@ msgstr ""
"be sent to them. (However, no more than %d messages will\n"
"be sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"OPERNEWS may only be used by Services Operators."
@@ -4867,7 +4853,7 @@ msgstr "E-mail cím: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Egyező emailek %s ehhez: %s."
#: modules/fantasy.cpp:19
@@ -4878,11 +4864,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "%s is enable"
@@ -4915,14 +4901,14 @@ msgstr ""
"a topicot a %s megjegyzi miután az utolsó user elhagyja a\n"
"szobát, és visszaállítja a következő megnyitáskor."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -5022,8 +5008,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Syntax: %s #szoba SECUREOPS {ON | OFF}\n"
"\n"
@@ -5067,7 +5053,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5092,22 +5078,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Vége a felhasználó listának."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "Hozzáférési lista vége."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Lista vége - %d / %d találat megjelenítve."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Hozzáférési lista vége."
@@ -5116,7 +5102,7 @@ msgstr "Hozzáférési lista vége."
msgid "End of autokick list"
msgstr "Hozzáférési lista vége."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Vége a felhasználó listának."
@@ -5149,7 +5135,7 @@ msgstr "Vége a felhasználó listának."
msgid "End of list - %d channels shown."
msgstr "Lista vége - %d / %d találat megjelenítve."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Lista vége - %d / %d találat megjelenítve."
@@ -5184,8 +5170,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Magyar"
@@ -5242,44 +5228,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "%s kivétel (#%d) áthelyezve a %d pozicíóba."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception for %s has been updated to %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr "Expires in: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Exception for %s has been updated to %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Lejárati idő megváltozott: %s."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasy"
@@ -5308,16 +5299,16 @@ msgstr "Ez a maszk: %s már szerepel a hozzáférési listádon."
msgid "Fingerprint %s is already in use."
msgstr "You are already in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "%s hozzáférése a (%s) csatornán változott: %d."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "%s hozzáférési listája:"
@@ -5407,7 +5398,7 @@ msgstr "A megadott csatorna (%s) új foundere: %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "GETPASS nem elérhető, amíg az encryption használatban van"
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "A befagyott kliens killelve."
@@ -5416,14 +5407,14 @@ msgstr "A befagyott kliens killelve."
msgid "Give Operflags to a certain user"
msgstr " OLINE Operflaget ad a biztos felhasználónak"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Gives you owner status on channel"
@@ -5499,24 +5490,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Nem írj visszafelé ezen a csatornán!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "%s nevű bot már létezik."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "%s nevű bot már létezik."
@@ -5526,8 +5513,8 @@ msgstr "%s nevű bot már létezik."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Jelszavas azonosítás"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Ha nem váltasz nevet 20 sec.-en belül, én megváltoztatom."
@@ -5540,12 +5527,12 @@ msgstr "Mellőzöttek lista törölve."
msgid "Ignore list is empty."
msgstr "Mellőzöttek lista üres."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "Botok listája:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Voices védelme"
@@ -5602,7 +5589,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5622,7 +5609,7 @@ msgstr ""
"Érvénytelen küszöb érték. 1-nél nagyobb egész számnak\n"
"kell lennie."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5642,17 +5629,17 @@ msgstr "\tItalics kicker : %s"
msgid "Join a group"
msgstr " GROUP Csatlakozás egy csoporthoz"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Üzenet mód"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Peace option for %s is now ON."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Peace option for %s is now ON."
@@ -5671,7 +5658,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr " KICK Kirúgja a felhasználót csatornáról"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5681,13 +5668,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Syntax: KICK #szoba nick [indok]\n"
"\n"
@@ -5713,19 +5700,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [#szoba] [list | NEW ]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [#szoba] [list | NEW ]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK nicknév "
@@ -5734,15 +5721,10 @@ msgstr "CHECK nicknév "
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS { ADD | DEL | LIST } [szöveg|szám]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Új nyelvezet: Magyar."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "A megadott csatorna (%s) új successora: %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5753,7 +5735,7 @@ msgstr "%s részére küldött utolsó memo üzenet visszavonva."
msgid "Last quit message"
msgstr "Utolsó kilépő üzenet: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr "Utoljára ekkor volt: %s"
@@ -5763,11 +5745,11 @@ msgstr "Utoljára ekkor volt: %s"
msgid "Last seen address"
msgstr "Utoljára látott cím: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr "Utoljára ekkor volt: %s"
@@ -5777,27 +5759,27 @@ msgstr "Utoljára ekkor volt: %s"
msgid "Last usermask"
msgstr "Utoljára ekkor volt: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "%s szintjének új értéke a (%s) csatornán: %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "A szintnek kizárólag %d és %d között kell lennie."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5813,7 +5795,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr " ALIST List channels you have access on"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5823,7 +5805,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST Listázza a betöltött modulokat"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "%s csoportjába tartozó nickek listája:"
@@ -6079,18 +6061,18 @@ msgstr " MODLIST Listázza a betöltött modulokat"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Lists information about the named registered channel"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Syntax: INFO #szoba\n"
"\n"
@@ -6177,7 +6159,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6216,12 +6202,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK AutoKirúgás listára teheted a \"rossz\" usereket"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr "BOT Karbantartja a hálózat botjainak listáját"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6229,7 +6215,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6247,7 +6233,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6259,7 +6245,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6310,7 +6296,7 @@ msgstr ""
"BADWORDS CLEAR parancs törli az összes bejegyzést\n"
"a tiltott szavak listájáról"
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr "BADWORDS Szerkeszti a tiltott szavak listáját"
@@ -6325,7 +6311,7 @@ msgstr ""
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Syntax: ACT #szoba szöveg\n"
"\n"
@@ -6334,13 +6320,13 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr ""
"SAY Makes the bot say the given text on the given channel"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr ""
"SAY Makes the bot say the given text on the given channel"
@@ -6375,7 +6361,7 @@ msgstr ""
"megfelelő szinttel, ami az üzenet megjelenitéséhez\n"
"szükséges a csatornán."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "Nem törölheted ezen a hálózaton az e-mail címed."
@@ -6395,12 +6381,12 @@ msgstr " IGNORE Módosítja a Szervíz mellőzési listáját"
msgid "Manage your auto join list"
msgstr " AKICK AutoKirúgás listára teheted a \"rossz\" usereket"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL Szerkeszti az AKILL listát"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL Szerkeszti az AKILL listát"
@@ -6410,20 +6396,20 @@ msgstr " AKILL Szerkeszti az AKILL listát"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Manipulálja a DefCon rendszert"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Manipulate the topic of the specified channel"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6436,8 +6422,8 @@ msgstr "Ez a maszk: %s már szerepel a hozzáférési listádon."
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "Ez a maszk: %s már szerepel a hozzáférési listádon."
@@ -6469,7 +6455,7 @@ msgstr "\tRögzített módok: %s"
msgid "Memo %d has been deleted."
msgstr "A megadott üzenetet (%d) töröltem."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Mellőzöttek lista üres."
@@ -6489,7 +6475,7 @@ msgstr "%s maximálisan fogadható üzeneteinek száma: %d."
msgid "Memo limit for %s set to 0."
msgstr "%s ezentúl nem fogadhat üzeneteket."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Üzenet elküldve %s részére."
@@ -6504,7 +6490,7 @@ msgstr "\tRögzített módok: %s"
msgid "Message"
msgstr "GLOBAL üzenet"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Üzenet mód"
@@ -6512,26 +6498,26 @@ msgstr "Üzenet mód"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "%s nick nem található a mellőzöttek listáján."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr "\tRögzített módok: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr "\tRögzített módok: %s"
@@ -6540,11 +6526,6 @@ msgstr "\tRögzített módok: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6595,7 +6576,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6606,7 +6587,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Módosítja a Szervíz mellőzési listáját"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP AutoOperátor lista beállítása"
@@ -6616,7 +6597,7 @@ msgstr " AOP AutoOperátor lista beállítása"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS A hozzáférési lista módosítása"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS A szoba hozzáférési listájának beállítása"
@@ -6626,7 +6607,7 @@ msgstr " ACCESS A szoba hozzáférési listájának beállítása"
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Módosítja a Szervíz mellőzési listáját"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Módosítja a session-korlát/kivétel listát"
@@ -6675,14 +6656,14 @@ msgstr "Modul: %s Verzió: %s Szerző: %s Betöltve: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Modul: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6695,19 +6676,19 @@ msgstr "%s hozzáférési listája:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "A %s nicknevet dropoltad."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "Ez a nicknév: %s már regisztrált!"
@@ -6722,7 +6703,6 @@ msgstr "Ez a nicknév: %s már regisztrált!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr " %snick illegális nicknév vagy nem használható."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6738,7 +6718,7 @@ msgstr "Ez a nick: %s jelenleg használatban van."
msgid "Nick %s is forbidden."
msgstr "Ezt a nicket %s nem fogja a services."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s is a services operator of type %s."
@@ -6763,12 +6743,12 @@ msgstr "Nickname %s registered."
msgid "Nick %s was truncated to %d characters."
msgstr "A nicked %s meg lett csonkítva %d karakter hosszúságúra."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s will expire."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s will not expire."
@@ -6833,17 +6813,17 @@ msgstr "A megadott csatorna %s már regisztrált!"
msgid "Nickname %s may not be registered."
msgstr "Ez a csatorna %s nem regisztrálható. "
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Ez a nicknév: %s számodra lett regisztrálva: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Nickname %s registered."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6852,7 +6832,7 @@ msgstr "Auto-op"
msgid "No bot"
msgstr "Nincs bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "nem fog elévülni"
@@ -6881,13 +6861,13 @@ msgstr "Nincs törölhető fellépési hír!"
msgid "No matches for %s found."
msgstr "Nincs Email listázva ehhez: %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "Nincs ilyen bejegyzés a %s AOP listán."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Nincs ilyen bejegyzés a (%s) csatorna hozzáférési listáján."
@@ -6897,21 +6877,21 @@ msgstr "Nincs ilyen bejegyzés a (%s) csatorna hozzáférési listáján."
msgid "No matching entries on %s autokick list."
msgstr "Nincs ilyen bejegyzés a (%s) csatorna autokick listáján."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Nincs ilyen szó %s a tiltott szavak listáján."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "Nincs ilyen bejegyzés a session-korlát kivétel listán."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Nincs ilyen bejegyzés a %s AOP listán."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Nincs ilyen bejegyzés az AKILL listán."
@@ -6924,7 +6904,12 @@ msgstr "Nincs visszavont memo üzenet."
msgid "No modules currently loaded matching that criteria."
msgstr "Jelenleg nincs modul betöltve."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Nem lehet új nicket regisztrálni."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6944,12 +6929,7 @@ msgstr "Nincs törölhető random news tétel!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Nem lehet új nicket regisztrálni."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6958,8 +6938,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "%s hozzáférési listája:"
@@ -6969,7 +6949,7 @@ msgstr "%s hozzáférési listája:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "%s usermódjai megváltoztatva."
@@ -6984,7 +6964,7 @@ msgstr "Nincs Bot mód most ONa %s szobán."
msgid "No-bot mode is now on on channel %s."
msgstr "Nincs Bot mód most ONa %s szobán."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6993,21 +6973,21 @@ msgstr ""
msgid "None"
msgstr "Nincs"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -7015,18 +6995,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS { ADD | DEL |LIST } [ szöveg | szám ]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "A régi info megegyezik az újjal."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr "Jelenleg online erről a címről: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7050,12 +7027,12 @@ msgstr "Oper news tétel #%d nem található!"
msgid "Oper news items:"
msgstr "Oper hírek listája:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "A %s nicknevet dropoltad."
@@ -7070,17 +7047,17 @@ msgstr "%s operflagek megadva a %s nicknek."
msgid "Operflags %s have been removed from %s."
msgstr "%s operflagek megadva a %s nicknek."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7094,12 +7071,12 @@ msgstr "Opok védelme"
msgid "Options"
msgstr "Beállításai: %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} szerver"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7116,12 +7093,12 @@ msgstr "Hibás jelszó."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "A megadott csatorna (%s) új successora: %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "%s nick jelszava elküldve."
@@ -7141,7 +7118,7 @@ msgstr "Hibás jelszó."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Békesség"
@@ -7155,7 +7132,7 @@ msgstr "Peace option for %s is now ON."
msgid "Peace option for %s is now on."
msgstr "Peace option for %s is now ON."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7186,12 +7163,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Kérlek várj %d másodpercet és próbáld újra."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Kérlek, várj %d másodpercet mielőtt SEND parancsot újra használod!"
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Kérlek, várj %d másodpercet mielőtt SEND parancsot újra használod!"
@@ -7201,12 +7178,12 @@ msgstr "Kérlek, várj %d másodpercet mielőtt SEND parancsot újra használod!
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Kérlek várj %d másodpercet, mielőtt ismét használod a GROUP parancsot."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr " Várj %d másodpercet mielőtt használnád ezt a parancsot!"
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7219,7 +7196,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7249,7 +7226,7 @@ msgstr ""
" PRIVATE Prevent the nickname from appearing in a\n"
" /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE Prevent the nickname from expiring"
@@ -7258,17 +7235,17 @@ msgstr " NOEXPIRE Prevent the nickname from expiring"
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privát"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Private mód a %s botban most ON."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Private mód a %s botban most ON."
@@ -7293,36 +7270,36 @@ msgstr "Private option is now ON for %s."
msgid "Private option is now on for %s."
msgstr "Private option is now ON for %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Kill védelem"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Protection is now ON for %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Protection is now ON for %s, with a reduced delay."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Protection is now ON for %s, with no delay."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Protection is now ON for %s."
@@ -7339,7 +7316,7 @@ msgstr ""
"és teljesen valós ident@host maszkot használja, minden \n"
"nick esetében végrehajtja az AKILLt."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Voices védelme"
@@ -7385,20 +7362,20 @@ msgstr " READ Elolvassa a megadott üzenete(ke)t"
msgid "Real name"
msgstr "Valódi neve: %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "A megadott csatorna %s successora törölve."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7408,33 +7385,33 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS Ãtállíthatod a szoba hozzáférési szintjeit"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr " RELEASE Visszaadja a neved a RECOVER után"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s is enable"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7446,12 +7423,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Nicknév regisztráció"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Nicknév regisztráció"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr "Regisztrálás ideje: %s"
@@ -7510,7 +7487,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7560,7 +7537,7 @@ msgstr ""
"megoszthasd a hozzáféréseidet és beállításaidat a nickjeid\n"
"között. Bővebb információkért írd be: /msg %s HELP GROUP"
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Sajnálom, a csatorna regisztráció jelenleg szünetel."
@@ -7570,12 +7547,12 @@ msgstr "Sajnálom, a csatorna regisztráció jelenleg szünetel."
msgid "Regulate the use of critical commands"
msgstr " PEACE Szabályozza a kritikus parancsok használatát"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Returns the owner status of the given nickname"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Törli egy felhasználónak a vhostját"
@@ -7626,46 +7603,46 @@ msgstr ""
" NOOP Ideiglenesen törli az összes O:line-t a szerver\n"
" távollétében"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr "\tRögzített módok: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr " OP Gives Op status to a selected nick on a channel"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7681,14 +7658,14 @@ msgstr "\tIsmétlésért kirúgás: %s"
msgid "Request a vHost for your nick"
msgstr "Nincs beállítva email cím a nevedhez."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Újratölti a szervíz Konfigurációs fájlját"
@@ -7698,7 +7675,7 @@ msgstr " RELOAD Újratölti a szervíz Konfigurációs fájlját"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Restrict access to the channel"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Korlátozott hozzáférés"
@@ -7735,7 +7712,7 @@ msgstr ""
" GETPASS Kiirja a jeszavát a nicknévnek\n"
" (encryption esetén nem használható)"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7751,8 +7728,18 @@ msgstr " GETKEY Returns the key of the given channel"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Returns the key of the given channel"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Syntax: GETEMAIL user@emailhoszt\n"
+"Visszaadja a megadott emaillel regisztrált nickeket.\n"
+"Megjegyzés: használhatsz * karaktert mind a user,\n"
+"mind az emailhost esetében. A parancs kiadásakor a\n"
+"lekért email cím és az azt lekérő személy naplózva lesz.\n"
+"Korlátozva Szervíz adminra."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7836,16 +7823,16 @@ msgstr " LOGOUT Reverses the effect of the IDENTIFY command"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} szerver"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Jelszavad elfogadva - azonosítás sikeres."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Jelszavad elfogadva - azonosítás sikeres."
@@ -7868,7 +7855,7 @@ msgstr " RESTART Menti az adatbázist, és újraindítja a szervízt"
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Founderjog védelme"
@@ -7883,7 +7870,7 @@ msgstr "Secure founder option for %s is now ON."
msgid "Secure founder option for %s is now on."
msgstr "Secure founder option for %s is now ON."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Opjog védelme"
@@ -7908,12 +7895,12 @@ msgstr "Secure option for %s is now ON."
msgid "Secure option for %s is now on."
msgstr "Secure option for %s is now ON."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Secure option is now ON for %s."
@@ -7923,11 +7910,11 @@ msgstr "Secure option is now ON for %s."
msgid "Secureops enforced on %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Biztonság"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7936,7 +7923,7 @@ msgstr ""
"Ãrd be: /msg %s HELP SET opció bÅ‘vebb információért az\n"
"adott opcióról."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -8003,7 +7990,7 @@ msgstr ""
"\n"
"Memo üzenet küldése az opereknek/adminoknak."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8079,14 +8066,14 @@ msgid "Server %s already exists."
msgstr "%s nevű bot már létezik."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "A %s nicknevet dropoltad."
@@ -8096,12 +8083,12 @@ msgstr "A %s nicknevet dropoltad."
msgid "Server %s is already in zone %s."
msgstr "You are already in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s jelenleg online."
@@ -8116,12 +8103,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "Nincsen bot kijelölve %s szobában többet."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8141,19 +8128,18 @@ msgstr "Servers found: %d"
msgid "Service"
msgstr "Servers found: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "A Services rendelkezésedre bocsájtotta a nicket."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s is a services operator of type %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr "Szervíz Defcon módban fut, próbáld később."
@@ -8208,7 +8194,7 @@ msgstr "A Szervíz úgy van beállítva, hogy nem küld mailt."
msgid "Services ignore list:"
msgstr " IGNORE Módosítja a Szervíz mellőzési listáját"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8222,7 +8208,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Servers found: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8232,7 +8218,7 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8242,12 +8228,12 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services will now autoop %s in channels."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services will now reply to %s with messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services will now reply to %s with notices."
@@ -8266,7 +8252,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Session korlát %s részére %d-re állítva."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Session korlátozás tiltva."
@@ -8310,7 +8296,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC A szobameghatározás állítás"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Set the display of your group in Services"
@@ -8320,12 +8306,12 @@ msgstr " DISPLAY Set the display of your group in Services"
msgid "Set the founder of a channel"
msgstr " FOUNDER A founder megváltoztatása"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr " LANGUAGE A szervíz nyelvezetének megválasztása"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Set the nickname password"
@@ -8698,7 +8684,7 @@ msgstr ""
"\n"
"Beállítható nicknév opciók. Az opció ezek egyike lehet:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8716,7 +8702,7 @@ msgstr ""
"\n"
"Korlátozva Szervíz adminnak."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8731,7 +8717,7 @@ msgstr ""
"Set to ON to allow ChanServ to op the given nickname \n"
"automatically when joining channels."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8742,7 +8728,7 @@ msgstr ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8755,7 +8741,7 @@ msgstr ""
"Sets whether you will be opped automatically. Set to ON to \n"
"allow ChanServ to op you automatically when entering channels."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8822,11 +8808,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Signed kick option for %s is now ON."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Signed kicks"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s túl sok üzenettel rendelkezik, és nem fogadhat többet."
@@ -8836,44 +8822,38 @@ msgstr "%s túl sok üzenettel rendelkezik, és nem fogadhat többet."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Csatornán tiltott szaval listájának változtatása letiltva."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Bot beállítás időlegesen szünetel."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "A bot módosítás ideiglenesen szünetel."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Bot beállítás időlegesen szünetel."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Bot beállítás időlegesen szünetel."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Csatorna AOP lista módosítás szünetel."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "A csatorna hozzáférési listájának módosítása szünetel."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Csatorna autokick listájának módosítása szünetel."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Csatornán tiltott szaval listájának változtatása letiltva."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "A csatornák regisztrációjának törlése jelenleg szünetel."
@@ -8903,7 +8883,7 @@ msgstr "Sajnálom, a nicknevek regisztrációjának törlése szünetel."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Sajnálom, a csoportok használata ideiglenesen le van tiltva."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Sajnálom, a nickregisztráció jelenleg nem működik."
@@ -8922,13 +8902,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Neked csak %d bejegyzésed lehet a hozzáférési listán."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8940,7 +8915,7 @@ msgstr "Neked csak %d helyed van a csatorna listáján."
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "%d bejegyzésnél nem lehet több a listán."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Csak %d tiltott szó lehet a csatornán."
@@ -9007,7 +8982,7 @@ msgstr "A megadott csatorna %s successora törölve."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "SuperAdmin setting not enabled in services.conf"
+msgstr "SuperAdmin setting not enabled in anope.conf"
#: modules/commands/ns_suspend.cpp:60
#, fuzzy
@@ -9230,7 +9205,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9305,7 +9280,7 @@ msgstr ""
"Ez az opció nem ajánlott, csak akkor használd, ha \n"
"szükséges és kapcsold ki, ha már nem."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9326,7 +9301,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Syntax: INVITE #szoba\n"
@@ -9344,7 +9319,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Syntax: UNBAN #szoba [nick]\n"
@@ -9398,7 +9373,7 @@ msgstr " SHUTDOWN Leállítja a szervíz programot mentéssel"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9409,7 +9384,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9418,7 +9393,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9435,10 +9410,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9446,14 +9421,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9468,7 +9443,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Syntax: HOP #szoba ADD nick\n"
@@ -9516,36 +9491,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "Az IMMED opció nem elérhető ezen a hálózaton."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9593,7 +9568,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9604,18 +9579,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9623,7 +9598,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9636,7 +9611,6 @@ msgstr ""
"Az email címed nem lesz kiadva harmadik személynek."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9654,7 +9628,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9664,12 +9638,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "Az AKILL lista törölve."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "Az AKILL lista törölve."
@@ -9688,7 +9662,7 @@ msgstr "The E-mail address of %s will now be hidden from %s INFO displays."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "The E-mail address of %s will now be shown in %s INFO displays."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9719,11 +9693,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9785,12 +9759,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "Nem változtathatod meg %s üzeneteinek számát."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9805,10 +9774,6 @@ msgstr "A Defcon szint most: %d"
msgid "The nick %s is now being changed to %s."
msgstr "A nicked %s meg lett változtatva erre: %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9832,12 +9797,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"The services access status of %s will now be shown in %s INFO displays."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Módosítja a session-korlát/kivétel listát"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9909,7 +9874,7 @@ msgstr "Nincs véletlenszerű hír."
msgid "There is no such configuration block %s."
msgstr " RELOAD Újratölti a szervíz Konfigurációs fájlját"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Nincs oper news."
@@ -9937,7 +9902,7 @@ msgstr "Ez a csatorna nem használható."
msgid "This channel may not be used."
msgstr "Ez a csatorna nem használható."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9973,7 +9938,7 @@ msgstr ""
"Ez a parancs lehetővé teszi, hogy a JELENLEGI nick\n"
"vhostját beállítsuk a csoport minden nickjére."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9986,7 +9951,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -10021,8 +9986,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10121,7 +10086,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10136,7 +10101,7 @@ msgstr ""
"Ez a parancs betölti azt modult, a modules könyvtárból,\n"
"amelyiknek a fájlnevét megadtad."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10189,7 +10154,7 @@ msgstr ""
"Ez a parancs betölti azt modult, a modules könyvtárból,\n"
"amelyiknek a fájlnevét megadtad."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10205,12 +10170,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10271,7 +10236,7 @@ msgstr ""
msgid "Topic"
msgstr "Témaváltás lezárása"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Témaváltás lezárása"
@@ -10286,7 +10251,7 @@ msgstr "Topic lock option for %s is now ON."
msgid "Topic lock option for %s is now on."
msgstr "Topic lock option for %s is now ON."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Témamegőrzés"
@@ -10301,7 +10266,7 @@ msgstr "Topic retention option for %s is now ON."
msgid "Topic retention option for %s is now on."
msgstr "Topic retention option for %s is now ON."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10309,17 +10274,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Kapcsold ki a caps lockod!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE A nickneved védelmének be-,kikapcsolása"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE A nickneved védelmének be-,kikapcsolása"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL A kill védelem be-,kikapcsolása"
@@ -10359,7 +10325,7 @@ msgstr ""
"(Máskülönben, bárki kaphat információt a nicknevedről\n"
"használva az INFO parancsot.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10390,7 +10356,7 @@ msgstr " SECURE A nickneved védelmének be-,kikapcsolása"
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE A nickneved védelmének be-,kikapcsolása"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10421,7 +10387,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10452,7 +10418,7 @@ msgstr ""
"kérlek ne használd ezt az opciót csak ha nagyon indokolt.\n"
"A network adminisztrátorok letilthatják ezt."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10489,7 +10455,7 @@ msgstr ""
"on a specific option. The options will be set on the given\n"
"nickname. "
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10498,7 +10464,7 @@ msgstr ""
"Ãrd be: /msg %s HELP SET opció bÅ‘vebb információért az\n"
"adott opcióról."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10513,8 +10479,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Kitölti a modult"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Nem sikerült eltávolítani a %s modult"
@@ -10558,7 +10524,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "\tAláhúzásért kirúgás: %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Unknown SASET option %s."
@@ -10578,7 +10544,7 @@ msgstr "Ismeretlen beállítás %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Ismeretlen parancs %s. Ãrd be: \"%s%s HELP\"."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Ismeretlen mód karakter: %c figyelmen kívül hagyva."
@@ -10606,8 +10572,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Syntax: DROP #szoba\n"
"\n"
@@ -10624,10 +10590,10 @@ msgstr " UNSUSPEND Unsuspend a given nick"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10678,31 +10644,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s váltóztatott a módodon."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS A szoba hozzáférési listájának beállítása"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "%s csatornán a tiltást levetetted magadról."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "%s vhosztja törölve lett."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "%s maximálisan fogadható üzeneteinek száma: %d."
@@ -10755,13 +10721,13 @@ msgstr "A %s csoport vhostja erre változott: %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [#szoba] [list | NEW ]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10774,7 +10740,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "A megadott csatorna (%s) új foundere: %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10812,7 +10778,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10899,7 +10865,7 @@ msgstr ""
"A RESET beállítás nullázza az aktuális felhasználók max.\n"
"számát átírja a jelenlegi felhasználó számra\t"
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10908,7 +10874,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Már tagja vagy ennek a csoportnak: %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Már be vagy azonosítva. :-)"
@@ -10973,7 +10939,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10998,13 +10964,22 @@ msgstr ""
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "You can not request a receipt when sending a memo to yourself."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Nem ghostolhatod ki magad!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Nincs ilyen bejegyzés a (%s) csatorna hozzáférési listáján."
@@ -11014,16 +10989,11 @@ msgstr "Nincs ilyen bejegyzés a (%s) csatorna hozzáférési listáján."
msgid "You can't logout %s, they are a Services Operator."
msgstr "%s nem tud kijelentkezni, mert Å‘ egy Services Operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "Nem törölheted ezen a hálózaton az e-mail címed."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -11034,12 +11004,7 @@ msgstr "%s max. bejövő üzenetek száma nem lehet több, mint %d."
msgid "You cannot set your memo limit higher than %d."
msgstr "A max. bejövő üzenetek száma nem lehet több, mint %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Nem törölheted ezen a hálózaton az e-mail címed."
@@ -11079,12 +11044,12 @@ msgstr "Van 1 üzeneted."
msgid "You currently have no memos."
msgstr "Jelenleg nincs üzeneted."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11120,7 +11085,7 @@ msgstr "You have been invited to %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "A nicked sikeresen kijelentkezett."
@@ -11163,32 +11128,27 @@ msgstr ""
"Figyelem: Fogadható üzenetek maximális száma (%d).\n"
"Nem fogadhatsz több üzenetet, amíg nem törölsz néhányat."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Törli a vhosztot a nickekröl a csoportban"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "Nem törölheted ezen a hálózaton az e-mail címed."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "Nem törölheted ezen a hálózaton az e-mail címed."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "%s nem tud kijelentkezni, mert Å‘ egy Services Operator."
@@ -11233,26 +11193,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "A csatornán operátornak kell lenned, hogy regisztrálhasd."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
msgstr "A csatornán operátornak kell lenned, hogy regisztrálhasd."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "A csatornán operátornak kell lenned, hogy regisztrálhasd."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "A csatornán operátornak kell lenned, hogy regisztrálhasd."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11260,18 +11205,18 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"A nicked regisztrálásához %d másodpercnél régebben kell csatlakozva lenned."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11282,33 +11227,15 @@ msgstr "Be kell állítanod egy E-mail címet a nicknevedhez."
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Értesítést kapsz új üzenetek érkezésekor."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr "Értesítést kapsz új üzenetek érkezéséről csatlakozáskor."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr "Értesítést kapsz új üzenetek érkezéséről csatlakozáskor."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr "Értesítést kapsz új üzenetek érkezéséről csatlakozáskor."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Értesítést kapsz az új üzeneteidről,ha fellépsz az IRC-re."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Értesítést kapsz új üzenetek érkezésekor."
@@ -11320,7 +11247,7 @@ msgstr "Ezentúl nem tudsz üzeneteket fogadni."
msgid "You will no longer be informed via email."
msgstr "Már nem kapsz értesítést emailben."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Nem kapsz értesítést az új üzeneteidről."
@@ -11346,23 +11273,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "A %s nevű bot törölve."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "Már be vagy azonosítva. :-)"
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Már be vagy azonosítva. :-)"
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "E-mail address for %s changed to %s."
@@ -11372,18 +11299,18 @@ msgstr "E-mail address for %s changed to %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Összes O:lines %s módosítva."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Összes O:lines %s módosítva."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "E-mail address for %s changed to %s."
@@ -11443,7 +11370,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Nickname %s registered."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "A nickneved most meg lesz változtatva: %s."
@@ -11452,43 +11379,42 @@ msgstr "A nickneved most meg lesz változtatva: %s."
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "A kód újra el lett küldve erre a címre: %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Jelszavad: %s - jegyezd meg a későbbi használathoz!"
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "A %s nevű bot törölve."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "A %s virtuális hosztod aktiválva."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "A %s@%s virtuális hosztod aktiválva."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -11538,7 +11464,7 @@ msgstr "[Véletlenszerű Hír] - %s %s"
msgid "[account] password"
msgstr "IDENTIFY jelszó"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #channel [nick]"
@@ -11596,8 +11522,8 @@ msgstr "INFO nick"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK nicknév "
@@ -11619,7 +11545,7 @@ msgstr "CHANKILL [+lejárat] {#szoba} [indok]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11627,22 +11553,22 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto-memo] A memo, amit %s számára küldtél meg lett tekintve."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto-memo] A memo, amit %s számára küldtél meg lett tekintve."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "%s részére küldött utolsó memo üzenet visszavonva."
@@ -11747,12 +11673,12 @@ msgstr ""
msgid "seconds"
msgstr "%s parancsok:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "A %s virtuális hosztod aktiválva."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "A %s nevű bot törölve."
@@ -11788,27 +11714,7 @@ msgstr "UNBAN #szoba [nick]"
msgid "{nick | channel}"
msgstr "CANCEL {nick | #szoba}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {nick | #szoba} memo-szöveg"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "%s kivétel (#%d) áthelyezve a %d pozicíóba."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "A régi info megegyezik az újjal."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Syntax: GETEMAIL user@emailhoszt\n"
-#~ "Visszaadja a megadott emaillel regisztrált nickeket.\n"
-#~ "Megjegyzés: használhatsz * karaktert mind a user,\n"
-#~ "mind az emailhost esetében. A parancs kiadásakor a\n"
-#~ "lekért email cím és az azt lekérő személy naplózva lesz.\n"
-#~ "Korlátozva Szervíz adminra."
diff --git a/language/anope.it_IT.po b/language/anope.it_IT.po
index 3668155ff..c338191a0 100644
--- a/language/anope.it_IT.po
+++ b/language/anope.it_IT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 20:40-0400\n"
"Last-Translator: Simos <simos@simosnap.org>\n"
"Language-Team: Italian\n"
@@ -27,17 +27,17 @@ msgstr "%d canale(i) eliminato(i), e %d canale(i) deregistrato(i)."
msgid "%d nickname(s) dropped."
msgstr "%d nickname(s) deregistrato(i)."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, c-format
msgid "%s added to %s %s list."
msgstr "%1$s aggiunto alla lista %3$s di %2$s."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s aggiunto alla lista di accesso di %s con il livello %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr ""
@@ -48,7 +48,7 @@ msgstr ""
msgid "%s added to %s autokick list."
msgstr "%s aggiunto alla lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s aggiunto alla lista delle bad words di %s."
@@ -63,17 +63,17 @@ msgstr "%s aggiunto alla lista di accesso di %s."
msgid "%s added to %s's certificate list."
msgstr "%s aggiunto alla lista dei certificati di %s."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, c-format
msgid "%s added to ignore list."
msgstr "%s aggiunto alla tua lista ignore."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s aggiunto alla lista %s."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s aggiunto alla lista AKILL."
@@ -107,7 +107,7 @@ msgstr ""
"Per maggiori informazioni sull'uso di un comando\n"
"specifico, digita %s%s %s comando.\n"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -124,7 +124,7 @@ msgstr ""
"Per maggiori informazioni su un comando specifico,\n"
"digita %s%s %s comando.\n"
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -139,7 +139,7 @@ msgstr ""
"Per maggiori informazioni su un comando specifico,\n"
"digita %s%s %s comando.\n"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -158,7 +158,7 @@ msgstr ""
"%s%s comando. Per avere maggiori informazioni su\n"
"un comando specifico, digita %s%s HELP comando.\n"
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s è già presente nella lista delle bad words di %s."
@@ -179,7 +179,7 @@ msgstr "%s esiste già nella lista EXCEPTION."
msgid "%s cannot be taken as times to ban."
msgstr "%s non può essere utilizzato come il numero di kick che porta al ban."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s ha modificato i tuoi usermodes in %s."
@@ -189,12 +189,12 @@ msgstr "%s ha modificato i tuoi usermodes in %s."
msgid "%s channel list:"
msgstr "Lista canalidi %s:"
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, c-format
msgid "%s deleted from %s %s list."
msgstr "%1$s eliminato dalla lista %3$s di %2$s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s eliminato dalla lista di accesso di %s."
@@ -204,7 +204,7 @@ msgstr "%s eliminato dalla lista di accesso di %s."
msgid "%s deleted from %s autokick list."
msgstr "%s eliminato dalla lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s eliminato dalla lista delle bad words di %s."
@@ -229,12 +229,12 @@ msgstr "%s eliminato dalla lista delle eccezioni."
msgid "%s deleted from the %s list."
msgstr "%s eliminato dalla lista %s"
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s eliminato dalla lista AKILL."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s disabilitato sul canale %s."
@@ -307,7 +307,7 @@ msgstr "%s è già presente in %s! "
msgid "%s is already in %s."
msgstr "%s è già presente in %s."
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, c-format
msgid "%s is already on the ignore list."
msgstr "%s è già presente nella lista ignore."
@@ -317,7 +317,7 @@ msgstr "%s è già presente nella lista ignore."
msgid "%s is already suspended."
msgstr "%s è già sospeso."
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s non è un nick o un canale registrato."
@@ -347,7 +347,7 @@ msgstr "%s non è al momento nel canale %s."
msgid "%s is not in %s."
msgstr "%s non è presente in %s."
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, c-format
msgid "%s is not on the ignore list."
msgstr "%s non trovato nella lista ignore."
@@ -382,12 +382,12 @@ msgid "%s matches auto kick entry %s on %s (%s)."
msgstr ""
"%s corrisponde al record %s presente nealla lista auto kick di %s (%s)."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, c-format
msgid "%s not found on %s %s list."
msgstr "%1$s non trovato nella lista %3$s di %2$s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s non trovato nella lista nella lista di accesso di %s."
@@ -397,7 +397,7 @@ msgstr "%s non trovato nella lista nella lista di accesso di %s."
msgid "%s not found on %s autokick list."
msgstr "%s non trovato nella lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s non trovato nella lista bad words di %s."
@@ -434,17 +434,17 @@ msgstr "Impossibile trovare %s nella lista delle eccezioni."
msgid "%s not found on the %s list."
msgstr "%s non trovato nella lista %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s non trovato nella lista AKILL."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, c-format
msgid "%s removed from the %s access list."
msgstr "%s eliminato dalla lista di accesso di %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, c-format
msgid "%s removed from the ignore list."
msgstr "%s rimosso dalla lista ignore."
@@ -476,20 +476,19 @@ msgstr ""
"Digita %s%s HELP %s option per ottenere maggiori\n"
"informazioni su un comando specifico."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr "CHANGE oldnick newnick [user [host [real]]]"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
msgid "DEL nick"
msgstr "DEL nick"
-#: modules/commands/os_session.cpp:560
-#, fuzzy
+#: modules/commands/os_session.cpp:601
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
"Note that nick!user@host and user@host masks are invalid!\n"
@@ -503,6 +502,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -548,7 +550,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -568,17 +570,17 @@ msgstr "[auto-memo] Il memo che hai inviato a %s è stato letto."
msgid "[target] [password]"
msgstr "[target] [password]"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr "address"
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
msgid "botname {ON|OFF}"
msgstr "botname {ON|OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
msgid "channel"
@@ -613,7 +615,7 @@ msgstr "channel nick"
msgid "channel nick [reason]"
msgstr "channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
msgid "channel target [what]"
msgstr "channel target [what]"
@@ -621,7 +623,7 @@ msgstr "channel target [what]"
msgid "channel text"
msgstr "channel text"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
msgid "channel time"
msgstr "channel time"
@@ -633,11 +635,11 @@ msgstr "channel user reason"
msgid "channel what"
msgstr "channel what"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
msgid "channel ADD mask"
msgstr "channel ADD mask"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr "channel ADD mask level"
@@ -645,7 +647,7 @@ msgstr "channel ADD mask level"
msgid "channel ADD message"
msgstr "channel ADD message"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr "channel ADD word [SINGLE | START | END]"
@@ -653,17 +655,17 @@ msgstr "channel ADD word [SINGLE | START | END]"
msgid "channel ADD {nick | mask} [reason]"
msgstr "channel ADD {nick | mask} [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
msgid "channel APPEND topic"
msgstr "channel APPEND topic"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
msgid "channel CLEAR"
msgstr "channel CLEAR"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
msgid "channel CLEAR [what]"
msgstr "channel CLEAR [what]"
@@ -675,7 +677,7 @@ msgstr "channel CLEAR [ALL]"
msgid "channel DEL num"
msgstr "channel DEL num"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
msgid "channel DEL {mask | entry-num | list}"
msgstr "channel DEL {mask | entry-num | list}"
@@ -683,7 +685,7 @@ msgstr "channel DEL {mask | entry-num | list}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "channel DEL {nick | mask | entry-num | list}"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
msgid "channel DEL {word | entry-num | list}"
msgstr "channel DEL {word | entry-num | list}"
@@ -691,7 +693,7 @@ msgstr "channel DEL {word | entry-num | list}"
msgid "channel ENFORCE"
msgstr "channel ENFORCE"
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
msgid "channel LIST"
msgstr "channel LIST"
@@ -699,36 +701,44 @@ msgstr "channel LIST"
msgid "channel LIST [mask | entry-num | list]"
msgstr "channel LIST [mask | entry-num | list]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
msgid "channel LIST [mask | list]"
msgstr "channel LIST [mask | list]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr "channel LIST [mask | +flags]"
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "channel LOCK {ADD|DEL|SET|LIST} [what]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr "channel MODIFY mask changes"
+
+#: modules/commands/cs_access.cpp:738
msgid "channel RESET"
msgstr "channel RESET"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
msgid "channel SET modes"
msgstr "channel SET modes"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+msgid "channel SET [topic]"
+msgstr "channel SET [topic]"
+
#: modules/commands/cs_akick.cpp:426
msgid "channel VIEW [mask | entry-num | list]"
msgstr "channel VIEW [mask | entry-num | list]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
msgid "channel VIEW [mask | list]"
msgstr "channel VIEW [mask | list]"
@@ -736,7 +746,7 @@ msgstr "channel VIEW [mask | list]"
msgid "channel [description]"
msgstr "channel [description]"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
msgid "channel [nick]"
msgstr "channel [nick]"
@@ -744,7 +754,7 @@ msgstr "channel [nick]"
msgid "channel [parameters]"
msgstr "channel [parameters]"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
msgid "channel [user]"
msgstr "channel [user]"
@@ -756,22 +766,12 @@ msgstr "channel [+expiry] [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "channel [+expiry] {nick | mask} [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "channel MODIFY mask changes"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "channel SET [topic]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
msgid "channel [UNLOCK|LOCK]"
msgstr "channel [UNLOCK|LOCK]"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
msgid "channel {ON|OFF}"
msgstr "channel {ON|OFF}"
@@ -794,7 +794,7 @@ msgstr "channel {ON|OFF} [ttb [num]]"
msgid "channel {ON|OFF} [ttb]"
msgstr "channel {ON|OFF} [ttb]"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr "channel {DIS | DISABLE} type"
@@ -816,24 +816,24 @@ msgstr "channel {ON | OFF}"
msgid "email"
msgstr "email"
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
msgid "language"
msgstr "language"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
msgid "memo-text"
msgstr "memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
msgid "message"
msgstr "message"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr "modname"
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr "new-display"
@@ -842,8 +842,9 @@ msgid "new-password"
msgstr "new-password"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
msgid "nick"
msgstr "nick"
@@ -868,16 +869,16 @@ msgstr "nick hostmask"
msgid "nick newnick"
msgstr "nick newnick"
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
msgid "nick [reason]"
msgstr "nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
msgid "nickname"
msgstr "nickname"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
msgid "nickname address"
msgstr "nickname address"
@@ -885,7 +886,7 @@ msgstr "nickname address"
msgid "nickname email"
msgstr "nickname email"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
msgid "nickname language"
msgstr "nickname language"
@@ -893,11 +894,11 @@ msgstr "nickname language"
msgid "nickname message"
msgstr "nickname message"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
msgid "nickname new-display"
msgstr "nickname new-display"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
msgid "nickname new-password"
msgstr "nickname new-password"
@@ -905,7 +906,7 @@ msgstr "nickname new-password"
msgid "nickname [parameter]"
msgstr "nickname [parameter]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
msgid "nickname [password]"
msgstr "nickname [password]"
@@ -917,14 +918,14 @@ msgstr "nickname [+expiry] [reason]"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
msgid "nickname {ON | OFF}"
msgstr "nickname {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "nickname {ON | QUICK | IMMED | OFF}"
@@ -960,11 +961,11 @@ msgstr "passcode"
msgid "password"
msgstr "password"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
msgid "password [email]"
msgstr "password [email]"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
msgid "password email"
msgstr "password email"
@@ -980,7 +981,7 @@ msgstr "pattern [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "server [reason]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
msgid "user modes"
msgstr "user modes"
@@ -988,7 +989,7 @@ msgstr "user modes"
msgid "user [reason]"
msgstr "user [reason]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, c-format
msgid ""
" \n"
@@ -1007,7 +1008,7 @@ msgstr ""
"o per altre azioni maliziose. L'abuso di %s\n"
"risulterà, come minimo, nella perdita del proprio nick."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
msgid ""
" \n"
"SNLINE ADD adds the given realname mask to the SNLINE\n"
@@ -1041,7 +1042,7 @@ msgstr ""
"Nota: visto che le mask di realname possono contenere spazi, il\n"
"separatore tra questa e il motivo sono i due punti."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1069,7 +1070,7 @@ msgstr ""
"anche se è la stessa di default. La durata di default per le\n"
"SQLINE può essere trovata con il comando STATS AKILL."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, c-format
msgid ""
" \n"
@@ -1185,7 +1186,7 @@ msgstr ""
"NOTA: Per registrare un canale, è necessario aver prima\n"
"registrato il tuo nickname."
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1211,7 +1212,7 @@ msgstr ""
"informazioni su come assegnare alcuni di questi privilegi ad\n"
"altri utenti del canale.\n"
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1222,7 +1223,7 @@ msgstr ""
"senza doversi identificare per quel nick, e possono visualizzare\n"
"le liste di accesso per qualunque nick."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1235,7 +1236,7 @@ msgstr ""
"configurazione\n"
"dei livelli per qualsiasi canale."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1252,7 +1253,22 @@ msgstr ""
"scadenza\n"
"automatica dei ban."
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+" \n"
+"I comandi %s sono limitati ai founders\n"
+"(a meno che SECUREOPS non sia disabilitato). Qualsiasi utente\n"
+"presente nella lista VOP o superiore puo usare il comando %s LIST.\n"
+" \n"
+
+#: modules/commands/cs_xop.cpp:546
#, c-format
msgid ""
" \n"
@@ -1293,7 +1309,7 @@ msgstr ""
" \n"
"Il comando %s CLEAR svuota la lista %s"
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1336,7 +1352,7 @@ msgstr ""
"Il comando AKICK CLEAR svuota la lista AutoKick.\n"
" "
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
msgid ""
" \n"
"The AKILL DEL command removes the given mask from the\n"
@@ -1378,7 +1394,7 @@ msgstr ""
" \n"
"AKILL CLEAR svuota la lista AKILL."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
msgid ""
" \n"
"The SNLINE DEL command removes the given mask from the\n"
@@ -1420,7 +1436,7 @@ msgstr ""
" \n"
"SNLINE CLEAR svuota la lista SNLINE."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1463,12 +1479,11 @@ msgstr ""
"SQLINE CLEAR svuota la lista SQLINE."
#: modules/commands/bs_assign.cpp:197
-#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
" \n"
"Questa opzione fa in modo che non sia possibile\n"
@@ -1476,7 +1491,7 @@ msgstr ""
"Se un bot è già assegnato, verrà rimosso\n"
"nel momento in cui viene attivata l'opzione."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
msgid ""
" \n"
"This option prevents a bot from being assigned to a\n"
@@ -1497,7 +1512,7 @@ msgstr ""
"Digita %s%s HELP comando per maggiori informazioni\n"
"sull'uso dei comandi sopraelencati."
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr " %s è online usando questo oper block."
@@ -1512,7 +1527,7 @@ msgstr " Il comando %s su %s è linkato a %s"
msgid " Providing service: %s"
msgstr " Servizio fornito: %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr " Questo oper è configurato nel file di configurazione."
@@ -1526,7 +1541,7 @@ msgstr " Caricato il: %p"
msgid " but %s mysteriously dematerialized."
msgstr " ma %s si è misteriosamente smaterializzato."
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1536,7 +1551,7 @@ msgstr "\"/msg %s\" non è più supportato. Usa \"/msg %s@%s\" o \"/%s\"."
msgid "\"Jupiter\" a server"
msgstr "Disabilita (\"jupiter\") un server"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1555,17 +1570,17 @@ msgstr "%b %d %H:%M:%S %Y %Z"
msgid "%c is an unknown status mode."
msgstr "%c è un modo sconosciuto."
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c non è bloccato su %s."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s è stato sbloccato da %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "%d records della lista di %s sono stati clonati su %s."
@@ -1590,8 +1605,8 @@ msgstr "%d nickname nel gruppo."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr "%lu nicks sono memorizzati nel database, memoria in uso: %.2Lf kB."
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, c-format
msgid "%s %s list is empty."
msgstr "La lista %2$s di %1$s è vuota."
@@ -1686,9 +1701,9 @@ msgstr "%s (%s) è stato visto l' ultima volta uscire da IRC (%s) %s fa (%s)."
msgid "%s (minimum %d/%d%%)"
msgstr "%s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "La lista di accesso di %s è vuota."
@@ -1698,7 +1713,7 @@ msgstr "La lista di accesso di %s è vuota."
msgid "%s added to %s's auto join list."
msgstr "%s aggiunto alla lista auto join di %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s già esistente."
@@ -1709,7 +1724,7 @@ msgstr "%s già esistente."
msgid "%s autokick list is empty."
msgstr "La lista autokick di %s è vuota."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "La lista delle bad words di %s è vuota."
@@ -1719,8 +1734,8 @@ msgstr "La lista delle bad words di %s è vuota."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s non può essere il successore del canale %s perché ne è il founder."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Comandi di %s:"
@@ -1820,7 +1835,7 @@ msgstr "%s è online in questo momento."
msgid "%s is a network service."
msgstr "%s è un network service."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s è già coperto da %s."
@@ -1835,7 +1850,7 @@ msgstr "%s è già presente nella lista auto join di %s."
msgid "%s is an unconfirmed nickname."
msgstr "%s è un nickname non confermato."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -1861,7 +1876,7 @@ msgstr "%s è disattivato"
msgid "%s is enabled"
msgstr "%s è attivato"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, c-format
msgid "%s is not a valid IP address."
msgstr "%s non è un indirizzo IP valido."
@@ -1907,7 +1922,7 @@ msgstr "%s è nel canale adesso (%s)"
msgid "%s is on the channel right now!"
msgstr "%s è nel canale adesso!"
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, c-format
msgid "%s list for %s"
msgstr "%s lista per %s"
@@ -1917,7 +1932,7 @@ msgstr "%s lista per %s"
msgid "%s list is empty."
msgstr "La lista %s è vuota."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, c-format
msgid "%s locked on %s."
msgstr "%s bloccato su %s."
@@ -1970,7 +1985,7 @@ msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr ""
"%s ti informerà dei nuovi memo quando ti connetti e quando torni dall'/AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) aggiunto alla lista dei bot."
@@ -2024,11 +2039,11 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
msgid "(disabled)"
msgstr "(disattivato)"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2092,7 +2107,7 @@ msgstr ". %s è online in questo momento."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2105,13 +2120,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Un memo di massa è stato inviato a tutti gli utenti registrati."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2148,7 +2163,7 @@ msgstr "ADD target info"
msgid "ADD text"
msgstr "ADD text"
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
msgid "ADD [+expiry] mask limit reason"
msgstr "ADD [+expiry] mask limit reason"
@@ -2164,11 +2179,11 @@ msgstr "ADD [nickname] mask"
msgid "ADD [nickname] [fingerprint]"
msgstr "ADD [nickname] [fingerprint]"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+expiry] mask reason"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+expiry] mask:reason"
@@ -2176,15 +2191,15 @@ msgstr "ADD [+expiry] mask:reason"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr "ADDIP server.name ip"
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr "ADDSERVER server.name [zone.name]"
@@ -2197,8 +2212,8 @@ msgstr "AKICK ENFORCE su %s completato, ne sono stati influenzati %d utenti.
msgid "AKILL all users on a specific channel"
msgstr "AKILL pert tutti gli utenti presenti in un canale specifico"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "La lista AKILL è vuota."
@@ -2229,18 +2244,18 @@ msgstr "Il livello di accesso deve essere compreso tra %d e %d (inclusi)."
msgid "Access level must be non-zero."
msgstr "Il livello di accesso deve essere diverso da zero."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Impostazioni dei livelli di accesso del canale %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr ""
"I livelli di accesso di %s sono stati ripristinati ai valori originali."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, c-format
msgid "Access list for %s:"
msgstr "Lista di accesso di %s:"
@@ -2254,23 +2269,15 @@ msgstr ""
"L' accesso a questo comando richiede che i permessi %s siano presenti nel "
"tuo opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Attiva le funzionalità di sicurezza"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -2295,7 +2302,7 @@ msgstr ""
"agli operatori quando viene usato il comando INFO per un nick\n"
".o per un canale."
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr "Aggiunto IP %s a %s."
@@ -2332,13 +2339,7 @@ msgstr "Aggiunto il server %s."
msgid "Added zone %s."
msgstr "Aggiunta la zona %s."
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2363,7 +2364,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Tutte le O:lines di %s sono state ripristinate."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Tutte le voci akick impostate su %s sono state clonate su %s"
@@ -2373,16 +2374,11 @@ msgstr "Tutte le voci akick impostate su %s sono state clonate su %s"
msgid "All available commands for %s:"
msgstr "Tutti i comandi disponibili per %s:"
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Tutte le voci badword impostate su %s sono state clonate su %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Tutte le voci akick impostate su %s sono state clonate su %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Tutte le Logon News sono state eliminate."
@@ -2392,12 +2388,12 @@ msgstr "Tutte le Logon News sono state eliminate."
msgid "All memos for channel %s have been deleted."
msgstr "Tutti i memo per il canale %s sono stati cancellati."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2422,7 +2418,7 @@ msgstr "Tutte le O:lines di %s sono state rimosse."
msgid "All random news items deleted."
msgstr "Tutte le Random News sono state eliminate."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Tutte le impostazioni di %s sono state clonate su %s."
@@ -2433,13 +2429,13 @@ msgid "All user modes on %s have been synced."
msgstr "Tutti gli user modes su %s sono stati sincronizzati."
#: modules/commands/hs_group.cpp:60
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Tutti i vhost nel gruppo %s sono stati impostati a %s"
#: modules/commands/hs_group.cpp:58
-#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+#, c-format
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Tutti i vhost nel gruppo %s sono stati impostati a %s@%s"
#: src/access.cpp:41
@@ -2564,7 +2560,7 @@ msgstr ""
"Permette agli Amministratori di inviare un messaggio a tutti\n"
"gli utenti della rete. Il messaggio sarà inviato dal nick %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
msgid ""
"Allows Services Operators to change modes for any channel.\n"
"Parameters are the same as for the standard /MODE command.\n"
@@ -2578,7 +2574,7 @@ msgstr ""
"Se viene usato CLEAR ALL, tutti i modi, compresi lo stato degli utenti, "
"vengono rimossi."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
msgid ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
@@ -2586,8 +2582,7 @@ msgstr ""
"Permette ai Services Operator di impostare modi per qualsiasi user.\n"
"I parametri sono gli stessi utilizzati con il comando /MODE standard."
-#: modules/commands/bs_bot.cpp:352
-#, fuzzy
+#: modules/commands/bs_bot.cpp:336
msgid ""
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
@@ -2597,13 +2592,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2666,7 +2661,7 @@ msgstr ""
"\n"
"Gli Ignore non saranno forzati sugli IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
"a user matching an AKILL mask attempts to connect, Services\n"
@@ -2707,7 +2702,7 @@ msgstr ""
"anche se è la stessa di default. La durata di default per le\n"
"AKILL può essere trovata con il comando STATS AKILL."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2719,17 +2714,14 @@ msgstr ""
"connettersi, i Services non gli permetteranno di proseguire\n"
"la sua session IRC."
-#: modules/commands/os_sxline.cpp:670
-#, fuzzy
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
"Permette ai Services Operators di manipolare la lista delle SQLINE. Se\n"
"un utente con un nick corrispondente una mask in SQLINE prova a\n"
@@ -2738,7 +2730,7 @@ msgstr ""
"Se il primo carattere della mask è #, i services\n"
"impediranno l' uso dei canali corrispondenti."
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2792,8 +2784,7 @@ msgstr ""
"sulla limitazione delle sessioni e come configurare limiti specifici\n"
"per determinati host o gruppi di host."
-#: modules/commands/cs_topic.cpp:193
-#, fuzzy
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -2801,9 +2792,8 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
"Permette la modifica del topic del canale specificato.\n"
"Il comando SET cambia il topic del canale al topic specificato\n"
@@ -2815,7 +2805,7 @@ msgstr ""
"Quando il blocco del topic è impostato, il topic del canale non è "
"modificabilese non tramite questo comando."
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -2844,7 +2834,7 @@ msgstr ""
" \n"
"Opzioni disponibili:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2875,7 +2865,7 @@ msgstr ""
"Esempio:\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2885,7 +2875,7 @@ msgstr ""
"con il nick fornito. Se MSG è attivo, i Services usano i messaggi (query),\n"
"altrimenti usano i notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2896,7 +2886,7 @@ msgstr ""
"con te. Se %s è attivo, i Services usano i messaggi (query),\n"
"altrimenti usano i notices."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -2978,7 +2968,7 @@ msgstr ""
"relative alla data di creazione e al numero di canali\n"
"a cui è assegnato."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
@@ -2986,7 +2976,7 @@ msgstr ""
"Sono disponibili metodi alternativi per la modifica delle\n"
"liste di accesso dei canali. "
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
msgid "Approve the requested vHost of a user"
msgstr "Approva il vHost richiesto di un utente"
@@ -2994,14 +2984,9 @@ msgstr "Approva il vHost richiesto di un utente"
msgid "As a Services Operator, you may drop any nick."
msgstr "La deregistrazione di qualsiasi nick è limitata ai Services Operator."
-#: modules/commands/bs_assign.cpp:19
-msgid "Assigns a bot to a channel"
-msgstr "Assegna un bot a un canale"
-
#: modules/commands/bs_assign.cpp:78
-#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3009,15 +2994,19 @@ msgstr ""
"indicato. Dopo averlo assegnato, il bot può essere\n"
"configurato in base alle necessità."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+msgid "Assigns a bot to a channel"
+msgstr "Assegna un bot a un canale"
+
+#: data/chanserv.example.conf:1186
msgid "Associate a URL with the channel"
msgstr "Associa un URL al canale"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr "Associa un URL con questo account"
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
msgid "Associate a URL with your account"
msgstr "Associa un URL con il tuo account"
@@ -3025,11 +3014,11 @@ msgstr "Associa un URL con il tuo account"
msgid "Associate a greet message with your nickname"
msgstr "Associa un messaggio di saluto al tuo nickname"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
msgid "Associate an E-mail address with the channel"
msgstr "Associa un indirizzo e-mail al canale"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
msgid "Associate an E-mail address with your nickname"
msgstr "Associa un indirizzo e-mail al tuo nick"
@@ -3037,11 +3026,11 @@ msgstr "Associa un indirizzo e-mail al tuo nick"
msgid "Associate oper info with a nick or channel"
msgstr "Associa oper info a un nick o un canale"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
msgid "Associates the given E-mail address with the nickname."
msgstr "Associa un indirizzo e-mail al nickname"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3051,7 +3040,7 @@ msgstr ""
"Questo indirizzo sarà mostrato quando qualcuno richiede\n"
"informazioni sul proprio nick con il comando INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3080,19 +3069,12 @@ msgstr "Stato di protect automatico al momento del join"
msgid "Automatic voice on join"
msgstr "Stato di voice automatico al momento del join"
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, c-format
msgid "Available commands for %s:"
msgstr "Comandi disponibili per %s:"
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr ""
-" \n"
-"I comandi disponibili sono:"
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr "Privilegi disponibili per %s:"
@@ -3106,20 +3088,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr "Kick in caso di bad words"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, c-format
msgid "Bad words list for %s:"
msgstr "Lista bad words per %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "La lista delle bad words è stata svuotata."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr "La scadenza dei ban non può essere superiore a 1 giorno."
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, c-format
msgid "Ban on %s expires in %s."
msgstr "Il ban su %s scadrà in %s."
@@ -3137,7 +3119,7 @@ msgstr "Il tipo di ban del canale %s ora è #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Imposta un ban su un nick o una mask nel canale"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3164,7 +3146,7 @@ msgstr "Bans forzati su %s."
msgid "Bolds kicker"
msgstr "Kick in caso di grassetto"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Il bot %s è già esistente."
@@ -3179,12 +3161,12 @@ msgstr "Il bot %s non esiste."
msgid "Bot %s has been assigned to %s."
msgstr "Il bot %s è stato assegnato a %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Il bot %s è stato modificato, ora si presenta come %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Il bot %s è stato eliminato."
@@ -3214,40 +3196,40 @@ msgstr "Il bot non kickerà gli operatori sul canale %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Il bot non kickerà i voice sul canale %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, c-format
msgid "Bot %s is not changeable."
msgstr "Il bot %s non è modificabile."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, c-format
msgid "Bot %s is not deletable."
msgstr "Il bot %s non è eliminabile."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr "I ban del bot scadranno automaticamente dopo %s."
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
msgid "Bot bans will no longer automatically expire."
msgstr "I ban del bot non scadranno automaticamente."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Gli host dei Bot possono contenere solamente %d caratteri."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
msgid "Bot hosts may only contain valid host characters."
msgstr "Gli host dei bot possono contenere unicamente caratteri validi."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Le ident dei Bot possono contenere solamente %d caratteri."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
msgid "Bot idents may only contain valid ident characters."
msgstr "Le ident dei bot possono contenere unicamente caratteri validi."
@@ -3264,12 +3246,12 @@ msgstr "Lista dei bot disponibili:"
msgid "Bot nick"
msgstr "Bot nick"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "I nick dei Bot possono contenere solamente %d caratteri."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
msgid "Bot nicks may only contain valid nick characters."
msgstr "I nick dei bot possono contenere unicamente caratteri validi."
@@ -3358,8 +3340,8 @@ msgstr "Il bot non kickerà più chi flooda."
msgid "Bot won't kick for repeats anymore."
msgstr "Il bot non kickerà più chi ripete."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3392,12 +3374,12 @@ msgstr ""
"sempre che non sia già stato letto prima dell'uso di questo\n"
"comando."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Non puoi clonare il canale %s su se stesso!"
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Impossibile inviare e-mail adesso, riprova più tardi."
@@ -3464,20 +3446,20 @@ msgstr ""
msgid "Change channel modes"
msgstr "Cambia i modi del canale."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
msgid "Change the communication method of Services"
msgstr "Cambia il metodo di comunicazione usato dai Services"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
msgid "Change user modes"
msgstr "Cambia i modi utente."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Modi utente di %s modificati in %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3485,7 +3467,7 @@ msgstr ""
"Imposta il nome con cui i Services fanno riferimento al tuo\n"
"gruppo. Il nuovo nome DEVE essere un nick del gruppo."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3501,7 +3483,7 @@ msgstr ""
"Imposta il nuovo founder del canale. Il nick specificato\n"
"deve essere registrato."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3514,7 +3496,7 @@ msgstr ""
"La lingua può essere scelta dalla seguente lista di\n"
"lingue supportate:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3527,13 +3509,13 @@ msgstr ""
"La lingua può essere scelta dalla seguente lista di\n"
"lingue supportate:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
"Cambia la password utilizzata per identificarti come\n"
"proprietario del nick."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3553,7 +3535,7 @@ msgstr ""
"è ancora registrato, il successore diventerà il nuovo\n"
"founder del canale. Il nick specificato deve essere registrato."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
msgid "Channel"
msgstr "Canale"
@@ -3632,12 +3614,12 @@ msgstr "Il canale %s scadrà."
msgid "Channel %s will not expire."
msgstr "Il canale %s non scadrà."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, c-format
msgid "Channel %s %s list has been cleared."
msgstr "La lista %2$s del canale %1$s è stata svuotata."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "La lista di accesso del canale %s è stata svuotata."
@@ -3647,7 +3629,7 @@ msgstr "La lista di accesso del canale %s è stata svuotata."
msgid "Channel %s akick list has been cleared."
msgstr "La lista autokick del canale %s è stata svuotata."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Il canale %s non ha modi bloccati."
@@ -3671,8 +3653,8 @@ msgstr "Lista Canali:"
msgid "Channel stats for %s on %s:"
msgstr "Statistiche del canale per %s su %s:"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
msgid "Channels may not be on access lists."
msgstr "I canali possono non essere nelle liste di accesso"
@@ -3732,10 +3714,9 @@ msgid "Checks if last memo to a nick was read"
msgstr "Controlla se l'ultimo memo inviato ad un nick è stato letto"
#: modules/commands/ms_check.cpp:69
-#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Controlla se l'_ultimo_ memo che hai inviato al nick è stato letto\n"
"oppure no. Nota che questo funziona unicamente coi nick, non coi canali."
@@ -3816,7 +3797,7 @@ msgstr "Configura i kick in caso di repeat"
msgid "Configures reverses kicker"
msgstr "Configura i kick in caso di reverse"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
msgid "Configures the time bot bans expire in"
msgstr "Imposta il tempo di scadenza dei ban impostati dal bot"
@@ -3828,7 +3809,7 @@ msgstr "Configura i kick in caso di underline"
msgid "Confirm a passcode"
msgstr "Conferma un codice di attivazione (passcode) di nickserv"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
msgid "Control modes and mode locks on a channel"
msgstr "Controlla i modi e il blocco dei modi di un canale"
@@ -3839,12 +3820,11 @@ msgstr ""
"Controlla il messaggio che sarà inviato agli utenti quando accedono al "
"canale."
-#: modules/commands/cs_clone.cpp:241
-#, fuzzy
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Copia tutte le impostazioni, accessi, akick, etc da un canale\n"
@@ -3853,37 +3833,37 @@ msgstr ""
"E' necessario essere founder di entrambi i canali per usare\n"
"questo comando."
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
msgid "Copy all settings from one channel to another"
msgstr "Copia tutte le impostazioni da un canale ad un altro"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
msgid "Created"
msgstr "Creato"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
msgid "Creator"
msgstr "Autore"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Lista %s attuale:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
msgid "Current AKILL list:"
msgstr "Lista AKILL attuale:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Lista delle eccezioni attuale:"
@@ -3931,12 +3911,12 @@ msgstr "DEL [nickname] fingerprint"
msgid "DEL [nickname] mask"
msgstr "DEL [nickname] mask"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {mask | entry-num | list | id}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
msgid "DEL {mask | entry-num | list}"
msgstr "DEL {mask | entry-num | list}"
@@ -3952,19 +3932,19 @@ msgstr "DEL {num | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr "DELIP server.name ip"
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr "DELSERVER server.name [zone.name]"
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr "DELZONE zone.name"
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
msgid "DEPOOL server.name"
msgstr "DEPOOL server.name"
@@ -3977,7 +3957,7 @@ msgstr "Database cleared, removed %lu nicks that were added after %s."
msgid "Date/Time"
msgstr "Date/Time"
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4102,16 +4082,20 @@ msgstr "Definisce i messaggi da mostrare agli operatori"
msgid "Delete a memo or memos"
msgstr "Cancella uno o più memo"
+#: modules/commands/hs_del.cpp:59
+msgid "Delete the vhost for all nicks in a group"
+msgstr "Rimuove il vhost da tutti i nick di un gruppo"
+
#: modules/commands/hs_del.cpp:19
msgid "Delete the vhost of another user"
msgstr "Rimuove il vhost di un altro utente"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Eliminati %1$d record dalla lista %3$s di %2$s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Eliminati %d record dalla lista di accesso di %s."
@@ -4121,7 +4105,7 @@ msgstr "Eliminati %d record dalla lista di accesso di %s."
msgid "Deleted %d entries from %s autokick list."
msgstr "Eliminati %d record dalla lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Eliminati %d record dalla lista delle bad words di %s."
@@ -4141,7 +4125,7 @@ msgstr "Eliminati %d record dalla lista %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "Eliminati %d record dalla lista AKILL."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "Eliminato un record dalla lista di accesso di %s."
@@ -4151,7 +4135,7 @@ msgstr "Eliminato un record dalla lista di accesso di %s."
msgid "Deleted 1 entry from %s autokick list."
msgstr "Eliminato un record dalla lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Eliminato un record dalla lista delle bad words di %s."
@@ -4174,7 +4158,7 @@ msgstr "Eliminato 1 record dalla lista AKILL."
msgid "Deleted info from %s."
msgstr "Eliminata nformazione da %s."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Eliminato un record dalla lista %2$s di %1$s."
@@ -4218,11 +4202,6 @@ msgid ""
"database."
msgstr "Elimina dal database il vhost assegnato al nick specificato."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr "Rimuove il vhost da tutti i nick di un gruppo"
-
#: modules/commands/hs_del.cpp:93
msgid ""
"Deletes the vhost for all nicks in the same group as\n"
@@ -4231,13 +4210,13 @@ msgstr ""
"Rimuove il vhost da tutti i nick dello stesso gruppo del nick\n"
"specificato."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
msgid "Description"
msgstr "Descrizione"
@@ -4251,7 +4230,7 @@ msgstr "La descrizione di %s è stata impostata a %s."
msgid "Description of %s unset."
msgstr "La descrizione di %s è stata rimossa."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
msgid "Disabled"
msgstr "Disattivato"
@@ -4275,7 +4254,7 @@ msgstr ""
" \n"
"Il motivo potrebbe essere richiesto su alcune reti."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, c-format
msgid "Displayed %d records (%d total)."
msgstr "Visualizzati %d records (totali: %d)"
@@ -4391,12 +4370,12 @@ msgstr ""
"i canali di cui sei founder. Qualsiasi altro utente avrà la\n"
"possibilità di avere il controllo di questo nick."
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "Indirizzo e-mail per %s cambiato in %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "Indirizzo e-mail per %s rimosso."
@@ -4453,8 +4432,8 @@ msgid "Email address"
msgstr "Indirizzo e-mail"
#: modules/commands/ns_getemail.cpp:41
-#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+#, c-format
+msgid "Email matched: %s to %s."
msgstr "Email corrispondondenti: %s a %s."
#: modules/fantasy.cpp:19
@@ -4465,11 +4444,11 @@ msgstr "Abilita i comandi Fantasy"
msgid "Enable greet messages"
msgstr "Abilita il messaggio di saluto"
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr "Abilita o disabilita il mantenimento degli user mode"
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
msgid "Enabled"
msgstr "Attivato"
@@ -4496,7 +4475,7 @@ msgstr ""
"e provvederanno a reimpostatarli la prossima volta che il canale\n"
"sarà creato."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4507,7 +4486,7 @@ msgstr ""
"usermodes dell' utente, e provvederanno a reimpostarli la prossima\n"
"volta che si autenticherà."
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4534,7 +4513,7 @@ msgstr ""
"avranno l'accesso sul canale secondo le liste di accesso."
#: modules/commands/cs_set.cpp:944
-#, fuzzy
+#, fuzzy, c-format
msgid ""
"Enables or disables signed kicks for a\n"
"channel. When SIGNKICK is set, kicks issued with\n"
@@ -4598,11 +4577,10 @@ msgstr ""
"il comando access/qop."
#: modules/commands/cs_set.cpp:872
-#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Attiva o disattiva l'opzione secure ops per il canale.\n"
"Quando l'opzione è attiva, gli utenti che non sono nella\n"
@@ -4625,7 +4603,7 @@ msgstr ""
"sarà creato."
#: modules/commands/cs_set.cpp:603
-#, fuzzy, c-format
+#, c-format
msgid ""
"Enables or disables the persistent channel setting.\n"
"When persistent is set, the service bot will remain\n"
@@ -4643,7 +4621,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -4667,20 +4645,20 @@ msgstr ""
"Inoltre, i services imposteranno o rimuoveranno il modo quando\n"
"persist viene abilitato o disabilitato."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
msgid "End of AKILL list."
msgstr "Fine della lista AKILL."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
msgid "End of access list"
msgstr "Fine della lista di accesso."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Fine della lista di accesso - %d/%d risultati mostrati."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Fine della lista di accesso."
@@ -4688,7 +4666,7 @@ msgstr "Fine della lista di accesso."
msgid "End of autokick list"
msgstr "Fine della lista auto kick."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
msgid "End of bad words list."
msgstr "Fine della lista bad words."
@@ -4718,7 +4696,7 @@ msgstr "Fine della lista forbid."
msgid "End of list - %d channels shown."
msgstr "Fine della lista - %d canali mostrati."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Fine della lista - %d/%d risultati mostrati."
@@ -4767,8 +4745,8 @@ msgstr ""
"a quando il numero degli stessi non scende al di sotto del limite canale,\n"
"se un limite è impostato"
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Italiano"
@@ -4825,17 +4803,16 @@ msgstr ""
"Errore! Il vHost è troppo lungo, usa un hostname più corto di %d caratteri."
#: modules/commands/ns_cert.cpp:325
-#, fuzzy
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
@@ -4854,31 +4831,36 @@ msgstr ""
" CERT LIST\n"
" Visualizza la lista dei certificati attuale."
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "L'eccezione per %s (numero %d) è stata spostata alla posizione %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception per %s è stata aggiornata in %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
msgid "Expires"
msgstr "Scadenza"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Scadenza e reason aggiornati per %s."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "Scadenza per %s modificata."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasia"
@@ -4906,16 +4888,16 @@ msgstr "La firma digitale %s è già presente nella lista dei certificati di %s
msgid "Fingerprint %s is already in use."
msgstr "La firma digitale %s è già in uso."
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Flags per %s su %s impostate a +%s"
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, c-format
msgid "Flags list for %s"
msgstr "Lista flags di %s"
@@ -4992,7 +4974,7 @@ msgid "GETPASS command unavailable because encryption is in use."
msgstr ""
"Il comando GETPASS non è disponibile perché è in uso la criptazione dei dati."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "La connessione fantasma con il tuo nick è stata disconnessa."
@@ -5000,7 +4982,7 @@ msgstr "La connessione fantasma con il tuo nick è stata disconnessa."
msgid "Give Operflags to a certain user"
msgstr "Imposta le operflag di un utente"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -5009,7 +4991,7 @@ msgstr ""
"Imposta lo stato di %s al nick specificato in un canale. Se il\n"
"nick non viene specificato, lo stato di %s viene impostato su te stesso."
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr ""
@@ -5085,24 +5067,20 @@ msgstr "Non conosco %s."
msgid "I've never seen %s on this channel."
msgstr "Non ho mai visto %s in questo canale."
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, c-format
msgid "IP %s already exists for %s."
msgstr "l'IP %s esiste già per %s."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, c-format
msgid "IP %s does not exist for %s."
msgstr "l'IP %s non esiste per %s."
@@ -5111,8 +5089,8 @@ msgstr "l'IP %s non esiste per %s."
msgid "Identify yourself with your password"
msgstr "Ti identifica per il tuo nick"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Se non cambi il tuo nick entro %s, verrà cambiato dal server."
@@ -5125,11 +5103,11 @@ msgstr "La lista ignore è stata cancellata."
msgid "Ignore list is empty."
msgstr "La lista ignore è vuota."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
msgid "Ignore list:"
msgstr "Lista ignore:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
msgid "Immediate protection"
msgstr "Protezione immediata"
@@ -5184,7 +5162,7 @@ msgstr ""
"E' stato inserito un codice di attivazione non valido, controlla di nuovo l' "
"email ricevuta e riprova."
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr "Codice di attivazione non valido."
@@ -5202,7 +5180,7 @@ msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr ""
"Valore di soglia non valido. Deve essere un numero intero maggiore di 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr "Valore non valido per LIMIT. Deve essere numerico."
@@ -5219,16 +5197,16 @@ msgstr "Kick in caso di italics"
msgid "Join a group"
msgstr "Entra in un gruppo"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
msgid "Keep modes"
msgstr "Mantenimento modes"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Il mantenimento dei modi per %s è stato disattivato."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Il mantenimento dei modi per %s è stato attivato."
@@ -5246,7 +5224,7 @@ msgstr "La key per il canale %s è %s."
msgid "Kick a user from a channel"
msgstr "Espelle un utente da un canale"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5255,13 +5233,12 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr "Espelle il nick specificato da un canale"
-#: modules/commands/cs_kick.cpp:128
-#, fuzzy
+#: modules/commands/cs_kick.cpp:115
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Espelle il nick specificato dal canale.\n"
" \n"
@@ -5286,17 +5263,17 @@ msgstr "LIMIT forzato su %s, %d utenti rimossi."
msgid "LIST threshold"
msgstr "LIST soglia"
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
msgid "LIST [mask | list | id]"
msgstr "LIST [mask | list | id]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
msgid "LIST [mask | list]"
msgstr "LIST [mask | list]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
msgid "LIST [nickname]"
msgstr "LIST [nickname]"
@@ -5304,15 +5281,10 @@ msgstr "LIST [nickname]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [testo|numero]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Lingua cambiata a Italiano."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Il successor del canale %s ora è %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5322,7 +5294,7 @@ msgstr "L'ultimo memo inviato a %s è stato annullato."
msgid "Last quit message"
msgstr "Ultimo messaggio di quit"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
msgid "Last seen"
msgstr "Ultimo accesso"
@@ -5330,11 +5302,11 @@ msgstr "Ultimo accesso"
msgid "Last seen address"
msgstr "Ultimo indirizzo usato"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr "Ultimo topic"
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
msgid "Last used"
msgstr "Ultimo usato"
@@ -5342,27 +5314,27 @@ msgstr "Ultimo usato"
msgid "Last usermask"
msgstr "Ultima usermask"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Il livello di %s sul canale %s è stato modificato a %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Il livello deve essere compreso tra %d e %d (inclusi)."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5376,7 +5348,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr "Mostra i canali in cui si ha accesso"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr "La lista per il modo %c è piena."
@@ -5385,7 +5357,7 @@ msgstr "La lista per il modo %c è piena."
msgid "List loaded modules"
msgstr "Elenca i moduli caricati"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, c-format
msgid "List of entries matching %s:"
msgstr "Lista delle voci corrispondenti %s:"
@@ -5626,19 +5598,17 @@ msgid "Lists currently loaded modules."
msgstr "Elenca i moduli attualmente caricati."
#: modules/commands/cs_info.cpp:19
-#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr "Mostra le informazioni su un canale registrato"
#: modules/commands/cs_info.cpp:76
-#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Mostra varie informazioni a proposito del canale\n"
"specificato (a patto che sia registrato), tra cui il\n"
@@ -5729,7 +5699,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr "Stai cercando te stesso, %s?"
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5796,11 +5770,11 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr "Modifica la lista AutoKick"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
msgid "Maintains network bot list"
msgstr "Gestisce la lista dei bot disponibili"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -5811,7 +5785,7 @@ msgstr ""
"nella lista %s ricevono i seguenti privilegi:\n"
" "
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -5840,7 +5814,7 @@ msgstr ""
"l' AKICK sarà aggiunto sull' account %s anzichè sulla mask.\n"
"Tutti i nickname presenti nel gruppo dell'account saranno in AKICK.\n"
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -5860,7 +5834,7 @@ msgstr ""
"ha livello utente 0, e qualsiasi utente non registrato\n"
"ha livello utente -1."
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -5895,7 +5869,7 @@ msgstr ""
"effettuato ogni volta che un utente scriverà la parola.\n"
" \n"
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
msgid "Maintains the bad words list"
msgstr "Gestisce la lista delle bad words"
@@ -5904,22 +5878,19 @@ msgid "Makes the bot do the equivalent of a \"/me\" command"
msgstr "Fa sì che il bot invii l'equivalente di un comando \"/me\""
#: modules/commands/bs_control.cpp:127
-#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Fa sì che il bot invii l'equivalente di un comando \"/me\"\n"
"nel canale specificato utilizzando il testo specificato."
#: modules/commands/bs_control.cpp:19
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr "Fa sì che il bot scriva il testo specificato nel canale specificato"
#: modules/commands/bs_control.cpp:69
-#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr "Fa sì che il bot scriva il testo specificato nel canale specificato."
#: modules/commands/greet.cpp:157
@@ -5946,7 +5917,7 @@ msgstr ""
"l'opzione GREET attiva, se in possesso del livello di accesso\n"
"necessario."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
msgid "Manage DNS zones for this network"
msgstr "Gestisce le zone DNS per questo network."
@@ -5962,12 +5933,12 @@ msgstr "Gestisce la lista ignore dei memo"
msgid "Manage your auto join list"
msgstr "Gestisce la tua lista auto join"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, c-format
msgid "Manipulate the %s list"
msgstr "Gestisce la lista %s"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "Gestisce la lista AKILL"
@@ -5975,19 +5946,19 @@ msgstr "Gestisce la lista AKILL"
msgid "Manipulate the DefCon system"
msgstr "Gestisce il sistema DefCon"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
msgid "Manipulate the topic of the specified channel"
msgstr "Gestisce il topic del canale specificato"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6000,8 +5971,8 @@ msgstr "La mask %s è già presente lista di accesso di %s."
msgid "Mask must be in the form user@host."
msgstr "La mask deve essere nel formato user@host."
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
msgid "Masks and unregistered users may not be on access lists."
msgstr ""
"Mask e utenti non registrati non possono essere aggiunti in una lista di "
@@ -6032,7 +6003,7 @@ msgstr "Memo %d da %s (%s)."
msgid "Memo %d has been deleted."
msgstr "Il memo %d è stato cancellato."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
msgid "Memo ignore list is empty."
msgstr "La lista ignore dei memo è vuota."
@@ -6051,7 +6022,7 @@ msgstr "Il limite dei memo di %s è stato impostato a %d."
msgid "Memo limit for %s set to 0."
msgstr "Il limite dei memo di %s è stato impostato a 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo inviato a %s."
@@ -6065,7 +6036,7 @@ msgstr "Memo per %s:"
msgid "Message"
msgstr "Messaggio"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Modalità messaggio"
@@ -6073,25 +6044,25 @@ msgstr "Modalità messaggio"
msgid "Method"
msgstr "Metodo"
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr "Parametro mancante per il modo %c."
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Il modo %s non è modo di stato o di lista."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
msgid "Mode lock"
msgstr "Modi bloccati"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, c-format
msgid "Mode locks for %s:"
msgstr "Modi bloccati per %s:"
@@ -6100,11 +6071,6 @@ msgstr "Modi bloccati per %s:"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, fuzzy, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr "%d canale(i) eliminato(i), e %d canale(i) deregistrato(i)."
-
#: modules/commands/ns_access.cpp:166
#, c-format
msgid ""
@@ -6148,11 +6114,10 @@ msgstr ""
" Visualizza la lista di accesso attuale."
#: modules/commands/ns_cert.cpp:319
-#, fuzzy
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6169,7 +6134,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr "Modifica la lista ignore dei Services"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, c-format
msgid "Modify the list of %s users"
msgstr "Modifica la lista degli utenti %s"
@@ -6178,7 +6143,7 @@ msgstr "Modifica la lista degli utenti %s"
msgid "Modify the list of authorized addresses"
msgstr "Modifica la lista degli indirizzi autorizzati"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
msgid "Modify the list of privileged users"
msgstr "Modifica la lista degli utenti con privilegi"
@@ -6186,7 +6151,7 @@ msgstr "Modifica la lista degli utenti con privilegi"
msgid "Modify the nickname client certificate list"
msgstr "Modifica la lista dei certificati del client per il nickname"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
msgid "Modify the session-limit exception list"
msgstr "Modifica la lista delle eccezioni del limite delle sessioni"
@@ -6233,14 +6198,14 @@ msgstr "Modulo: %s Versione: %s Autore: %s caricato: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Modulo: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr "Nome"
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr "Nome Tipo"
@@ -6253,18 +6218,18 @@ msgstr "Statistiche network per %s:"
msgid "Never"
msgstr "Mai"
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
msgid "Nick"
msgstr "Nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, c-format
msgid "Nick %s has been confirmed."
msgstr "Il nick %s è stato confermato."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, c-format
msgid "Nick %s is already an operator."
msgstr "Il nick %s è già un operatore."
@@ -6279,7 +6244,6 @@ msgstr "Il nick %s è già stato confermato."
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Il nick %s è un nickname non autorizzato e non può essere utilizzato."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6295,7 +6259,7 @@ msgstr "Il nick %s è stato vietato da %s: %s."
msgid "Nick %s is forbidden."
msgstr "Il nick %s è vietato."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s non è un Services Operator."
@@ -6320,12 +6284,12 @@ msgstr "il nickname %s non è registrato."
msgid "Nick %s was truncated to %d characters."
msgstr "Il nick %s è stato troncato a %d caratteri."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Il nick %s scadrà."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Il nick %s non scadrà."
@@ -6390,17 +6354,17 @@ msgstr "Il nickname %s è già registrato!"
msgid "Nickname %s may not be registered."
msgstr "Il nickname %s non può essere registrato."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Il nick %s è stato registrato sotto la tua user@host-mask: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, c-format
msgid "Nickname %s registered."
msgstr "Nickname %s registrato."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
msgid "No auto-op"
msgstr "No auto-op"
@@ -6408,7 +6372,7 @@ msgstr "No auto-op"
msgid "No bot"
msgstr "Nessun bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
msgid "No expire"
msgstr "Nessuna scadenza"
@@ -6436,13 +6400,13 @@ msgstr "Nessuna Logon News da eliminare!"
msgid "No matches for %s found."
msgstr "Nessuna corrispondenza trovata per %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, c-format
msgid "No matching entries on %s %s list."
msgstr "Nessun record corrispondente nella lista %2$s di %1$s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Nessun record corrispondente nella lista di accesso di %s."
@@ -6452,21 +6416,21 @@ msgstr "Nessun record corrispondente nella lista di accesso di %s."
msgid "No matching entries on %s autokick list."
msgstr "Nessun record corrispondente nella lista autokick di %s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Nessun record corrispondente nella lista delle bad words di %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "Nessun record corrispondente nella lista delle eccezioni."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, c-format
msgid "No matching entries on the %s list."
msgstr "Nessun record corrispondente nella lista %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Nessun record corrispondente nella lista AKILL."
@@ -6478,7 +6442,12 @@ msgstr "Nessun memo è annullabile."
msgid "No modules currently loaded matching that criteria."
msgstr "Nessn modulo attualmente caricato corrisponde quei criteri."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, c-format
+msgid "No nick registrations matching %s found."
+msgstr "Nessuna registrazione corrispondente %s è stata trovata."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
"Nessuno sta usando il tuo nick, e attualmente non è trattenuto dai service."
@@ -6499,12 +6468,7 @@ msgstr "Nessuna Random News da eliminare!"
msgid "No records to display."
msgstr "Nessun risultato da mostrare."
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "Nessuna registrazione corrispondente %s è stata trovata."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr "Nessuna richista trovata per il nick %s."
@@ -6513,8 +6477,8 @@ msgstr "Nessuna richista trovata per il nick %s."
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr "No kick firmati quanto è usato SIGNKICK LEVEL"
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, c-format
msgid "No stats for %s."
msgstr "Non ci sono stats per %s:"
@@ -6524,7 +6488,7 @@ msgstr "Non ci sono stats per %s:"
msgid "No such info \"%s\" on %s."
msgstr "Nessuna informazione \"%s\" su %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, c-format
msgid "No users on %s match %s."
msgstr "Nessun user su %s corrisponde a %s."
@@ -6539,7 +6503,7 @@ msgstr "La modalità No Bot ora è non attiva nel canale %s."
msgid "No-bot mode is now on on channel %s."
msgstr "La modalità No Bot ora è attiva nel canale %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr "Non-status modes elimiti su %s."
@@ -6548,21 +6512,21 @@ msgstr "Non-status modes elimiti su %s."
msgid "None"
msgstr "Nessuna"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr "Niente da eseguire."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr "Numero"
@@ -6570,17 +6534,14 @@ msgstr "Numero"
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [testo|numero]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Le vecchie informazioni sono identiche a quelle nuove."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
msgid "Online from"
msgstr "Connesso da"
-#: modules/commands/os_oper.cpp:139
-#, fuzzy, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr " Questo oper è configurato nel file di configurazione."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr "Informazioni Operatore"
@@ -6604,12 +6565,12 @@ msgstr "Impossibile trovare la Oper News #%s!"
msgid "Oper news items:"
msgstr "Lista delle Oper News:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr "Privilegi di operatore rimossi da %s (%s)."
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, c-format
msgid "Oper type %s has not been configured."
msgstr "Il tipo di operatore %s non è stato configurato."
@@ -6624,17 +6585,17 @@ msgstr "Le operflags %s sono state aggiunte a %s."
msgid "Operflags %s have been removed from %s."
msgstr "Le operflags %s sono state rimosse a %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr "L' opertype %s non ha comandi permessi."
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr "L' opertype %s non ha privilegi permessi."
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr "L' opertype %s riceve i modi %s quando si identifica."
@@ -6647,11 +6608,11 @@ msgstr "Protezione per gli op"
msgid "Options"
msgstr "Opzioni"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
msgid "POOL server.name"
msgstr "POOL server.name"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr "Parametro"
@@ -6667,12 +6628,12 @@ msgstr "Password accettata."
msgid "Password authentication required for that command."
msgstr "Autenticazione con password richiesta per questo comando."
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, c-format
msgid "Password for %s changed to %s."
msgstr "La password di %s è stata cambiata in %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, c-format
msgid "Password for %s changed."
msgstr "La password di %s è stata cambiata."
@@ -6691,7 +6652,7 @@ msgstr "Password errata."
msgid "Password reset email for %s has been sent."
msgstr "E' stata inviata una email per il reset della password di %s."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Peace"
@@ -6705,7 +6666,7 @@ msgstr "L'opzione peace per %s è ora disattivata."
msgid "Peace option for %s is now on."
msgstr "L'opzione peace per %s è ora attiva."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
msgid "Persistent"
msgstr "Persistant"
@@ -6742,12 +6703,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Attendi %d secondi è riprova."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Attendi %d secondi prima di richiedere un nuovo vHost."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Attendi %d secondi prima di usare di nuovo il comando %s."
@@ -6758,13 +6719,13 @@ msgid "Please wait %d seconds before using the GROUP command again."
msgstr ""
"Per favore attendi %d secondi prima di usare di nuovo il comando GROUP."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Per favore attendi %d secondi prima di usare di nuovo il comando REGISTER."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -6777,7 +6738,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr "Impedisce che un bot venga assegnato da un non IRC operator"
@@ -6797,7 +6758,7 @@ msgstr "Impedisce ad un canale di scadere"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Nasconde il nickname dall' output del comando LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
msgid "Prevent the nickname from expiring"
msgstr "Impedisce ad un nickname di scadere"
@@ -6805,17 +6766,17 @@ msgstr "Impedisce ad un nickname di scadere"
msgid "Prevents users being kicked by Services"
msgstr "Impedisce agli utenti di essere kickati dai Services"
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privato"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, c-format
msgid "Private mode of bot %s is now off."
msgstr "La modalità Private del bot %s ora è disattivata."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, c-format
msgid "Private mode of bot %s is now on."
msgstr "La modalità private del bot %s ora è attiva."
@@ -6840,36 +6801,36 @@ msgstr "L'opzione private è adesso disattivata per %s."
msgid "Private option is now on for %s."
msgstr "L'opzione private è adesso attiva per %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr "Il privilegio %s è stato aggiunto a %s su %s, le nuove flags sono +%s"
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Il privilegio %s è stato rimosso a %s su %s, le nuove flags sono +%s"
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Protezione"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, c-format
msgid "Protection is now off for %s."
msgstr "La protezione è adesso disattivata per %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "La protezione è adesso attiva per %s, con un ritardo ridotto."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "La protezione è adesso attiva per %s, senza ritardo."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, c-format
msgid "Protection is now on for %s."
msgstr "La protezione è adesso attiva per %s."
@@ -6884,7 +6845,7 @@ msgstr ""
"Utilizza la mask completa ident@host per ogni nick,\n"
"in seguito imposta l'AKILL. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
msgid "Quick protection"
msgstr "Protezione rapida"
@@ -6926,20 +6887,20 @@ msgstr "Legge uno o più memo"
msgid "Real name"
msgstr "Real name"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, c-format
msgid "Reason for %s updated."
msgstr "Reason per %s aggiornata."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -6955,21 +6916,21 @@ msgstr ""
"comando GHOST). Se l' utente che sta usando il tuo nick non è\n"
"identificato sarà forzato a cambiarlo dai services."
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
msgid "Redefine the meanings of access levels"
msgstr "Ridefinisce i privilegi dei livelli di accesso"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
msgid "Regains control of your nick"
msgstr "Permette di riottenere il controllo del proprio nick"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
msgid "Regex is disabled."
msgstr "Le espressioni regolari sono disabilitate."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6978,9 +6939,9 @@ msgstr ""
"E' supportato l' uso di espressioni regolari utilizzando il motore %s.\n"
"Se vuoi puoi includere la mask tra //."
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6993,11 +6954,11 @@ msgstr ""
msgid "Register a channel"
msgstr "Registra un canale"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
msgid "Register a nickname"
msgstr "Registra un nickname"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
msgid "Registered"
msgstr "Registrato"
@@ -7047,7 +7008,7 @@ msgstr ""
"impostazioni del canale e riceverà automaticamente da %s\n"
"i privilegi di operatore del canale quando vi accede."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7089,7 +7050,7 @@ msgstr ""
"di almeno 5 caratteri. Infine, gli spazi non possono essere \n"
"usati all'interno di una password."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
msgid "Registration is currently disabled."
msgstr "Spiacente, la registrazione è temporaneamente disabilitata."
@@ -7097,11 +7058,11 @@ msgstr "Spiacente, la registrazione è temporaneamente disabilitata."
msgid "Regulate the use of critical commands"
msgstr "Regola l'uso dei comandi critici"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
msgid "Reject the requested vHost for the given nick."
msgstr "Rifiuta il vHost richisto per il nick specificato."
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
msgid "Reject the requested vHost of a user"
msgstr "Rifiuta il vHost richisto di un utente"
@@ -7138,22 +7099,22 @@ msgstr ""
msgid "Remove all operators from a server remotely"
msgstr "Rimuove temporaneamente tutti gli operatori di un server"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, c-format
msgid "Removed IP %s from %s."
msgstr "IP %s rimosso da %s."
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr "Server %s rimosso dalla zona %s."
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr "Server %s rimosso."
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7162,20 +7123,19 @@ msgstr ""
"Rimuove lo stato di %s al nick specificato in un canale. Se il nick\n"
"non viene specificato, lo stato di %s sarà rimosso a te stesso."
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Rimuove lo stato di %s al nick specificato o a te stesso in un canale."
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
msgid "Removes a selected nicks status from a channel"
msgstr "Rimuove lo stato di un nick specificato in un canale"
-#: modules/commands/cs_updown.cpp:223
-#, fuzzy
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
"Rimuove lo stato di un nick specificato in un canale. Se il nick\n"
@@ -7183,7 +7143,7 @@ msgstr ""
"canale non viene specificato, lo stato viene rimosso su tutti i canali\n"
"in cui ti trovi."
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr "%s rimosso perchè già coperto da %s."
@@ -7197,10 +7157,9 @@ msgstr "Kick in caso di repeat"
msgid "Request a vHost for your nick"
msgstr "Richiede un vHost per il tuo nick"
-#: modules/commands/hs_request.cpp:180
-#, fuzzy
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
@@ -7208,7 +7167,7 @@ msgstr ""
"da un amministratore della rete. Nel frattempo, rimani in attesa\n"
"che la tua richiesta sia presa in considerazione."
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
msgid "Resend registration confirmation email"
msgstr "Reinvia l' email di conferma per la registrazione"
@@ -7216,7 +7175,7 @@ msgstr "Reinvia l' email di conferma per la registrazione"
msgid "Restrict access to the channel"
msgstr "Limita l'accesso al canale"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
msgid "Restricted access"
msgstr "Acesso limitato"
@@ -7247,7 +7206,7 @@ msgstr "Mantiene il topic quando il canale non è in uso"
msgid "Retrieve the password for a nickname"
msgstr "Recupera la password di un nickname"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr "Recupera le richieste di vhost"
@@ -7260,9 +7219,16 @@ msgid "Returns the key of the given channel."
msgstr "Recupera la password (+k) del canale specificato."
#: modules/commands/ns_getemail.cpp:58
-#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr "Recupera la password (+k) del canale specificato."
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Mostra i nick che utilizzano l' indirizzo email specificato.\n"
+"Non è possibile usare wildcards. L' uso di questo comando viene\n"
+"loggato dai services, nel log sarà incluso l' utente che ha eseguito\n"
+"il comando e l' indirizzo email che è stato specificato."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7331,18 +7297,18 @@ msgstr "Deidentifica dal proprio nick"
msgid "SET server"
msgstr "SET server"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr "SET server.name option value"
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr ""
"Firma digitale del certificato SSL accettata - adesso sei identificato come"
" %s."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr ""
"Firma digitale del certificato SSL accettata - adesso sei riconosciuto."
@@ -7364,7 +7330,7 @@ msgstr "Salva i database e riavvia i Services"
msgid "Searches logs for a matching pattern"
msgstr "Cerca nei log per la chiave specificata corrispondente"
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
msgid "Secure founder"
msgstr "Secure Founder"
@@ -7378,7 +7344,7 @@ msgstr "L'opzione Secure founder per %s è ora disattivata."
msgid "Secure founder option for %s is now on."
msgstr "L'opzione Secure founder per %s è ora attiva."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
msgid "Secure ops"
msgstr "Secure ops"
@@ -7402,12 +7368,12 @@ msgstr "L'opzione Secure per %s è ora disattivata."
msgid "Secure option for %s is now on."
msgstr "L'opzione Secure per %s è ora attiva."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, c-format
msgid "Secure option is now off for %s."
msgstr "Opzione secure disattivata per %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, c-format
msgid "Secure option is now on for %s."
msgstr "Opzione secure attiva per %s."
@@ -7417,11 +7383,11 @@ msgstr "Opzione secure attiva per %s."
msgid "Secureops enforced on %s."
msgstr "Secureops forzato su %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Sicurezza"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7430,7 +7396,7 @@ msgstr ""
"Digita %s%s HELP %s per ottenere maggiori\n"
"informazioni sulla lista di accesso."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7483,7 +7449,7 @@ msgstr "Invia un memo contenente testo-memo a tutti gli utenti registrati."
msgid "Sends all services staff a memo containing memo-text."
msgstr "Invia un memo contenente testo-memo a tutto lo staff dei services."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
msgid ""
"Sends the named nick or channel a memo containing\n"
"memo-text. When sending to a nickname, the recipient will\n"
@@ -7550,14 +7516,14 @@ msgid "Server %s already exists."
msgstr "Il server %s è già esistente."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, c-format
msgid "Server %s does not exist."
msgstr "Il server %s non esiste."
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, c-format
msgid "Server %s has no configured IPs."
msgstr "Il server %s non ha IP configurati."
@@ -7567,12 +7533,12 @@ msgstr "Il server %s non ha IP configurati."
msgid "Server %s is already in zone %s."
msgstr "Il server %s è già presente nella zona %s."
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, c-format
msgid "Server %s is already pooled."
msgstr "Il server %s è già in pool."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, c-format
msgid "Server %s is not currently linked."
msgstr "Il server %s non è attualmente linkato."
@@ -7587,12 +7553,12 @@ msgstr "Il server %s non è presente nella zona %s."
msgid "Server %s is not linked to the network."
msgstr "Il server %s non è linkato al network."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, c-format
msgid "Server %s is not pooled."
msgstr "Il server %s non è in pool."
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr "Il server %s deve essere chiuso prima di essere eliminato."
@@ -7610,19 +7576,18 @@ msgstr "Servers trovati: %d"
msgid "Service"
msgstr "Service"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, c-format
msgid "Service's hold on %s has been released."
msgstr "Il blocco dei servizi sul nick %s è stato rilasciato."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s è un services operator di tipo %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
msgid "Services are in DefCon mode, please try again later."
msgstr "I servizi sono in modalità Defcon, prego riprovare più tardi."
@@ -7672,7 +7637,7 @@ msgstr "I servizi sono stati configurati per non inviare e-mail."
msgid "Services ignore list:"
msgstr "Lista ignore dei Services:"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
"correctly?"
@@ -7685,7 +7650,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Services up %s."
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "I servizi imposteranno lo stato di %s automaticamente nei canali."
@@ -7696,7 +7661,7 @@ msgid "Services will no longer automatically give modes to users in %s."
msgstr ""
"I servizi non imposterannno più lo stato di %s automaticamente nei canali."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "I servizi non imposterannno più lo stato di %s nei canali."
@@ -7706,12 +7671,12 @@ msgstr "I servizi non imposterannno più lo stato di %s nei canali."
msgid "Services will now automatically give modes to users in %s."
msgstr "I servizi imposteranno automaticamente lo stato degli utenti su %s."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "I servizi risponderanno a %s usando i messaggi."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "I servizi risponderanno a %s usando i notices."
@@ -7729,7 +7694,7 @@ msgstr "Session"
msgid "Session limit for %s set to %d."
msgstr "Il limite di sessioni per %s è stato impostato a %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Il limite delle sessioni è disabilitato."
@@ -7766,7 +7731,7 @@ msgstr "Imposta il canale come permanente"
msgid "Set the channel description"
msgstr "Imposta la descrizione del canale"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
msgid "Set the display of your group in Services"
msgstr "Imposta il nome del tuo gruppo"
@@ -7774,11 +7739,11 @@ msgstr "Imposta il nome del tuo gruppo"
msgid "Set the founder of a channel"
msgstr "Imposta il founder del canale"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
msgid "Set the language Services will use when messaging you"
msgstr "Imposta la lingua utilizzata dai Services"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
msgid "Set the nickname password"
msgstr "Imposta la password del nick"
@@ -8105,7 +8070,7 @@ msgstr ""
msgid "Sets various nickname options. option can be one of:"
msgstr "Imposta varie opzioni del nick. option può essere una delle seguenti:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8119,7 +8084,7 @@ msgstr ""
"Imposta se il canale scadrà o meno in caso di inutilizzo. Se\n"
"l'opzione è impostata a ON, il canale non scadrà."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8133,7 +8098,7 @@ msgstr ""
"di impostare lo stato del nickname specificato automaticamente\n"
"quando accede al canale."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8141,7 +8106,7 @@ msgstr ""
"Imposta se il nickname specificato scadrà. Impostandolo su\n"
"ON eviterà che il nickname scada."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8154,7 +8119,7 @@ msgstr ""
"quando accedi ai canali. Nota che a seconda delle impostazioni del canale\n"
"alcuni modi potrebbero non essere impostati automaticamente."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8215,11 +8180,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "L'opzione Signed kick per %s è ora attiva."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Signed kick"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s attualmente ha troppi memo e non può riceverne altri."
@@ -8229,51 +8194,43 @@ msgstr "%s attualmente ha troppi memo e non può riceverne altri."
msgid "Sorry, I have not seen %s."
msgstr "Spiacente, non ho visto %s."
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr ""
-"Spiacente, la modifica della lista bad words è temporaneamente disabilitata."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Spiacente, l'assegnazione dei bot è temporaneamente disabilitata."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Spiacente, la modifica dei bot è temporaneamente disabilitata."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr ""
"Spiacente, l'impostazione delle opzioni dei bot è temporaneamente "
"disabilitata."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr ""
-"Spiacente, l'impostazione delle opzioni dei bot è temporaneamente "
-"disabilitata."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Spiacente, la modifica della lista %s è temporaneamente disabilitata."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr ""
"Spiacente, la modifica della lista di accesso dei canali è temporaneamente "
"disabilitata."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr ""
"Spiacente, la modifica della lista autokick è temporaneamente disabilitata."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr ""
+"Spiacente, la modifica della lista bad words è temporaneamente disabilitata."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr ""
@@ -8305,7 +8262,7 @@ msgstr "Spiacente, la deregistrazione dei nick è temporaneamente disabilitata."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Spiacente, il raggruppamento dei nick è temporaneamente disabilitato."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Spiacente, la registrazione dei nick è temporaneamente disabilitata."
@@ -8326,13 +8283,8 @@ msgstr "Spiacente, il limite massimo di %d auto join è stato raggiunto."
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Spiacente, il limite massimo di %d certificati è stato raggiunto."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "La lista oper info per %s è piena."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8346,7 +8298,7 @@ msgstr ""
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Spiacente, puoi avere un massimo di %d mask in autokick."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr ""
@@ -8413,7 +8365,7 @@ msgid ""
"Super admin can not be set because it is not enabled in the configuration."
msgstr ""
"L'impostazione SuperAdmin non può essere attivata perchè non è abilitata in "
-"services.conf"
+"anope.conf"
#: modules/commands/ns_suspend.cpp:60
msgid "Suspend a given nick"
@@ -8615,7 +8567,6 @@ msgstr ""
"--noexpire."
#: modules/commands/ms_set.cpp:246
-#, fuzzy
msgid ""
"Syntax: NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\n"
" \n"
@@ -8628,7 +8579,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -8706,7 +8657,7 @@ msgstr ""
"Questa opzione NON è persistente, e dovrebbe essere usata\n"
"solo quando necessario, e reimpostata a OFF al più presto."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -8723,12 +8674,12 @@ msgstr ""
"comando REGISTER."
#: modules/commands/cs_invite.cpp:91
-#, fuzzy, c-format
+#, c-format
msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Chiede a %s di invitarti, o di invitare il nick specificato\n"
@@ -8738,14 +8689,14 @@ msgstr ""
"livello di accesso 5 o superiori al canale."
#: modules/commands/cs_unban.cpp:103
-#, fuzzy, c-format
+#, c-format
msgid ""
"Tells %s to remove all bans preventing you or the given\n"
"user from entering the given channel. If no channel is\n"
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Chiede a %s di rimuovere tutti i ban che non ti permettono,\n"
@@ -8792,7 +8743,7 @@ msgstr "Termina i Services salvando i database"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -8809,7 +8760,7 @@ msgstr ""
"specificato può essere un livello numerico o il nome di un\n"
"privilegio (es. AUTOOP)."
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -8823,7 +8774,7 @@ msgstr ""
"LIST). Se vuoi puoi rimuovere te stesso da una lista di accesso,\n"
"anche se non hai l' accesso necessario per modificarla."
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -8854,21 +8805,20 @@ msgstr ""
"Il comando ACCESS CLEAR svuota completamente la lista di\n"
"accesso."
-#: modules/commands/cs_flags.cpp:447
-#, fuzzy
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
"Il comando CLEAR svuota la lista di accesso del canale, richiede di essere "
"founder."
#: modules/commands/cs_seen.cpp:174
-#, fuzzy, c-format
+#, c-format
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
@@ -8881,8 +8831,7 @@ msgstr ""
" %s CLEAR 30m\n"
" Rimuoverà tutti i dati aggiunti negli ultimi 30 minuti."
-#: modules/commands/bs_badwords.cpp:438
-#, fuzzy
+#: modules/commands/bs_badwords.cpp:437
msgid ""
"The DEL command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
@@ -8896,7 +8845,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Il comando DEL rimuove la parola specificata dalla lista\n"
@@ -8916,10 +8865,9 @@ msgstr ""
"Il comando CLEAR rimuove tutti i records dalla lista bad words."
#: modules/commands/cs_entrymsg.cpp:241
-#, fuzzy
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
"Il comando ENTRYMSG ADD aggiunge il messaggio specificato\n"
@@ -8927,10 +8875,9 @@ msgstr ""
"dell' ingresso nel canale."
#: modules/commands/cs_entrymsg.cpp:253
-#, fuzzy
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
"Il comando ENTRYMSG CLEAR rimuove tutti i records dalla\n"
@@ -8939,11 +8886,10 @@ msgstr ""
"di ingresso è di conseguenza disabilitato."
#: modules/commands/cs_entrymsg.cpp:245
-#, fuzzy
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
"TIl comando ENTRYMSG DEL rimuove il messaggio specificato dalla\n"
@@ -8953,19 +8899,18 @@ msgstr ""
"dei messaggi come spiegato di seguito."
#: modules/commands/cs_entrymsg.cpp:250
-#, fuzzy
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
"Il comando ENTRYMSG LIST mosta la lista dei messaggi da mostrare agli utenti "
"al momento dell' ingresso nel canale."
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "L'opzione IMMED non è disponibile su questa rete."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9006,7 +8951,7 @@ msgstr ""
"Per una lista delle funzioni e delle caratteristiche i cui livelli\n"
"possono essere impostati, vedi HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9026,19 +8971,18 @@ msgstr ""
"lista di accesso\n"
"con il flag specificato."
-#: modules/commands/cs_flags.cpp:435
-#, fuzzy
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
"Il comando MODIFY permette di modificare la lista di accesso. Se la mask\n"
"non è già presente nella lista di accesso viene aggiunta, e quindi le "
@@ -9060,7 +9004,7 @@ msgstr ""
"Il comando STATS mostra le statistiche relative ai memorizzati e l' uso "
"della memoria."
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -9076,7 +9020,6 @@ msgstr ""
"Di default l' indirizzo email è nascosto."
#: modules/commands/cs_log.cpp:258
-#, fuzzy, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9094,7 +9037,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9128,12 +9071,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "La lista ban di %s è piena."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, c-format
msgid "The %s list has been cleared."
msgstr "La lista %s è stata svuotata."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "La lista AKILL è stata svuotata."
@@ -9152,7 +9095,7 @@ msgstr "L'indirizzo e-mail di %s verrà ora nascosto da %s INFO."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "L'indirizzo e-mail di %s verrà ora mostrato in %s INFO."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr "Le flags disponibili sono:"
@@ -9181,11 +9124,11 @@ msgstr "L' indirizzo email %s ha raggiunto il limite di 1 utente."
msgid "The entry message list for %s is full."
msgstr "La lista dei messaggi di ingresso per %s è piena."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr "I seguenti nomi di caratteristiche/funzioni sono disponibili:"
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9249,12 +9192,7 @@ msgstr "La mask deve contenere almeno un carattere che non sia una wildcard."
msgid "The memo limit for %s may not be changed."
msgstr "Il limite dei memo di %s non può essere modificato."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "La lista oper info per %s è piena."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9270,10 +9208,6 @@ msgstr "Il nuovo nome del gruppo adesso è: %s"
msgid "The nick %s is now being changed to %s."
msgstr "Il nick %s viene ora cambiato in %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, c-format
msgid "The oper info already exists on %s."
@@ -9295,11 +9229,11 @@ msgstr "Lo stato di accesso ai servizi di %s verrà ora nascosto da %s INFO."
msgid "The services access status of %s will now be shown in %s INFO displays."
msgstr "Lo stato di accesso ai servizi di %s verrà ora mostrato in %s INFO."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
msgid "The session exception list is empty."
msgstr "La lista delle eccezioni sulle sessioni è vuota."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9374,7 +9308,7 @@ msgstr "Non c'è nessuna Random News."
msgid "There is no such configuration block %s."
msgstr "Non c'e' nessun blocco di configurazione %s."
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, c-format
msgid "There is no such mode %s."
msgstr "Non esiste alcun modo %s."
@@ -9400,7 +9334,7 @@ msgstr "Questo canale è sospeso."
msgid "This channel may not be used."
msgstr "Questo canale non può essere usato."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9433,7 +9367,7 @@ msgstr ""
"Questo comando permette agli utenti di impostare il vhost del\n"
"loro nick ATTUALE come vhost di tutti i nick nello stesso gruppo."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9450,7 +9384,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr "Questo comando è un alias del comando %s."
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
msgid ""
"This command is used by several commands as a way to confirm\n"
"changes made to your account.\n"
@@ -9475,10 +9409,9 @@ msgid "This command lists information about the specified loaded module."
msgstr "Questo comando elenca informazioni sul modulo caricato specificato."
#: modules/commands/hs_list.cpp:136
-#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -9568,7 +9501,7 @@ msgstr ""
"I Services Operators possono specificare un nick per modificare la lista\n"
"auto join di altri utenti."
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9580,7 +9513,7 @@ msgstr ""
msgid "This command reloads the module named modname."
msgstr "Questo comando ricarica il modulo chiamato modname."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr "Questo comando recupera le richieste di vhosts."
@@ -9645,7 +9578,7 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "Questo comando scarica il modulo chiamato modname."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
"Questo comando permette di ottenere il reinvio della email di conferma per "
@@ -9665,12 +9598,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Questo nickname è stato vietato: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "Questo nickname è stato recuperato da %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -9734,7 +9667,7 @@ msgstr "Top %i di %s"
msgid "Topic"
msgstr "Topic"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
msgid "Topic lock"
msgstr "Blocco del topic"
@@ -9748,7 +9681,7 @@ msgstr "Il blocco del topic per %s è ora disattivato."
msgid "Topic lock option for %s is now on."
msgstr "Il blocco del topic per %s è ora attivo."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
msgid "Topic retention"
msgstr "Mantenimento del topic"
@@ -9762,7 +9695,7 @@ msgstr "Il mantenimento del topic per %s è ora disattivato."
msgid "Topic retention option for %s is now on."
msgstr "Il mantenimento del topic per %s è ora attivo."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr "Topic impostato da"
@@ -9770,15 +9703,16 @@ msgstr "Topic impostato da"
msgid "Turn caps lock OFF!"
msgstr "Disattiva il caps lock!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
msgid "Turn chanstats statistics on or off"
msgstr "Attiva o disattiva le statistiche chanstats"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
msgid "Turn nickname security on or off"
msgstr "Attiva o disattiva le impostazioni di sicurezza"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
msgid "Turn protection on or off"
msgstr "Attiva o disattiva le impostazioni di protezione"
@@ -9812,7 +9746,7 @@ msgstr ""
"chiunque sappia il tuo nick può leggerne le informazioni con il\n"
"comando INFO."
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9839,7 +9773,7 @@ msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr ""
"Attiva o disattiva le statistiche di chanstats nel canale per questo utente."
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9868,7 +9802,7 @@ msgstr ""
"opzione se non è strettamente necessario.\n"
"L'opzione IMMED, inoltre, potrebbe non essere disponibile."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -9897,7 +9831,7 @@ msgstr ""
"opzione se non è strettamente necessario.\n"
"L'opzione IMMED, inoltre, potrebbe non essere disponibile."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr "Tipo"
@@ -9936,7 +9870,7 @@ msgstr ""
"su un'opzione specifica. Le opzioni verranno impostate sul\n"
"nickname specificato."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -9945,7 +9879,7 @@ msgstr ""
"Digita %s%s HELP %s option per ottenere maggiori\n"
"informazioni su un opzione specifica."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -9960,8 +9894,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Rimuove un modulo"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, c-format
msgid "Unable to find regex engine %s."
msgstr "Impossibile trovare la regex engine %s."
@@ -10000,7 +9934,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Kick in caso di sottolineato"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
msgid "Unknown SET option."
msgstr "Opzione SET sconosciuta."
@@ -10019,7 +9953,7 @@ msgstr "Comando %s sconosciuto."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Comando sconosciuto %s. \"%s%s HELP\" per l'aiuto."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "Modo sconosciuto carattere %c ignorato."
@@ -10042,10 +9976,9 @@ msgstr ""
"dal founder del canale."
#: modules/commands/cs_drop.cpp:74
-#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Deregistra il canale specificato. Solo i Services Operator\n"
"possono deregistrare un canale del quale non sono founder."
@@ -10058,11 +9991,10 @@ msgstr "Rilascia il nick specificato"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr "Rilascia un nickname permettendone nuovamente l' uso."
-#: modules/commands/cs_updown.cpp:126
-#, fuzzy
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
"Aggiorna lo stato del nick specificato in un canale. Se il nick\n"
@@ -10111,30 +10043,30 @@ msgstr ""
msgid "Used on"
msgstr "Usato on"
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "Autorizzato al cambio del topic del canale"
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr "Modifica la lista degli utenti con privilegi"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
msgid "User has been banned from the channel"
msgstr "L' utente è stato bannato dal canale"
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, c-format
msgid "User limit for %s removed."
msgstr "Il limite di utenti per %s è stato rimosso."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, c-format
msgid "User limit for %s set to %d."
msgstr "Limite di utenti per %s impostato a %d."
@@ -10185,12 +10117,12 @@ msgstr "Il vhost per il gruppo %s è stato impostato a %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
msgid "VIEW [mask | list | id]"
msgstr "VIEW [mask | list | id]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr "VIEW [mask | list]"
@@ -10203,7 +10135,7 @@ msgstr "Value"
msgid "Value of %s:%s changed to %s"
msgstr "Valore di %s:%s cambiato in %s ."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr "Vhost"
@@ -10241,7 +10173,7 @@ msgstr ""
"Quando questa opzione è attiva, il canale non sarà\n"
"incluso nella lista restituita da %s's %s."
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
msgid ""
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
@@ -10323,7 +10255,7 @@ msgstr ""
"l' opzione HASH , mostra informazioni relativa alla hash map. \n"
"L'opzione ALL, mostra tutte le statische descritte in precedenza."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr "Word"
@@ -10332,7 +10264,7 @@ msgstr "Word"
msgid "You are already a member of the group of %s."
msgstr "Sei già un membro del gruppo %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Sei già identificato."
@@ -10371,8 +10303,7 @@ msgstr "Ora sei un IRC Operator."
#: modules/commands/ns_resetpass.cpp:108
msgid "You are now identified for your nick. Change your password now."
-msgstr ""
-"Adesso sei identificato per il tuo nick. Cambia la tua password adesso."
+msgstr "Adesso sei identificato per il tuo nick. Cambia la tua password adesso."
#: modules/commands/ns_group.cpp:50
#, c-format
@@ -10392,7 +10323,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr "Non puoi usare NOOP sui Services."
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10418,13 +10349,22 @@ msgid "You can not request a receipt when sending a memo to yourself."
msgstr ""
"Non puoi richiedere una conferma di lettura se invii un memo a te stesso."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, c-format
+msgid "You can not set the %c flag."
+msgstr "Non puoi impostare il flag %c."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "Non puoi rimuovere i bot quando persist è impostato nel canale."
+
+#: modules/commands/ns_recover.cpp:143
#, c-format
msgid "You can't %s yourself!"
msgstr "Non puoi %s te stesso!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
msgid "You can't add a channel to its own access list."
msgstr "Non puoi aggiungere un canale alla sua stessa access list."
@@ -10433,16 +10373,11 @@ msgstr "Non puoi aggiungere un canale alla sua stessa access list."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Non puoi deidentificare %s , è un Services Operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, c-format
msgid "You cannot %s on this network."
msgstr "Non puoi usare %s su questo network."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "Non puoi impostare il flag %c."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10455,12 +10390,7 @@ msgid "You cannot set your memo limit higher than %d."
msgstr ""
"Non puoi impostare il limite dei tuoi memo ad un valore superiore a %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "Non puoi rimuovere i bot quando persist è impostato nel canale."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Non puoi annullare l'impostazione dell'e-mail."
@@ -10500,12 +10430,12 @@ msgstr "Hai 1 memo."
msgid "You currently have no memos."
msgstr "Non hai nessun memo."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr "Non hai accesso per impostare il modo %c."
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "Non hai accesso per cambiare i modi di %s."
@@ -10543,7 +10473,7 @@ msgstr "Sei stato invitato in %s da %s."
msgid "You have been invited to %s."
msgstr "Sei stato invitato in %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "Hai effettuato il login come %s."
@@ -10583,29 +10513,24 @@ msgstr ""
"Attenzione: Hai raggiunto il numero massimo di memo (%d). Non potrai "
"ricevere nuovi memo finché non ne elimini alcuni dal tuo archivio."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Sei stato invitato in %s."
-
#: modules/commands/ns_drop.cpp:66
msgid "You may drop any nick within your group."
msgstr "Puoi deregistrare qualsiasi nick del tuo gruppo."
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr "Non puoi sbloccare/bloccare il modo %c."
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
msgid "You may not change the e-mail of other Services Operators."
msgstr "Non puoi cambiare l'e-mail di altri Services Operators."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
msgid "You may not change the email of an unconfirmed account."
msgstr "Non puoi cambiare l'e-mail di un account non confermato."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
msgid "You may not change the password of other Services Operators."
msgstr "Non puoi cambiare la password di altri Services Operators."
@@ -10649,28 +10574,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "E' necessario essere operatore del canale per poterlo registrare."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "E' necessario essere identificati per usare questo comando."
-
#: modules/commands/cs_register.cpp:37
msgid "You must confirm your account before you can register a channel."
msgstr ""
"E' necessario confermare il tuo account prima di poter registrare un canale."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr ""
-"E' necessario confermare il tuo account prima di poter registrare un canale."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr ""
-"E' necessario confermare il tuo account prima di poter registrare un canale."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -10680,21 +10588,21 @@ msgstr ""
"E' necessario specificare il nome del canale due volte come conferma che "
"vuoi deregistrare %s."
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"E' necessario aver usato questo nick per almeno %d secondi prima di poterlo "
"registrare."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
"E' necessario avere i privilegi %s(ME) nel canale per poter usare questo "
"comando."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -10708,33 +10616,15 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "E' necessario essere identificati per usare questo comando."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Sarai informato dei nuovi memo quando li ricevi."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr "Sarai informato dei nuovi memo quando ti connetti e quando li ricevi."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr "Sarai informato dei nuovi memo quando ti connetti e quando li ricevi."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr "Sarai informato dei nuovi memo quando ti connetti e quando li ricevi."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Sarai informato dei nuovi memo quando ti connetti."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Sarai informato dei nuovi memo quando li ricevi."
@@ -10746,7 +10636,7 @@ msgstr "Non potrai più ricevere memo."
msgid "You will no longer be informed via email."
msgstr "Non sarai più informato via email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Non sarai informato dei nuovi memo."
@@ -10774,22 +10664,22 @@ msgstr ""
"Il tuo IRCd non supporta vIdent, se non è così, perfavore segnala il "
"problema come un possibile bug"
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Il tuo account %s è stato creato con successo."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
msgid "Your account is already confirmed."
msgstr "Il tuo account è già stato confermato."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Se non confermato, il tuo account scadra in %s."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Il tuo indirizzo email è stato cambiato in %s."
@@ -10798,7 +10688,7 @@ msgstr "Il tuo indirizzo email è stato cambiato in %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Il tuo indirizzo email non è consentito, scegline un altro diverso."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
@@ -10806,12 +10696,12 @@ msgstr ""
"Il tuo indirizzo email non è stato confermato. Per confermarlo, segui le "
"istruzioni contenute nella email che hai ricevuto quando ti sei registrato."
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Il tuo indirizzo email per %s è stato confermato."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, c-format
msgid "Your email has been updated to %s"
msgstr "Il tuo indirizzo email è stato aggiornato a %s"
@@ -10868,7 +10758,7 @@ msgstr "Il tuo nick è presente in nessun gruppo, non puoi usare UNGROUP."
msgid "Your nick isn't registered."
msgstr "Il tuo nickname non è registrato."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Il tuo nick sarà cambiato in %s"
@@ -10877,19 +10767,18 @@ msgstr "Il tuo nick sarà cambiato in %s"
msgid "Your oper block doesn't require logging in."
msgstr "Il tuo blocco oper non richiede l' accesso."
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Il codice di attivazione è stato reinviato a %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "La tua password è %s - non dimenticarla!"
#: include/language.h:77
-#, fuzzy, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
"La password scelta è troppo lunga. Per favore prova di nuovo con una "
"password più corta."
@@ -10898,23 +10787,23 @@ msgstr ""
msgid "Your password reset request has expired."
msgstr "La tua richiesta di reset della password è scaduta."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
msgid "Your vHost has been requested."
msgstr "Il tuo vHost è stato richisto."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Il tuo vhost %s ora è attivato."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Il tuo vhost %s@%s ora è attivato."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr ""
"Il tuo vhost è stato rimosso e l' offuscamento IP/Host standard ripristinato."
@@ -10962,7 +10851,7 @@ msgstr "[Random News - %s] %s"
msgid "[account] password"
msgstr "[account] password"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
msgid "[channel [nick]]"
msgstr "[channel [nick]]"
@@ -11010,8 +10899,8 @@ msgstr "[nick]"
msgid "[nickname [REVALIDATE]]"
msgstr "[nickname [REVALIDATE]]"
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
msgid "[nickname]"
msgstr "[nickname]"
@@ -11031,7 +10920,7 @@ msgstr "[+expiry] channel reason"
msgid "[Hostname hidden]"
msgstr "[Hostname nascosto]"
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr "[Sospeso]"
@@ -11039,21 +10928,21 @@ msgstr "[Sospeso]"
msgid "[Unconfirmed]"
msgstr "[Non confermato]"
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto-memo] La tua richiesta per il vHost è stata approvata."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto-memo] La tua richiesta per il vHost è stata rifiutata."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
"[auto memo] La tua richiesta per il vHost è stata rifiutata. Motivo: %s"
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] il vHost %s è stato richiesto da %s."
@@ -11155,12 +11044,12 @@ msgstr "secondo"
msgid "seconds"
msgstr "secondi"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, c-format
msgid "vHost for %s has been activated."
msgstr "Il vHost per %s è stato attivato."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, c-format
msgid "vHost for %s has been rejected."
msgstr "Il vHost per %s è stato rifiutato."
@@ -11194,36 +11083,6 @@ msgstr "{channel | nickname}"
msgid "{nick | channel}"
msgstr "{nick | channel}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
msgid "{nick | channel} memo-text"
msgstr "{nick | channel} memo-text"
-
-#~ msgid ""
-#~ " \n"
-#~ "The %s commands are limited to founders\n"
-#~ "(unless SECUREOPS is off). However, any user on the\n"
-#~ "VOP list or above may use the %s LIST command.\n"
-#~ " \n"
-#~ msgstr ""
-#~ " \n"
-#~ "I comandi %s sono limitati ai founders\n"
-#~ "(a meno che SECUREOPS non sia disabilitato). Qualsiasi utente\n"
-#~ "presente nella lista VOP o superiore puo usare il comando %s LIST.\n"
-#~ " \n"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "L'eccezione per %s (numero %d) è stata spostata alla posizione %d."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Le vecchie informazioni sono identiche a quelle nuove."
-
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Mostra i nick che utilizzano l' indirizzo email specificato.\n"
-#~ "Non è possibile usare wildcards. L' uso di questo comando viene\n"
-#~ "loggato dai services, nel log sarà incluso l' utente che ha eseguito\n"
-#~ "il comando e l' indirizzo email che è stato specificato."
diff --git a/language/anope.nl_NL.po b/language/anope.nl_NL.po
index 4f6d1132c..d000bf320 100644
--- a/language/anope.nl_NL.po
+++ b/language/anope.nl_NL.po
@@ -1,14 +1,14 @@
# Anope IRC Services language file
-# Copyright (C) 2013-2016
+# Copyright (C) 2013-2015
# This file is distributed under the same license as the Anope IRC Services package.
-# Robby <robby@chatbelgie.be>, 2013-2016.
+# Robby <robby@chatbelgie.be>, 2013-2015.
#
msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-07-07 15:52+0200\n"
-"PO-Revision-Date: 2016-07-07 16:03+0200\n"
+"POT-Creation-Date: 2015-09-18 05:40+0200\n"
+"PO-Revision-Date: 2015-09-18 05:56+0200\n"
"Last-Translator: Robby <robby@chatbelgie.be>\n"
"Language-Team: Dutch\n"
"Language: nl_NL\n"
@@ -66,12 +66,12 @@ msgstr "%s toegevoegd aan %s's certificaatlijst."
msgid "%s added to ignore list."
msgstr "%s toegevoegd aan negeerlijst."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, c-format
msgid "%s added to the %s list."
msgstr "%s toegevoegd aan de %s lijst."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s toegevoegd aan de AKILL lijst."
@@ -81,7 +81,8 @@ msgstr "%s toegevoegd aan de AKILL lijst."
msgid ""
"%s 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"
+"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"
msgstr ""
@@ -142,7 +143,7 @@ msgstr ""
"Voor meer informatie over een specifiek commando, typ\n"
"%s%s %s commando.\n"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -176,8 +177,8 @@ msgstr "%s bestaat al op %s autokicklijst."
msgid "%s already exists on the EXCEPTION list."
msgstr "%s bestaat al op de uitzonderingenlijst."
-#: modules/commands/bs_kick.cpp:214 modules/commands/bs_kick.cpp:389
-#: modules/commands/bs_kick.cpp:520 modules/commands/bs_kick.cpp:651
+#: modules/commands/bs_kick.cpp:216 modules/commands/bs_kick.cpp:391
+#: modules/commands/bs_kick.cpp:522 modules/commands/bs_kick.cpp:653
#, c-format
msgid "%s cannot be taken as times to ban."
msgstr "%s kan niet worden ingesteld als aantal keer om dan te bannen."
@@ -230,9 +231,9 @@ msgstr "%s verwijderd van de uitzonderingenlijst voor sessielimieten."
#: modules/commands/os_sxline.cpp:99
#, c-format
msgid "%s deleted from the %s list."
-msgstr "%s verwijderd uit de %s lijst."
+msgstr "%s verwijderd van de %s lijst."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s verwijderd van de AKILL lijst."
@@ -262,7 +263,7 @@ msgstr "%s werd gepart van %s."
msgid "%s has been unbanned from %s."
msgstr "%s wordt niet meer verbannen op %s."
-#: modules/commands/ns_alist.cpp:110
+#: modules/commands/ns_alist.cpp:101
#, c-format
msgid "%s has no access in any channels."
msgstr "%s heeft op geen enkel kanaal toegang."
@@ -282,7 +283,7 @@ msgstr "%s heeft te veel geregistreerde kanalen."
msgid "%s is a super administrator."
msgstr "%s is een super administrator."
-#: modules/pseudoclients/memoserv.cpp:203
+#: modules/pseudoclients/memoserv.cpp:202
#, c-format
msgid ""
"%s is a utility allowing IRC users to send short\n"
@@ -329,17 +330,17 @@ msgstr "%s is geen geregistreerde niet-verboden nick of kanaal."
msgid "%s is not a valid ban type."
msgstr "%s is geen geldige ban type."
-#: modules/commands/bs_info.cpp:101
+#: modules/commands/bs_info.cpp:102
#, c-format
msgid "%s is not a valid bot or registered channel."
msgstr "%s is geen geldige bot of geregistreerd kanaal."
-#: include/language.h:86
+#: include/language.h:87
#, c-format
msgid "%s is not a valid e-mail address."
msgstr "%s is geen geldig e-mailadres."
-#: include/language.h:80
+#: include/language.h:81
#, c-format
msgid "%s is not currently on channel %s."
msgstr "%s is niet aanwezig op kanaal %s."
@@ -354,7 +355,7 @@ msgstr "%s is niet op %s."
msgid "%s is not on the ignore list."
msgstr "%s staat niet op de negeerlijst."
-#: modules/commands/cs_status.cpp:90
+#: modules/commands/cs_status.cpp:75
#, c-format
msgid "%s is on the auto kick list of %s (%s)."
msgstr "%s staat op de autokicklijst van %s (%s)."
@@ -364,27 +365,21 @@ msgstr "%s staat op de autokicklijst van %s (%s)."
msgid "%s is the founder of %s."
msgstr "%s is de stichter van %s."
-#: modules/commands/cs_status.cpp:78
-#, c-format
-msgid "%s matches access entry %s (from entry %s), which has privilege %s."
-msgstr ""
-"%s stemt overeen met toegangsvermelding %s (van vermelding %s), die privilege %s "
-"heeft."
-
-#: modules/commands/cs_status.cpp:71
+#: modules/commands/cs_status.cpp:64
#, c-format
msgid "%s matches access entry %s, which has privilege %s."
msgstr "%s stemt overeen met toegangsvermelding %s, die privilege %s heeft."
-#: include/language.h:109
+#: include/language.h:110
#, c-format
msgid ""
-"%s matches an except on %s and cannot be banned until the except has been removed."
+"%s matches an except on %s and cannot be banned until the except has been "
+"removed."
msgstr ""
-"%s stemt overeen met een uitzondering op %s en kan niet verbannen worden tot deze "
-"uitzondering verwijderd is."
+"%s stemt overeen met een uitzondering op %s en kan niet verbannen worden tot "
+"deze uitzondering verwijderd is."
-#: modules/commands/cs_status.cpp:96
+#: modules/commands/cs_status.cpp:81
#, c-format
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s stemt overeen met autokick %s op %s (%s)."
@@ -427,7 +422,8 @@ msgstr "%s niet gevonden op de negeerlijst."
#: modules/commands/os_session.cpp:238
#, c-format
msgid ""
-"%s not found on session list, but has a limit of %d because it matches entry: %s."
+"%s not found on session list, but has a limit of %d because it matches entry:"
+" %s."
msgstr ""
"%s niet gevonden op sessielijst, maar heeft een limiet van %d omdat het "
"overeenstemt met: %s."
@@ -442,7 +438,7 @@ msgstr "%s niet gevonden op de uitzonderingenlijst voor sessielimieten."
msgid "%s not found on the %s list."
msgstr "%s niet gevonden op de %s lijst."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s niet gevonden op de AKILL lijst."
@@ -477,7 +473,7 @@ msgstr "%s zal nu genegeerd worden voor %s."
msgid "%s will now permanently be ignored."
msgstr "%s zal nu permanent genegeerd worden."
-#: include/language.h:66
+#: include/language.h:67
#, c-format
msgid "%s%s HELP %s for more information."
msgstr "%s%s HELP %s voor meer informatie."
@@ -575,7 +571,7 @@ msgstr "[auto-memo] De memo die je naar %s gestuurd hebt is bekeken."
msgid "[target] [password]"
msgstr "[doel] [wachtwoord]"
-#: modules/commands/ns_set.cpp:448
+#: modules/commands/ns_set.cpp:442
msgid "address"
msgstr "adres"
@@ -584,10 +580,10 @@ msgid "botname {ON|OFF}"
msgstr "botnick {ON|OFF}"
#: modules/extra/stats/cs_fantasy_top.cpp:39
-#: modules/extra/stats/cs_fantasy_top.cpp:51 modules/commands/cs_suspend.cpp:152
-#: modules/commands/cs_sync.cpp:20 modules/commands/cs_log.cpp:106
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_getkey.cpp:20
+#: modules/extra/stats/cs_fantasy_top.cpp:51
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_log.cpp:106 modules/commands/bs_assign.cpp:91
+#: modules/commands/cs_info.cpp:20 modules/commands/cs_getkey.cpp:20
msgid "channel"
msgstr "kanaal"
@@ -611,7 +607,7 @@ msgstr "kanaal masker [reden]"
msgid "channel modes"
msgstr "kanaal modes"
-#: modules/commands/cs_set.cpp:264 modules/commands/cs_set.cpp:961
+#: modules/commands/cs_set.cpp:264 modules/commands/cs_set.cpp:962
#: modules/commands/bs_assign.cpp:20
msgid "channel nick"
msgstr "kanaal nick"
@@ -747,7 +743,7 @@ msgstr "kanaal [beschrijving]"
msgid "channel [nick]"
msgstr "kanaal [nick]"
-#: modules/commands/cs_set_misc.cpp:96
+#: modules/commands/cs_set_misc.cpp:95
msgid "channel [parameters]"
msgstr "kanaal [parameters]"
@@ -759,7 +755,7 @@ msgstr "kanaal [nick]"
msgid "channel [+expiry] [reason]"
msgstr "kanaal [+verlooptijd] [reden]"
-#: modules/commands/cs_ban.cpp:40
+#: modules/commands/cs_ban.cpp:41
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "kanaal [+verlooptijd] {nick | masker} [reden]"
@@ -780,22 +776,22 @@ msgstr "kanaal [UNLOCK|LOCK]"
msgid "channel {ON|OFF}"
msgstr "kanaal {ON|OFF}"
-#: modules/commands/bs_kick.cpp:491
+#: modules/commands/bs_kick.cpp:493
msgid "channel {ON|OFF} [ttb [ln [secs]]]"
msgstr "kanaal {ON|OFF} [ttb [lijnen [seconden]]]"
-#: modules/commands/bs_kick.cpp:361
+#: modules/commands/bs_kick.cpp:363
msgid "channel {ON|OFF} [ttb [min [percent]]]"
msgstr "kanaal {ON|OFF} [ttb [minuten [percentage]]]"
-#: modules/commands/bs_kick.cpp:623
+#: modules/commands/bs_kick.cpp:625
msgid "channel {ON|OFF} [ttb [num]]"
msgstr "kanaal {ON|OFF} [ttb [aantal]]"
-#: modules/commands/bs_kick.cpp:252 modules/commands/bs_kick.cpp:288
-#: modules/commands/bs_kick.cpp:327 modules/commands/bs_kick.cpp:457
-#: modules/commands/bs_kick.cpp:589 modules/commands/bs_kick.cpp:724
-#: modules/commands/bs_kick.cpp:758
+#: modules/commands/bs_kick.cpp:254 modules/commands/bs_kick.cpp:290
+#: modules/commands/bs_kick.cpp:329 modules/commands/bs_kick.cpp:459
+#: modules/commands/bs_kick.cpp:591 modules/commands/bs_kick.cpp:713
+#: modules/commands/bs_kick.cpp:747
msgid "channel {ON|OFF} [ttb]"
msgstr "kanaal {ON|OFF} [ttb]"
@@ -803,16 +799,16 @@ msgstr "kanaal {ON|OFF} [ttb]"
msgid "channel {DIS | DISABLE} type"
msgstr "kanaal {DIS | DISABLE} type"
-#: modules/commands/cs_set.cpp:884
+#: modules/commands/cs_set.cpp:885
msgid "channel {ON | LEVEL | OFF}"
msgstr "kanaal {ON | LEVEL | OFF}"
#: modules/extra/stats/m_chanstats.cpp:10 modules/commands/cs_set.cpp:72
#: modules/commands/cs_set.cpp:333 modules/commands/cs_set.cpp:398
#: modules/commands/cs_set.cpp:470 modules/commands/cs_set.cpp:633
-#: modules/commands/cs_set.cpp:695 modules/commands/cs_set.cpp:758
-#: modules/commands/cs_set.cpp:822 modules/commands/cs_set.cpp:1047
-#: modules/commands/bs_kick.cpp:792 modules/commands/bs_kick.cpp:857
+#: modules/commands/cs_set.cpp:695 modules/commands/cs_set.cpp:759
+#: modules/commands/cs_set.cpp:823 modules/commands/cs_set.cpp:1048
+#: modules/commands/bs_kick.cpp:781 modules/commands/bs_kick.cpp:846
#: modules/commands/cs_topic.cpp:21 modules/commands/cs_list.cpp:181
msgid "channel {ON | OFF}"
msgstr "kanaal {ON | OFF}"
@@ -821,7 +817,7 @@ msgstr "kanaal {ON | OFF}"
msgid "email"
msgstr "e-mail"
-#: modules/commands/ns_set.cpp:786
+#: modules/commands/ns_set.cpp:780
msgid "language"
msgstr "taal"
@@ -848,7 +844,7 @@ msgstr "nieuw-wachtwoord"
#: modules/extra/stats/cs_fantasy_stats.cpp:52 modules/commands/hs_del.cpp:20
#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
-#: modules/commands/hs_request.cpp:192 modules/commands/cs_seen.cpp:262
+#: modules/commands/hs_request.cpp:193 modules/commands/cs_seen.cpp:258
msgid "nick"
msgstr "nick"
@@ -872,7 +868,7 @@ msgstr "nick hostmasker"
msgid "nick newnick"
msgstr "nick nieuwenick"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:242
msgid "nick [reason]"
msgstr "nick [reden]"
@@ -881,7 +877,7 @@ msgstr "nick [reden]"
msgid "nickname"
msgstr "nick"
-#: modules/commands/ns_set.cpp:538
+#: modules/commands/ns_set.cpp:532
msgid "nickname address"
msgstr "nickname adres"
@@ -889,7 +885,7 @@ msgstr "nickname adres"
msgid "nickname email"
msgstr "nick e-mail"
-#: modules/commands/ns_set.cpp:864
+#: modules/commands/ns_set.cpp:855
msgid "nickname language"
msgstr "nickname taal"
@@ -897,7 +893,7 @@ msgstr "nickname taal"
msgid "nickname message"
msgstr "nickname bericht"
-#: modules/commands/ns_set.cpp:396
+#: modules/commands/ns_set.cpp:390
msgid "nickname new-display"
msgstr "nickname nieuwe-weergave"
@@ -909,7 +905,7 @@ msgstr "nickname nieuw-wachtwoord"
msgid "nickname [parameter]"
msgstr "nickname [parameter]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:132
msgid "nickname [password]"
msgstr "nick [wachtwoord]"
@@ -922,13 +918,13 @@ msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "nick {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
#: modules/extra/stats/m_chanstats.cpp:122 modules/commands/ns_set.cpp:299
-#: modules/commands/ns_set.cpp:623 modules/commands/ns_set.cpp:977
-#: modules/commands/ns_set.cpp:1068 modules/commands/ns_set.cpp:1097
+#: modules/commands/ns_set.cpp:617 modules/commands/ns_set.cpp:968
+#: modules/commands/ns_set.cpp:1059 modules/commands/ns_set.cpp:1088
#: modules/commands/ns_list.cpp:252
msgid "nickname {ON | OFF}"
msgstr "nickname {ON | OFF}"
-#: modules/commands/ns_set.cpp:752
+#: modules/commands/ns_set.cpp:746
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "nickname {ON | QUICK | IMMED | OFF}"
@@ -940,7 +936,7 @@ msgstr "optie (kanaal | bot) instellingen"
msgid "option channel parameters"
msgstr "optie kanaal parameters"
-#: modules/commands/bs_kick.cpp:120
+#: modules/commands/bs_kick.cpp:122
msgid "option channel {ON|OFF} [settings]"
msgstr "optie kanaal {ON|OFF} [instellingen]"
@@ -960,15 +956,15 @@ msgstr "optie instelling"
msgid "passcode"
msgstr "bevestigingscode"
-#: modules/commands/os_login.cpp:19
+#: modules/commands/os_login.cpp:20
msgid "password"
msgstr "wachtwoord"
-#: modules/commands/ns_register.cpp:124
+#: modules/commands/ns_register.cpp:110
msgid "password [email]"
msgstr "wachtwoord [e-mail]"
-#: modules/commands/ns_register.cpp:122
+#: modules/commands/ns_register.cpp:108
msgid "password email"
msgstr "wachtwoord e-mail"
@@ -1010,7 +1006,7 @@ msgstr ""
"kwaadwillige acties te helpen. Misbruik van %s zal resulteren in,\n"
"minimaal, het verlies van de misbruikte nick(s)."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
msgid ""
" \n"
"SNLINE ADD adds the given realname mask to the SNLINE\n"
@@ -1044,7 +1040,7 @@ msgstr ""
"Let op: omdat het naam masker spaties mag bevatten, is de scheiding\n"
"tussen het masker en de reden een dubbele punt (:)."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:670
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1141,7 +1137,7 @@ msgstr ""
"van de gebruikers die het kanaal binnenkomen weergegeven,\n"
"mits ze hiertoe voldoende rechten hebben op het kanaal."
-#: modules/commands/bs_kick.cpp:843
+#: modules/commands/bs_kick.cpp:832
msgid ""
" \n"
"Enables or disables ops protection mode on a channel.\n"
@@ -1154,7 +1150,7 @@ msgstr ""
"gekickt worden, zelfs wanneer deze niet overeen komen\n"
"met het NOKICK niveau."
-#: modules/commands/bs_kick.cpp:908
+#: modules/commands/bs_kick.cpp:897
msgid ""
" \n"
"Enables or disables voices protection mode on a channel.\n"
@@ -1174,8 +1170,8 @@ msgid ""
"Fantasy commands may be prefixed with one of the following characters: %s\n"
msgstr ""
" \n"
-"Fantasie commando's mogen voorafgegaan worden met één van de volgende karakters: "
-"%s\n"
+"Fantasie commando's mogen voorafgegaan worden met één van de volgende "
+"karakters: %s\n"
#: modules/commands/cs_register.cpp:105
msgid ""
@@ -1187,7 +1183,7 @@ msgstr ""
"OPGELET: Om een kanaal te kunnen registreren moet\n"
"eerst je nickname geregistreerd zijn."
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, c-format
msgid ""
" \n"
@@ -1225,7 +1221,7 @@ msgstr ""
"verwijderen zonder zich voor die nick te identificeren, en\n"
"mogen de toegangslijst voor elke nick bekijken."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
msgid ""
" \n"
"Services Operators can also, depending on their access drop\n"
@@ -1333,7 +1329,7 @@ msgstr ""
" \n"
"Het AKICK CLEAR commando maakt de AutoKicklijst leeg."
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
msgid ""
" \n"
"The AKILL DEL command removes the given mask from the\n"
@@ -1376,7 +1372,7 @@ msgstr ""
" \n"
"AKILL CLEAR maakt de AKILL lijst leeg."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
msgid ""
" \n"
"The SNLINE DEL command removes the given mask from the\n"
@@ -1417,7 +1413,7 @@ msgstr ""
" \n"
"SNLINE CLEAR verwijdert alle vermeldingen van de SNLINE lijst."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:689
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1482,7 +1478,7 @@ msgstr ""
"toegewezen aan een kanaal door gebruikers die geen\n"
"IRC operator zijn."
-#: modules/pseudoclients/memoserv.cpp:216
+#: modules/pseudoclients/memoserv.cpp:215
#, c-format
msgid ""
" \n"
@@ -1493,7 +1489,7 @@ msgstr ""
"Typ %s%s HELP commando voor help over een van\n"
"de bovenstaande commando's."
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:166
#, c-format
msgid " %s is online using this oper block."
msgstr " %s is online met dit oper blok."
@@ -1508,7 +1504,7 @@ msgstr " Commando %s op %s is gelinkt aan %s"
msgid " Providing service: %s"
msgstr " Stelt ter beschikking: %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:162
msgid " This oper is configured in the configuration file."
msgstr " Deze oper is ingesteld in het configuratiebestand."
@@ -1517,21 +1513,23 @@ msgstr " Deze oper is ingesteld in het configuratiebestand."
msgid " Loaded at: %p"
msgstr " Geladen op: %p"
-#: modules/commands/cs_seen.cpp:302
+#: modules/commands/cs_seen.cpp:298
#, c-format
msgid " but %s mysteriously dematerialized."
msgstr " maar %s is in rook opgegaan."
-#: src/messages.cpp:339
+#: src/messages.cpp:340
#, c-format
-msgid "\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
-msgstr "\"/msg %s\" wordt niet meer ondersteund. Gebruik \"/msg %s@%s\" of \"/%s\"."
+msgid ""
+"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
+msgstr ""
+"\"/msg %s\" wordt niet meer ondersteund. Gebruik \"/msg %s@%s\" of \"/%s\"."
#: modules/commands/os_jupe.cpp:19
msgid "\"Jupiter\" a server"
msgstr "Blokkeer een server"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:160
#, c-format
msgid "%-8s %s"
msgstr "%-8s %s"
@@ -1539,9 +1537,10 @@ msgstr "%-8s %s"
#: modules/extra/stats/cs_fantasy_top.cpp:152
#, c-format
msgid "%2lu %-16s letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"
-msgstr "%2lu %-16s letters: %s, woorden: %s, lijnen: %s, smileys: %s, acties: %s"
+msgstr ""
+"%2lu %-16s letters: %s, woorden: %s, lijnen: %s, smileys: %s, acties: %s"
-#: src/misc.cpp:359
+#: src/misc.cpp:360
msgid "%b %d %H:%M:%S %Y %Z"
msgstr "%b %d %H:%M:%S %Y %Z"
@@ -1580,10 +1579,11 @@ msgstr "%d modules geladen."
msgid "%d nickname(s) in the group."
msgstr "%d nick(s) in de groep."
-#: modules/commands/cs_seen.cpp:137
+#: modules/commands/cs_seen.cpp:138
#, c-format
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
-msgstr "%lu nicks zijn opgeslagen in de database, geheugenverbruik is %.2Lf kB."
+msgstr ""
+"%lu nicks zijn opgeslagen in de database, geheugenverbruik is %.2Lf kB."
#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
#: modules/commands/cs_xop.cpp:458
@@ -1591,95 +1591,97 @@ msgstr "%lu nicks zijn opgeslagen in de database, geheugenverbruik is %.2Lf kB."
msgid "%s %s list is empty."
msgstr "%s %s lijst is leeg."
-#: modules/commands/bs_kick.cpp:1151 modules/commands/bs_kick.cpp:1181
-#: modules/commands/bs_kick.cpp:1191 modules/commands/bs_kick.cpp:1201
-#: modules/commands/bs_kick.cpp:1211
+#: modules/commands/bs_kick.cpp:1140 modules/commands/bs_kick.cpp:1170
+#: modules/commands/bs_kick.cpp:1180 modules/commands/bs_kick.cpp:1190
+#: modules/commands/bs_kick.cpp:1200
#, c-format
msgid "%s (%d kick(s) to ban)"
msgstr "%s (%d kick(s) tot ban)"
-#: modules/commands/bs_kick.cpp:1161
+#: modules/commands/bs_kick.cpp:1150
#, c-format
msgid "%s (%d kick(s) to ban; %d lines in %ds)"
msgstr "%s (%d kick(s) tot ban; %d lijnen in %ds)"
-#: modules/commands/bs_kick.cpp:1171
+#: modules/commands/bs_kick.cpp:1160
#, c-format
msgid "%s (%d kick(s) to ban; %d times)"
msgstr "%s (%d kick(s) tot ban; %d maal)"
-#: modules/commands/bs_kick.cpp:1141
+#: modules/commands/bs_kick.cpp:1130
#, c-format
msgid "%s (%d kick(s) to ban; minimum %d/%d%%)"
msgstr "%s (%d kick(s) tot ban; minimaal %d/%d%%)"
-#: modules/commands/bs_kick.cpp:1163
+#: modules/commands/bs_kick.cpp:1152
#, c-format
msgid "%s (%d lines in %ds)"
msgstr "%s (%d lijnen in %ds)"
-#: modules/commands/bs_kick.cpp:1173
+#: modules/commands/bs_kick.cpp:1162
#, c-format
msgid "%s (%d times)"
msgstr "%s (%d keer)"
-#: modules/commands/cs_seen.cpp:357
+#: modules/commands/cs_seen.cpp:353
#, c-format
msgid "%s (%s) was kicked from %s (\"%s\") %s ago%s"
msgstr "%s (%s) werd gekickt van %s (\"%s\") %s geleden%s"
-#: modules/commands/cs_seen.cpp:354
+#: modules/commands/cs_seen.cpp:350
#, c-format
msgid "%s (%s) was kicked from a secret channel %s ago%s"
msgstr "%s (%s) werd gekickt van een geheim kanaal %s geleden%s"
-#: modules/commands/cs_seen.cpp:325
+#: modules/commands/cs_seen.cpp:321
#, c-format
msgid "%s (%s) was last seen changing nick from %s to %s %s ago%s"
msgstr ""
"%s (%s) werd het laatst gezien bij het van nick veranderen van %s naar %s %s "
"geleden%s"
-#: modules/commands/cs_seen.cpp:320
+#: modules/commands/cs_seen.cpp:316
#, c-format
msgid "%s (%s) was last seen changing nick to %s %s ago%s"
msgstr ""
-"%s (%s) werd het laatst gezien bij het van nick veranderen naar %s %s geleden%s"
+"%s (%s) werd het laatst gezien bij het van nick veranderen naar %s %s geleden"
+"%s"
-#: modules/commands/cs_seen.cpp:309
+#: modules/commands/cs_seen.cpp:305
#, c-format
msgid "%s (%s) was last seen connecting %s ago (%s)%s"
msgstr "%s (%s) werd het laatst gezien bij het verbinden %s geleden (%s)%s"
-#: modules/commands/cs_seen.cpp:334
+#: modules/commands/cs_seen.cpp:330
#, c-format
msgid "%s (%s) was last seen joining %s %s ago%s"
msgstr "%s (%s) werd het laatst gezien bij het binnenkomen op %s %s geleden%s"
-#: modules/commands/cs_seen.cpp:331
+#: modules/commands/cs_seen.cpp:327
#, c-format
msgid "%s (%s) was last seen joining a secret channel %s ago%s"
msgstr ""
"%s (%s) werd het laatst gezien bij het binnenkomen van een geheim kanaal %s "
"geleden%s"
-#: modules/commands/cs_seen.cpp:343
+#: modules/commands/cs_seen.cpp:339
#, c-format
msgid "%s (%s) was last seen parting %s %s ago%s"
msgstr "%s (%s) werd het laatst gezien bij het verlaten van %s %s geleden%s"
-#: modules/commands/cs_seen.cpp:340
+#: modules/commands/cs_seen.cpp:336
#, c-format
msgid "%s (%s) was last seen parting a secret channel %s ago%s"
msgstr ""
-"%s (%s) werd het laatst gezien bij het verlaten van een geheim kanaal %s geleden%s"
+"%s (%s) werd het laatst gezien bij het verlaten van een geheim kanaal %s "
+"geleden%s"
-#: modules/commands/cs_seen.cpp:348
+#: modules/commands/cs_seen.cpp:344
#, c-format
msgid "%s (%s) was last seen quitting (%s) %s ago (%s)."
msgstr "%s (%s) werd het laatst gezien bij het quitten (%s) %s geleden (%s)."
-#: modules/commands/bs_kick.cpp:1143
+#: modules/commands/bs_kick.cpp:1132
#, c-format
msgid "%s (minimum %d/%d%%)"
msgstr "%s (minimaal %d/%d%%)"
@@ -1696,7 +1698,7 @@ msgstr "%s toegangslijst is leeg."
msgid "%s added to %s's auto join list."
msgstr "%s toegevoegd aan %s's autojoinlijst."
-#: src/xline.cpp:389
+#: src/xline.cpp:360
#, c-format
msgid "%s already exists."
msgstr "%s bestaat al."
@@ -1712,18 +1714,19 @@ msgstr "%s autokicklijst is leeg."
msgid "%s bad words list is empty."
msgstr "%s slechtewoordenlijst is leeg."
-#: modules/commands/cs_set.cpp:1004
+#: modules/commands/cs_set.cpp:1005
#, c-format
msgid "%s cannot be the successor on channel %s as they are the founder."
-msgstr "%s kan de opvolger niet zijn op kanaal %s omdat hij/zij de stichter is."
+msgstr ""
+"%s kan de opvolger niet zijn op kanaal %s omdat hij/zij de stichter is."
#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/hostserv.cpp:78
-#: modules/pseudoclients/operserv.cpp:287
+#: modules/pseudoclients/operserv.cpp:279
#, c-format
msgid "%s commands:"
msgstr "%s commando's:"
-#: include/language.h:69
+#: include/language.h:70
#, c-format
msgid "%s coverage is too wide; Please use a more specific mask."
msgstr "%s is te breed; gelieve een meer specifiek masker te gebruiken."
@@ -1768,12 +1771,12 @@ msgstr "%s heeft momenteel geen memo's."
msgid "%s deleted from the %s forbid list."
msgstr "%s verwijderd van de verboden %s lijst."
-#: include/language.h:105
+#: include/language.h:106
#, c-format
msgid "%s for %s set to %s."
msgstr "%s voor %s gewijzigd naar %s."
-#: include/language.h:106
+#: include/language.h:107
#, c-format
msgid "%s for %s unset."
msgstr "%s voor %s verwijderd."
@@ -1788,12 +1791,12 @@ msgstr "%s had een ongeldige opgegeven sleutel, en werd dus genegeerd."
msgid "%s has no memo limit."
msgstr "%s heeft geen memolimiet."
-#: include/language.h:115
+#: include/language.h:116
#, c-format
msgid "%s has no memos."
msgstr "%s heeft geen memo's."
-#: include/language.h:118
+#: include/language.h:119
#, c-format
msgid "%s has no new memos."
msgstr "%s heeft geen nieuwe memo's."
@@ -1808,17 +1811,17 @@ msgstr "%s is %s"
msgid "%s is a Services Operator of type %s."
msgstr "%s is een Services Operator van het type %s."
-#: modules/commands/cs_seen.cpp:280
+#: modules/commands/cs_seen.cpp:276
#, c-format
msgid "%s is a client on services."
msgstr "%s is een bot van Services."
-#: modules/commands/cs_seen.cpp:200
+#: modules/commands/cs_seen.cpp:201
#, c-format
msgid "%s is a network service."
msgstr "%s is een netwerkdienst."
-#: src/xline.cpp:407
+#: src/xline.cpp:378
#, c-format
msgid "%s is already covered by %s."
msgstr "%s is al gedekt door %s."
@@ -1859,7 +1862,7 @@ msgstr "%s is uitgeschakeld"
msgid "%s is enabled"
msgstr "%s is ingeschakeld"
-#: modules/commands/os_dns.cpp:507
+#: modules/commands/os_dns.cpp:506
#, c-format
msgid "%s is not a valid IP address."
msgstr "%s is geen geldig IP-adres."
@@ -1883,8 +1886,8 @@ msgstr "%s wordt niet geïnformeerd over nieuwe memo's."
#, c-format
msgid "%s is notified of new memos at logon and when they arrive."
msgstr ""
-"%s wordt geïnformeerd over nieuwe memo's wanneer hij/zij inlogt en wanneer deze "
-"toekomen."
+"%s wordt geïnformeerd over nieuwe memo's wanneer hij/zij inlogt en wanneer "
+"deze toekomen."
#: modules/commands/ms_info.cpp:122
#, c-format
@@ -1896,12 +1899,12 @@ msgstr "%s wordt geïnformeerd over nieuwe memo's wanneer je inlogt."
msgid "%s is notified when new memos arrive."
msgstr "%s wordt geinformeerd over nieuwe memo's wanneer deze arriveren."
-#: modules/commands/cs_seen.cpp:232
+#: modules/commands/cs_seen.cpp:233
#, c-format
msgid "%s is on the channel right now (as %s)!"
msgstr "%s is nu op het kanaal (als %s)!"
-#: modules/commands/cs_seen.cpp:221
+#: modules/commands/cs_seen.cpp:222
#, c-format
msgid "%s is on the channel right now!"
msgstr "%s is nu op het kanaal!"
@@ -1931,7 +1934,7 @@ msgstr "%s niet gevonden."
msgid "%s settings:"
msgstr "%s instellingen:"
-#: modules/commands/cs_seen.cpp:255
+#: modules/commands/cs_seen.cpp:251
#, c-format
msgid "%s was last seen here %s ago."
msgstr "%s werd hier het laatst %s geleden gezien."
@@ -1954,12 +1957,14 @@ msgstr "%s zal je niet over memo's informeren."
#: modules/commands/ms_set.cpp:42
#, c-format
msgid "%s will now notify you of memos when they are sent to you."
-msgstr "%s zal je nu informeren over memo's wanneer deze naar jou worden verzonden."
+msgstr ""
+"%s zal je nu informeren over memo's wanneer deze naar jou worden verzonden."
#: modules/commands/ms_set.cpp:30
#, c-format
msgid ""
-"%s will now notify you of memos when you log on and when they are sent to you."
+"%s will now notify you of memos when you log on and when they are sent to "
+"you."
msgstr ""
"%s zal je nu informeren over memo's zodra je inlogt en wanneer deze naar je "
"toegezonden worden."
@@ -1967,7 +1972,8 @@ msgstr ""
#: modules/commands/ms_set.cpp:36
#, c-format
msgid "%s will now notify you of memos when you log on or unset /AWAY."
-msgstr "%s zal je nu informeren over memo's wanneer je inlogt of /AWAY uitschakelt."
+msgstr ""
+"%s zal je nu informeren over memo's wanneer je inlogt of /AWAY uitschakelt."
#: modules/commands/bs_bot.cpp:89
#, c-format
@@ -2004,17 +2010,17 @@ msgstr "%s's memolimiet is %d, en mag niet worden veranderd."
msgid "%s's memo limit is %d."
msgstr "%s's memolimiet is %d."
-#: src/misc.cpp:363
+#: src/misc.cpp:364
#, c-format
msgid "(%s ago)"
msgstr "(%s geleden)"
-#: src/misc.cpp:365
+#: src/misc.cpp:366
#, c-format
msgid "(%s from now)"
msgstr "(%s vanaf nu)"
-#: modules/commands/os_dns.cpp:244
+#: modules/commands/os_dns.cpp:243
msgid "(Split)"
msgstr "(Gesplit)"
@@ -2031,7 +2037,7 @@ msgstr "(uitgeschakeld)"
msgid "(founder only)"
msgstr "(enkel stichter)"
-#: src/misc.cpp:367
+#: src/misc.cpp:368
msgid "(now)"
msgstr "(nu)"
@@ -2077,42 +2083,42 @@ msgstr "* Negeer niet-operators (geen boodschap)"
msgid "* Use the reduced session limit of %d"
msgstr "* Gebruik de beperkte sessielimiet van %d"
-#: modules/commands/cs_seen.cpp:318
+#: modules/commands/cs_seen.cpp:314
#, c-format
msgid ", but %s mysteriously dematerialized."
msgstr ", maar %s is in rook opgegaan."
-#: modules/commands/cs_seen.cpp:316
+#: modules/commands/cs_seen.cpp:312
#, c-format
msgid ". %s is still online."
msgstr "%s is nog steeds online."
-#: include/language.h:87
+#: include/language.h:88
msgid "<unknown>"
msgstr "<onbekend>"
-#: modules/commands/ns_set.cpp:497
+#: modules/commands/ns_set.cpp:491
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
"change your e-mail address."
msgstr ""
-"Een bevestigings-e-mail werd verstuurd naar %s. Volg de instructies om je e-mail "
-"adres te wijzigen."
+"Een bevestigings-e-mail werd verstuurd naar %s. Volg de instructies om je e-"
+"mail adres te wijzigen."
#: modules/commands/ms_sendall.cpp:45
msgid "A massmemo has been sent to all registered users."
msgstr "Een memo werd gestuurd naar alle geregistreerde gebruikers."
-#: modules/commands/hs_request.cpp:285
+#: modules/commands/hs_request.cpp:286
msgid ""
-"A memo informing the user will also be sent, which includes the reason for the "
-"rejection if supplied."
+"A memo informing the user will also be sent, which includes the reason for "
+"the rejection if supplied."
msgstr ""
-"Een informerende memo zal ook gestuurd worden naar de gebruiker, met de reden "
-"indien opgegeven."
+"Een informerende memo zal ook gestuurd worden naar de gebruiker, met de "
+"reden indien opgegeven."
-#: modules/commands/hs_request.cpp:229
+#: modules/commands/hs_request.cpp:230
msgid "A memo informing the user will also be sent."
msgstr "Een informerende memo zal ook gestuurd worden naar de gebruiker."
@@ -2125,11 +2131,11 @@ msgstr ""
"Een notificatie-memo is naar %s verstuurd om hem/haar te\n"
"informeren dat je zijn/haar memo gelezen hebt."
-#: include/language.h:123
+#: include/language.h:124
msgid "A vHost ident must be in the format of a valid ident."
msgstr "Een vHost ident moet in het formaat van een geldige ident zijn."
-#: include/language.h:122
+#: include/language.h:123
msgid "A vHost must be in the format of a valid hostname."
msgstr "Een vHost moet in het formaat van een geldige host zijn."
@@ -2165,11 +2171,11 @@ msgstr "ADD [nick] masker"
msgid "ADD [nickname] [fingerprint]"
msgstr "ADD [nick] [vingerafdruk]"
-#: modules/commands/os_sxline.cpp:659 modules/commands/os_akill.cpp:386
+#: modules/commands/os_sxline.cpp:651 modules/commands/os_akill.cpp:380
msgid "ADD [+expiry] mask reason"
msgstr "ADD [+verlooptijd] masker reden"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
msgid "ADD [+expiry] mask:reason"
msgstr "ADD [+verlooptijd] masker:reden"
@@ -2177,15 +2183,15 @@ msgstr "ADD [+verlooptijd] masker:reden"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+verlooptijd] vermelding reden"
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "ADDIP server.name ip"
msgstr "ADDIP server.naam ip"
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "ADDSERVER server.name [zone.name]"
msgstr "ADDSERVER server.naam [domein.naam]"
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "ADDZONE zone.name"
msgstr "ADDZONE domein.naam"
@@ -2198,13 +2204,13 @@ msgstr "AKICK ENFORCE voor %s klaar; %d gebruiker(s) zijn/is getroffen."
msgid "AKILL all users on a specific channel"
msgstr "AKILL alle gebruikers op een specifiek kanaal"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "AKILL lijst is leeg."
-#: modules/commands/bs_kick.cpp:1211 modules/commands/bs_kick.cpp:1213
-#: modules/commands/bs_kick.cpp:1216
+#: modules/commands/bs_kick.cpp:1200 modules/commands/bs_kick.cpp:1202
+#: modules/commands/bs_kick.cpp:1205
msgid "AMSG kicker"
msgstr "AMSG-kicker"
@@ -2212,7 +2218,7 @@ msgstr "AMSG-kicker"
msgid "Access"
msgstr "Toegang"
-#: include/language.h:72
+#: include/language.h:73
msgid "Access denied."
msgstr "Toegang geweigerd."
@@ -2221,7 +2227,7 @@ msgstr "Toegang geweigerd."
msgid "Access for %s on %s:"
msgstr "Toegang voor %s op %s:"
-#: include/language.h:107
+#: include/language.h:108
#, c-format
msgid "Access level must be between %d and %d inclusive."
msgstr "Toegangsniveau moet tussen de %d en %d zijn."
@@ -2248,15 +2254,17 @@ msgstr "Toegangslijst voor %s:"
#: modules/commands/help.cpp:166
#, c-format
msgid ""
-"Access to this command requires the permission %s to be present in your opertype."
+"Access to this command requires the permission %s to be present in your "
+"opertype."
msgstr ""
-"Toegang tot dit commando vereist dat het %s recht in jouw opertype aanwezig is."
+"Toegang tot dit commando vereist dat het %s recht in jouw opertype aanwezig "
+"is."
-#: modules/commands/ns_cert.cpp:368 modules/commands/ns_cert.cpp:392
#: modules/commands/ns_identify.cpp:94
#, c-format
msgid ""
-"Account %s has already reached the maximum number of simultaneous logins (%u)."
+"Account %s has already reached the maximum number of simultaneous logins "
+"(%u)."
msgstr ""
"Account %s heeft reeds het maximum aantal gelijktijdige logins bereikt (%u)."
@@ -2264,11 +2272,11 @@ msgstr ""
msgid "Activate security features"
msgstr "Activeer veiligheidsopties"
-#: modules/commands/hs_request.cpp:227
+#: modules/commands/hs_request.cpp:228
msgid "Activate the requested vHost for the given nick."
msgstr "Activeer de aangevraagde vHost voor de opgegeven nick."
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -2289,11 +2297,13 @@ msgid ""
"This will show to opers in the respective info command for\n"
"the nick or channel."
msgstr ""
-"Voeg oper informatie toe of verwijder deze voor de opgegeven nick of kanaal.\n"
-"Dit zal getoond worden aan operators in het respectievelijke INFO commando voor\n"
+"Voeg oper informatie toe of verwijder deze voor de opgegeven nick of "
+"kanaal.\n"
+"Dit zal getoond worden aan operators in het respectievelijke INFO commando "
+"voor\n"
"de nick of het kanaal."
-#: modules/commands/os_dns.cpp:515
+#: modules/commands/os_dns.cpp:514
#, c-format
msgid "Added IP %s to %s."
msgstr "IP-adres %s toegevoegd aan %s."
@@ -2301,7 +2311,7 @@ msgstr "IP-adres %s toegevoegd aan %s."
#: modules/commands/os_forbid.cpp:227
#, c-format
msgid "Added a forbid on %s of type %s to expire on %s."
-msgstr "Verbod toegevoegd op %s van het type %s dat verloopt op %s."
+msgstr "Verbod toegevoegd op %s van het type %s, verloopt op %s."
#: modules/commands/os_info.cpp:164
#, c-format
@@ -2320,12 +2330,12 @@ msgstr "Nieuw operator nieuwsbericht toegevoegd."
msgid "Added new random news item."
msgstr "Nieuw willekeurig nieuwsbericht toegevoegd."
-#: modules/commands/os_dns.cpp:395
+#: modules/commands/os_dns.cpp:394
#, c-format
msgid "Added server %s."
msgstr "Server %s toegevoegd."
-#: modules/commands/os_dns.cpp:300
+#: modules/commands/os_dns.cpp:299
#, c-format
msgid "Added zone %s."
msgstr "Domein %s toegevoegd."
@@ -2335,10 +2345,11 @@ msgid ""
"Adding, deleting, or clearing entry messages requires the\n"
"SET permission."
msgstr ""
-"Toevoegen, verwijderen, of leegmaken van de welkomstberichtenlijst vereist het\n"
+"Toevoegen, verwijderen, of leegmaken van de welkomstberichtenlijst vereist "
+"het\n"
"SET recht."
-#: modules/commands/ns_register.cpp:104
+#: modules/commands/ns_register.cpp:90
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2396,13 +2407,13 @@ msgstr "Alle memo's voor kanaal %s zijn verwijderd."
msgid "All modes cleared on %s."
msgstr "Alle modes verwijderd op %s."
-#: modules/commands/ns_register.cpp:382
+#: modules/commands/ns_register.cpp:368
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
msgstr ""
-"Alle nieuwe accounts moeten gevalideerd worden door een beheerder. Gelieve te "
-"wachten op bevestiging."
+"Alle nieuwe accounts moeten gevalideerd worden door een beheerder. Gelieve "
+"te wachten op bevestiging."
#: modules/commands/ms_del.cpp:111
msgid "All of your memos have been deleted."
@@ -2421,7 +2432,7 @@ msgstr "Alle operators van %s zijn verwijderd."
msgid "All random news items deleted."
msgstr "Alle willekeurige nieuwsberichten zijn verwijderd."
-#: modules/commands/cs_clone.cpp:211
+#: modules/commands/cs_clone.cpp:210
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Alle instellingen van %s zijn gekopiëerd naar %s."
@@ -2433,123 +2444,123 @@ msgstr "Alle gebruikermodes op %s zijn gesynchroniseerd."
#: modules/commands/hs_group.cpp:60
#, c-format
-msgid "All vhosts in the group %s have been set to %s."
-msgstr "Alle vHosts in de groep %s zijn gewijzigd naar %s."
+msgid "All vhost's in the group %s have been set to %s."
+msgstr "Alle vHosts in de groep %s zijn ingesteld op %s."
#: modules/commands/hs_group.cpp:58
#, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
-msgstr "Alle vHosts in de groep %s zijn gewijzigd naar %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
+msgstr "Alle vHosts in de groep %s zijn ingesteld op %s@%s."
-#: src/access.cpp:40
+#: src/access.cpp:41
msgid "Allowed to (de)halfop him/herself"
msgstr "Kan zich/haarzelf (de)halfop'en"
-#: src/access.cpp:39
+#: src/access.cpp:40
msgid "Allowed to (de)halfop users"
msgstr "Kan gebruikers (de)halfop'en"
-#: src/access.cpp:48
+#: src/access.cpp:49
msgid "Allowed to (de)op him/herself"
msgstr "Kan zich/haarzelf (de)op'en"
-#: src/access.cpp:47
+#: src/access.cpp:48
msgid "Allowed to (de)op users"
msgstr "Kan gebruikers (de)op'en"
-#: src/access.cpp:50
+#: src/access.cpp:51
msgid "Allowed to (de)owner him/herself"
msgstr "Kan zich/haarzelf (de)owner'en"
-#: src/access.cpp:49
+#: src/access.cpp:50
msgid "Allowed to (de)owner users"
msgstr "Kan gebruikers (de)owner'en"
-#: src/access.cpp:52
+#: src/access.cpp:53
msgid "Allowed to (de)protect him/herself"
msgstr "Kan zich/haarzelf (de)protect'en"
-#: src/access.cpp:51
+#: src/access.cpp:52
msgid "Allowed to (de)protect users"
msgstr "Kan gebruikers (de)protect'en"
-#: src/access.cpp:59
+#: src/access.cpp:60
msgid "Allowed to (de)voice him/herself"
msgstr "Kan zich/haarzelf (de)voice'en"
-#: src/access.cpp:58
+#: src/access.cpp:59
msgid "Allowed to (de)voice users"
msgstr "Kan gebruikers (de)voice'en"
-#: src/access.cpp:27
+#: src/access.cpp:28
msgid "Allowed to assign/unassign a bot"
msgstr "Kan bots toewijzen/verwijderen"
-#: src/access.cpp:34
+#: src/access.cpp:35
msgid "Allowed to ban users"
msgstr "Kan gebruikers bannen"
-#: src/access.cpp:56
+#: src/access.cpp:57
msgid "Allowed to change channel topics"
msgstr "Kan de topic wijzigen"
-#: src/access.cpp:41
+#: src/access.cpp:42
msgid "Allowed to get full INFO output"
msgstr "Kan de volledige INFO zien"
-#: src/access.cpp:36
+#: src/access.cpp:37
msgid "Allowed to issue commands restricted to channel founders"
msgstr "Kan commando's voorbehouden aan stichters uitvoeren"
-#: src/access.cpp:33
+#: src/access.cpp:34
msgid "Allowed to modify channel badwords list"
msgstr "Kan de slechtewoordenlijst aanpassen"
-#: src/access.cpp:24
+#: src/access.cpp:25
msgid "Allowed to modify the access list"
msgstr "Kan de toegangslijst aanpassen"
-#: src/access.cpp:44
+#: src/access.cpp:45
msgid "Allowed to read channel memos"
msgstr "Kan kanaalmemo's lezen"
-#: src/access.cpp:54
+#: src/access.cpp:55
msgid "Allowed to set channel settings"
msgstr "Kan kanaalinstellingen wijzigen"
-#: src/access.cpp:57
+#: src/access.cpp:58
msgid "Allowed to unban users"
msgstr "Kan bans op gebruikers verwijderen"
-#: src/access.cpp:37
+#: src/access.cpp:38
msgid "Allowed to use GETKEY command"
msgstr "Kan het GETKEY commando gebruiken"
-#: src/access.cpp:53
+#: src/access.cpp:54
msgid "Allowed to use SAY and ACT commands"
msgstr "Kan de SAY en ACT commando's gebruiken"
-#: src/access.cpp:35
+#: src/access.cpp:36
msgid "Allowed to use fantasy commands"
msgstr "Kan fantasie commando's gebruiken"
-#: src/access.cpp:26
+#: src/access.cpp:27
msgid "Allowed to use the AKICK command"
msgstr "Kan het AKICK commando gebruiken"
-#: src/access.cpp:42
+#: src/access.cpp:43
msgid "Allowed to use the INVITE command"
msgstr "Kan het INVITE commando gebruiken"
-#: src/access.cpp:43
+#: src/access.cpp:44
msgid "Allowed to use the KICK command"
msgstr "Kan het KICK commando gebruiken"
-#: src/access.cpp:45
+#: src/access.cpp:46
msgid "Allowed to use the MODE command"
msgstr "Kan het MODE commando gebruiken"
-#: src/access.cpp:25
+#: src/access.cpp:26
msgid "Allowed to view the access list"
msgstr "Kan de toegangslijst bekijken"
@@ -2664,7 +2675,7 @@ msgstr ""
"IRC operators zullen niet genegeerd worden, zelfs al komen\n"
"ze overeen met een masker uit de lijst."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
"a user matching an AKILL mask attempts to connect, Services\n"
@@ -2710,7 +2721,7 @@ msgstr ""
"standaard verlooptijd. De huidige standaard verlooptijd voor een\n"
"AKILL kan gevonden worden met het STATS AKILL commando."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2722,7 +2733,7 @@ msgstr ""
"overeenkomt met een vermelding op de lijst, dan zal Services\n"
"die gebruiker verwijderen."
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
@@ -2801,8 +2812,8 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do not "
-"have\n"
+"topic lock is set, the channel topic will be unchangeable by users who do "
+"not have\n"
"the TOPIC privilege."
msgstr ""
"Maakt het mogelijk de topic van een kanaal aan te passen en te beheren.\n"
@@ -2812,7 +2823,8 @@ msgstr ""
"topic.\n"
" \n"
"LOCK en UNLOCK kunnen gebruikt worden om de topic te vergrendelen\n"
-"of ontgrendelen. Wanneer de topic vergrendeld is kan de topic niet gewijzigd\n"
+"of ontgrendelen. Wanneer de topic vergrendeld is kan de topic niet "
+"gewijzigd\n"
"worden door gebruikers die niet beschikken over het TOPIC privilege."
#: modules/commands/os_kick.cpp:62
@@ -2845,7 +2857,7 @@ msgstr ""
" \n"
"Beschikbare opties:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:249
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -2875,7 +2887,7 @@ msgstr ""
"Voorbeeld:\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:984
+#: modules/commands/ns_set.cpp:975
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2885,7 +2897,7 @@ msgstr ""
"gebruiker stuurt. Als MSG ingesteld is zal Services privé-\n"
"berichten gebruiken, anders zullen ze notice's gebruiken."
-#: modules/commands/ns_set.cpp:958
+#: modules/commands/ns_set.cpp:949
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2955,12 +2967,12 @@ msgstr ""
"bericht (QUIT) verbergen. De tweede parameter geeft aan of\n"
"de informatie moet getoont (OFF) of verborgen (ON) worden."
-#: modules/commands/bs_info.cpp:118
+#: modules/commands/bs_info.cpp:119
#, c-format
msgid "Allows you to see %s information about a channel or a bot"
msgstr "Stelt je in staat %s informatie te zien over een kanaal of bot"
-#: modules/commands/bs_info.cpp:108
+#: modules/commands/bs_info.cpp:109
#, c-format
msgid ""
"Allows you to see %s information about a channel or a bot.\n"
@@ -2983,7 +2995,7 @@ msgstr ""
"Alternatieve methodes voor het beheren en aanpassen\n"
"van de kanaaltoegangslijsten zijn beschikbaar."
-#: modules/commands/hs_request.cpp:191
+#: modules/commands/hs_request.cpp:192
msgid "Approve the requested vHost of a user"
msgstr "Keur de aangevraagde vHost van een gebruiker goed"
@@ -3009,11 +3021,11 @@ msgstr ""
msgid "Associate a URL with the channel"
msgstr "Koppel een URL aan het kanaal"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:592
msgid "Associate a URL with this account"
msgstr "Koppel een URL aan dit account"
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:591
msgid "Associate a URL with your account"
msgstr "Koppel een URL aan jouw account"
@@ -3025,7 +3037,7 @@ msgstr "Koppel een begroeting aan je nick"
msgid "Associate an E-mail address with the channel"
msgstr "Koppel een e-mailadres aan het kanaal"
-#: modules/commands/ns_set.cpp:447
+#: modules/commands/ns_set.cpp:441
msgid "Associate an E-mail address with your nickname"
msgstr "Koppel een e-mailadres aan jouw nick"
@@ -3033,11 +3045,11 @@ msgstr "Koppel een e-mailadres aan jouw nick"
msgid "Associate oper info with a nick or channel"
msgstr "Koppel oper informatie aan een nick of kanaal"
-#: modules/commands/ns_set.cpp:550
+#: modules/commands/ns_set.cpp:544
msgid "Associates the given E-mail address with the nickname."
msgstr "Koppel het opgegeven e-mailadres aan de nick"
-#: modules/commands/ns_set.cpp:525
+#: modules/commands/ns_set.cpp:519
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
@@ -3047,7 +3059,7 @@ msgstr ""
"zal worden weergegeven wanneer iemand informatie over je\n"
"nick opvraagt met het INFO commando."
-#: modules/commands/ns_set.cpp:1306
+#: modules/commands/ns_set.cpp:1297
msgid "Auto-op"
msgstr "Auto-op"
@@ -3056,36 +3068,36 @@ msgstr "Auto-op"
msgid "Autokick list for %s:"
msgstr "Autokicklijst voor %s:"
-#: src/access.cpp:29
+#: src/access.cpp:30
msgid "Automatic channel operator status upon join"
msgstr "Automatische kanaaloperator status bij het betreden"
-#: src/access.cpp:28
+#: src/access.cpp:29
msgid "Automatic halfop upon join"
msgstr "Automatische halfoperator status bij het betreden"
-#: src/access.cpp:30
+#: src/access.cpp:31
msgid "Automatic owner upon join"
msgstr "Automatische eigenaar status bij het betreden"
-#: src/access.cpp:31
+#: src/access.cpp:32
msgid "Automatic protect upon join"
msgstr "Automatische bescherming status bij het betreden"
-#: src/access.cpp:32
+#: src/access.cpp:33
msgid "Automatic voice on join"
msgstr "Automatische voice status bij het betreden"
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:195
#, c-format
msgid "Available commands for %s:"
msgstr "Beschikbare commando's voor %s:"
-#: modules/commands/os_oper.cpp:176
+#: modules/commands/os_oper.cpp:174
msgid "Available opertypes:"
msgstr "Beschikbare opertypes:"
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:217
#, c-format
msgid "Available privileges for %s:"
msgstr "Beschikbare privileges voor %s:"
@@ -3094,8 +3106,8 @@ msgstr "Beschikbare privileges voor %s:"
msgid "BANS enforced by "
msgstr "BANS afgedwongen door "
-#: modules/commands/bs_kick.cpp:1121 modules/commands/bs_kick.cpp:1123
-#: modules/commands/bs_kick.cpp:1126
+#: modules/commands/bs_kick.cpp:1110 modules/commands/bs_kick.cpp:1112
+#: modules/commands/bs_kick.cpp:1115
msgid "Bad words kicker"
msgstr "Slechtewoordenkicker"
@@ -3112,7 +3124,7 @@ msgstr "Slechtewoordenlijst is nu leeg."
msgid "Ban expiry may not be longer than 1 day."
msgstr "Ban verlooptijd mag niet langer dan 1 dag zijn."
-#: modules/commands/cs_ban.cpp:140 modules/commands/cs_ban.cpp:175
+#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
#, c-format
msgid "Ban on %s expires in %s."
msgstr "Ban op %s verloopt over %s."
@@ -3126,11 +3138,11 @@ msgstr "Bantype"
msgid "Ban type for channel %s is now #%d."
msgstr "Ban type voor kanaal %s is nu #%d."
-#: modules/commands/cs_ban.cpp:39
+#: modules/commands/cs_ban.cpp:40
msgid "Bans a given nick or mask on a channel"
msgstr "Ban een opgegeven nick of masker op een kanaal"
-#: modules/commands/cs_ban.cpp:227
+#: modules/commands/cs_ban.cpp:228
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3152,8 +3164,8 @@ msgstr ""
msgid "Bans enforced on %s."
msgstr "Bans afgedwongen op %s."
-#: modules/commands/bs_kick.cpp:1131 modules/commands/bs_kick.cpp:1133
-#: modules/commands/bs_kick.cpp:1136
+#: modules/commands/bs_kick.cpp:1120 modules/commands/bs_kick.cpp:1122
+#: modules/commands/bs_kick.cpp:1125
msgid "Bolds kicker"
msgstr "Vetkicker"
@@ -3162,7 +3174,7 @@ msgstr "Vetkicker"
msgid "Bot %s already exists."
msgstr "Bot %s bestaat al."
-#: include/language.h:119
+#: include/language.h:120
#, c-format
msgid "Bot %s does not exist."
msgstr "Bot %s bestaat niet."
@@ -3187,22 +3199,22 @@ msgstr "Bot %s is verwijderd."
msgid "Bot %s is already assigned to channel %s."
msgstr "Bot %s is al toegewezen aan kanaal %s."
-#: modules/commands/bs_kick.cpp:832
+#: modules/commands/bs_kick.cpp:821
#, c-format
msgid "Bot will kick ops on channel %s."
msgstr "Bot zal ops kicken op kanaal %s."
-#: modules/commands/bs_kick.cpp:897
+#: modules/commands/bs_kick.cpp:886
#, c-format
msgid "Bot will kick voices on channel %s."
msgstr "Bot zal voices kicken op kanaal %s."
-#: modules/commands/bs_kick.cpp:824
+#: modules/commands/bs_kick.cpp:813
#, c-format
msgid "Bot won't kick ops on channel %s."
msgstr "Bot zal geen ops kicken op kanaal %s."
-#: modules/commands/bs_kick.cpp:889
+#: modules/commands/bs_kick.cpp:878
#, c-format
msgid "Bot won't kick voices on channel %s."
msgstr "Bot zal geen voices kicken op kanaal %s."
@@ -3244,7 +3256,7 @@ msgstr "Bot idents mogen maximaal %d karakters bevatten."
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot idents mogen alleen geldige ident-karakters bevatten."
-#: include/language.h:121
+#: include/language.h:122
#, c-format
msgid "Bot is not on channel %s."
msgstr "Bot is niet op kanaal %s."
@@ -3253,7 +3265,7 @@ msgstr "Bot is niet op kanaal %s."
msgid "Bot list:"
msgstr "Botlijst:"
-#: modules/commands/bs_info.cpp:87
+#: modules/commands/bs_info.cpp:88
msgid "Bot nick"
msgstr "Bot nick"
@@ -3266,7 +3278,7 @@ msgstr "Bot nicks mogen maximaal %d karakters bevatten."
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot nicks mogen alleen geldige nick-karakters bevatten."
-#: modules/commands/bs_kick.cpp:225
+#: modules/commands/bs_kick.cpp:227
#, c-format
msgid ""
"Bot will now kick for %s, and will place a ban\n"
@@ -3275,12 +3287,12 @@ msgstr ""
"Bot zal nu kicken voor %s, en zal een ban plaatsen\n"
"na %d kicks op dezelfde gebruiker."
-#: modules/commands/bs_kick.cpp:228
+#: modules/commands/bs_kick.cpp:230
#, c-format
msgid "Bot will now kick for %s."
msgstr "Bot zal nu kicken voor %s."
-#: modules/commands/bs_kick.cpp:416
+#: modules/commands/bs_kick.cpp:418
#, c-format
msgid ""
"Bot will now kick for caps (they must constitute at least\n"
@@ -3291,7 +3303,7 @@ msgstr ""
"%d karakters en %d%% van het gehele bericht), en zal\n"
"een ban plaatsen na %d kicks op dezelfde gebruiker."
-#: modules/commands/bs_kick.cpp:420
+#: modules/commands/bs_kick.cpp:422
#, c-format
msgid ""
"Bot will now kick for caps (they must constitute at least\n"
@@ -3300,7 +3312,7 @@ msgstr ""
"Bot zal nu kicken voor hoofdletters (bij minstens\n"
"%d karakters en %d%% van het gehele bericht)."
-#: modules/commands/bs_kick.cpp:551
+#: modules/commands/bs_kick.cpp:553
#, c-format
msgid ""
"Bot will now kick for flood (%d lines in %d seconds\n"
@@ -3309,69 +3321,49 @@ msgstr ""
"Bot zal nu kicken voor flood (%d regels in %d seconden),\n"
"en zal een ban plaatsen na %d kicks op dezelfde gebruiker."
-#: modules/commands/bs_kick.cpp:554
+#: modules/commands/bs_kick.cpp:556
#, c-format
msgid "Bot will now kick for flood (%d lines in %d seconds)."
msgstr "Bot zal nu kicken voor flood (%d regels in %d seconden)."
-#: modules/commands/bs_kick.cpp:677
-#, c-format
-msgid ""
-"Bot will now kick for repeats (users that repeat the\n"
-"same message %d time), and will place a ban after %d\n"
-"kicks for the same user."
-msgstr ""
-"Bot zal nu kicken voor herhalingen (gebruikers die %d maal\n"
-"hetzelfde herhalen), en zal een ban plaatsen na %d\n"
-"kicks op dezelfde gebruiker."
-
-#: modules/commands/bs_kick.cpp:687
-#, c-format
-msgid ""
-"Bot will now kick for repeats (users that repeat the\n"
-"same message %d time)."
-msgstr ""
-"Bot zal nu kicken voor herhalingen (gebruikers die %d maal\n"
-"hetzelfde herhalen)."
-
#: modules/commands/bs_kick.cpp:673
#, c-format
msgid ""
-"Bot will now kick for repeats (users that repeat the\n"
-"same message %d times), and will place a ban after %d\n"
+"Bot will now kick for repeats (users that say the\n"
+"same thing %d times), and will place a ban after %d\n"
"kicks for the same user."
msgstr ""
"Bot zal nu kicken voor herhalingen (gebruikers die %d maal\n"
-"hetzelfde herhalen), en zal een ban plaatsen na %d\n"
+"hetzelfde zeggen), en zal een ban plaatsen na %d\n"
"kicks op dezelfde gebruiker."
-#: modules/commands/bs_kick.cpp:684
+#: modules/commands/bs_kick.cpp:677
#, c-format
msgid ""
-"Bot will now kick for repeats (users that repeat the\n"
-"same message %d times)."
+"Bot will now kick for repeats (users that say the\n"
+"same thing %d times)."
msgstr ""
"Bot zal nu kicken voor herhalingen (gebruikers die %d maal\n"
-"hetzelfde herhalen)."
+"hetzelfde zeggen)."
-#: modules/commands/bs_kick.cpp:239
+#: modules/commands/bs_kick.cpp:241
#, c-format
msgid "Bot won't kick for %s anymore."
msgstr "Bot zal niet meer kicken voor %s."
-#: modules/commands/bs_kick.cpp:426
+#: modules/commands/bs_kick.cpp:428
msgid "Bot won't kick for caps anymore."
msgstr "Bot zal niet meer kicken voor hoofdletters."
-#: modules/commands/bs_kick.cpp:559
+#: modules/commands/bs_kick.cpp:561
msgid "Bot won't kick for flood anymore."
msgstr "Bot zal niet meer kicken voor flood."
-#: modules/commands/bs_kick.cpp:694
+#: modules/commands/bs_kick.cpp:683
msgid "Bot won't kick for repeats anymore."
msgstr "Bot zal niet meer kicken voor herhalingen."
-#: modules/commands/cs_access.cpp:472 modules/commands/os_sxline.cpp:201
+#: modules/commands/cs_access.cpp:472 modules/commands/os_sxline.cpp:199
#: modules/commands/os_session.cpp:514
msgid "By"
msgstr "Door"
@@ -3380,7 +3372,7 @@ msgstr "Door"
msgid "CLEAR target"
msgstr "CLEAR doel"
-#: modules/commands/cs_seen.cpp:119
+#: modules/commands/cs_seen.cpp:120
msgid "CLEAR time"
msgstr "CLEAR tijd"
@@ -3410,12 +3402,12 @@ msgstr ""
msgid "Cannot clone channel %s to itself!"
msgstr "Kan kanaal %s niet naar zichzelf clonen!"
-#: modules/commands/ns_register.cpp:325
+#: modules/commands/ns_register.cpp:311
msgid "Cannot send mail now; please retry a little later."
msgstr "Onmogelijk e-mail te sturen; probeer later opnieuw."
-#: modules/commands/bs_kick.cpp:1141 modules/commands/bs_kick.cpp:1143
-#: modules/commands/bs_kick.cpp:1146
+#: modules/commands/bs_kick.cpp:1130 modules/commands/bs_kick.cpp:1132
+#: modules/commands/bs_kick.cpp:1135
msgid "Caps kicker"
msgstr "Hoofdletterskicker"
@@ -3476,7 +3468,7 @@ msgstr "ChanServ is vereist om PERSIST te activeren op dit netwerk."
msgid "Change channel modes"
msgstr "Wijzig kanaalmodes"
-#: modules/commands/ns_set.cpp:897
+#: modules/commands/ns_set.cpp:888
msgid "Change the communication method of Services"
msgstr "Verander de communicatiemethode van Services"
@@ -3489,7 +3481,7 @@ msgstr "Wijzig gebruikersmodes"
msgid "Changed usermodes of %s to %s."
msgstr "Gebruikersmodes van %s veranderd naar %s."
-#: modules/commands/ns_set.cpp:408
+#: modules/commands/ns_set.cpp:402
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3497,7 +3489,7 @@ msgstr ""
"Verandert de weergegeven nick van de nick-groep in Services.\n"
"De nieuwe weergave MOET een nick in de groep zijn."
-#: modules/commands/ns_set.cpp:384
+#: modules/commands/ns_set.cpp:378
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3513,7 +3505,7 @@ msgstr ""
"Verandert de stichter van een kanaal. De nieuwe nick moet\n"
"een geregistreerde nick zijn."
-#: modules/commands/ns_set.cpp:876
+#: modules/commands/ns_set.cpp:867
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3525,7 +3517,7 @@ msgstr ""
"op een commando dat werd verzonden). taal moet gekozen\n"
"worden uit de volgende lijst van ondersteunde talen:"
-#: modules/commands/ns_set.cpp:840
+#: modules/commands/ns_set.cpp:831
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3551,7 +3543,7 @@ msgstr ""
"Verandert het wachtwoord dat je gebruikt om je te identificeren\n"
"als de eigenaar van de nick."
-#: modules/commands/cs_set.cpp:1028
+#: modules/commands/cs_set.cpp:1029
msgid ""
"Changes the successor of a channel. If the founder's\n"
"nickname expires or is dropped while the channel is still\n"
@@ -3568,7 +3560,7 @@ msgstr ""
msgid "Channel"
msgstr "Kanaal"
-#: include/language.h:84
+#: include/language.h:85
#, c-format
msgid "Channel %s doesn't exist."
msgstr "Kanaal %s bestaat niet."
@@ -3618,7 +3610,7 @@ msgstr "Kanaal %s is weer vrijgegeven."
msgid "Channel %s is now suspended."
msgstr "Kanaal %s is nu geschorst."
-#: include/language.h:83
+#: include/language.h:84
#, c-format
msgid "Channel %s isn't registered."
msgstr "Kanaal %s is niet geregistreerd."
@@ -3633,12 +3625,12 @@ msgstr "Kanaal %s is niet geschorst."
msgid "Channel %s registered under your account: %s"
msgstr "Kanaal %s is nu geregistreerd op jouw account: %s"
-#: modules/commands/cs_set.cpp:1081
+#: modules/commands/cs_set.cpp:1082
#, c-format
msgid "Channel %s will expire."
msgstr "Kanaal %s zal verlopen."
-#: modules/commands/cs_set.cpp:1075
+#: modules/commands/cs_set.cpp:1076
#, c-format
msgid "Channel %s will not expire."
msgstr "Kanaal %s zal niet verlopen."
@@ -3663,19 +3655,19 @@ msgstr "Kanaal %s autokicklijst is leeggemaakt."
msgid "Channel %s has no mode locks."
msgstr "Kanaal %s heeft geen vergrendelde modes."
-#: include/language.h:82
+#: include/language.h:83
#, c-format
msgid "Channel %s is currently suspended."
msgstr "Kanaal %s is momenteel geschorst."
-#: include/language.h:101
+#: include/language.h:102
#, c-format
msgid "Channel %s is not a valid channel."
msgstr "Kanaal %s is geen geldig kanaal."
#: modules/commands/os_list.cpp:67
msgid "Channel list:"
-msgstr "Kanalenlijst:"
+msgstr "Kanaallijst:"
#: modules/extra/stats/cs_fantasy_stats.cpp:148
#, c-format
@@ -3687,7 +3679,7 @@ msgstr "Kanaalstatistieken voor %s op %s:"
msgid "Channels may not be on access lists."
msgstr "Kanalen mogen niet op de toegangslijst staan."
-#: modules/commands/ns_alist.cpp:114
+#: modules/commands/ns_alist.cpp:105
#, c-format
msgid "Channels that %s has access on:"
msgstr "Kanalen waar %s toegang op heeft:"
@@ -3697,7 +3689,8 @@ msgstr "Kanalen waar %s toegang op heeft:"
msgid "Channels: %lu entries, %lu buckets, longest chain is %d"
msgstr "Kanalen: %lu vermeldingen, %lu emmers, langste ketting is %d"
-#: modules/extra/stats/m_chanstats.cpp:509 modules/extra/stats/m_chanstats.cpp:517
+#: modules/extra/stats/m_chanstats.cpp:509
+#: modules/extra/stats/m_chanstats.cpp:517
msgid "Chanstats"
msgstr "Kanaalstatistieken"
@@ -3727,7 +3720,7 @@ msgstr "Chanstats statistieken zijn nu ingeschakeld voor dit kanaal."
msgid "Chanstats statistics are now enabled for your nick."
msgstr "Chanstats statistieken zijn nu ingeschakeld voor jouw nick."
-#: modules/commands/cs_seen.cpp:366
+#: modules/commands/cs_seen.cpp:362
msgid ""
"Checks for the last time nick was seen joining, leaving,\n"
"or changing nick on the network and tells you when and, depending\n"
@@ -3756,8 +3749,8 @@ msgstr ""
msgid "Cleared info from %s."
msgstr "Informatie verwijderd van %s."
-#: modules/commands/bs_kick.cpp:1151 modules/commands/bs_kick.cpp:1153
-#: modules/commands/bs_kick.cpp:1156
+#: modules/commands/bs_kick.cpp:1140 modules/commands/bs_kick.cpp:1142
+#: modules/commands/bs_kick.cpp:1145
msgid "Colors kicker"
msgstr "Kleurenkicker"
@@ -3765,19 +3758,19 @@ msgstr "Kleurenkicker"
msgid "Command"
msgstr "Commando"
-#: modules/commands/bs_kick.cpp:251
+#: modules/commands/bs_kick.cpp:253
msgid "Configures AMSG kicker"
msgstr "Configureert AMSG-kicker"
-#: modules/commands/bs_kick.cpp:287
+#: modules/commands/bs_kick.cpp:289
msgid "Configures badwords kicker"
msgstr "Configureert slechtewoordenkicker"
-#: modules/commands/bs_kick.cpp:326
+#: modules/commands/bs_kick.cpp:328
msgid "Configures bolds kicker"
msgstr "Configureert vetkicker"
-#: modules/commands/bs_kick.cpp:132
+#: modules/commands/bs_kick.cpp:134
msgid "Configures bot kickers. option can be one of:"
msgstr "Configureert bot kickers. optie kan zijn:"
@@ -3795,7 +3788,7 @@ msgstr ""
" \n"
"Beschikbare opties:"
-#: modules/commands/bs_kick.cpp:360
+#: modules/commands/bs_kick.cpp:362
msgid "Configures caps kicker"
msgstr "Configureert hoofdletterskicker"
@@ -3803,27 +3796,27 @@ msgstr "Configureert hoofdletterskicker"
msgid "Configures channel logging settings"
msgstr "Configureert kanaal log instellingen"
-#: modules/commands/bs_kick.cpp:456
+#: modules/commands/bs_kick.cpp:458
msgid "Configures color kicker"
msgstr "Configureert kleurenkicker"
-#: modules/commands/bs_kick.cpp:490
+#: modules/commands/bs_kick.cpp:492
msgid "Configures flood kicker"
msgstr "Configureert floodkicker"
-#: modules/commands/bs_kick.cpp:588
+#: modules/commands/bs_kick.cpp:590
msgid "Configures italics kicker"
msgstr "Configureert cursiefkicker"
-#: modules/commands/bs_kick.cpp:119
+#: modules/commands/bs_kick.cpp:121
msgid "Configures kickers"
msgstr "Configureert kickers"
-#: modules/commands/bs_kick.cpp:622
+#: modules/commands/bs_kick.cpp:624
msgid "Configures repeat kicker"
msgstr "Configureert herhalingskicker"
-#: modules/commands/bs_kick.cpp:723
+#: modules/commands/bs_kick.cpp:712
msgid "Configures reverses kicker"
msgstr "Configureert inverteringskicker"
@@ -3831,7 +3824,7 @@ msgstr "Configureert inverteringskicker"
msgid "Configures the time bot bans expire in"
msgstr "Configureert wanneer bot bans verlopen"
-#: modules/commands/bs_kick.cpp:757
+#: modules/commands/bs_kick.cpp:746
msgid "Configures underlines kicker"
msgstr "Configureert onderlijningskicker"
@@ -3844,12 +3837,13 @@ msgid "Control modes and mode locks on a channel"
msgstr "Beheer modes en vergrendelde modes op een kanaal"
#: modules/commands/cs_entrymsg.cpp:239
-msgid "Controls what messages will be sent to users when they join the channel."
+msgid ""
+"Controls what messages will be sent to users when they join the channel."
msgstr ""
-"Beheer welke berichten verstuurd worden naar gebruikers wanneer ze het kanaal "
-"betreden."
+"Beheer welke berichten verstuurd worden naar gebruikers wanneer ze het "
+"kanaal betreden."
-#: modules/commands/cs_clone.cpp:242
+#: modules/commands/cs_clone.cpp:241
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
@@ -3867,10 +3861,10 @@ msgstr "Kopiëer alle instellingen van het ene kanaal naar het andere"
#: modules/commands/hs_list.cpp:58 modules/commands/cs_flags.cpp:301
#: modules/commands/cs_mode.cpp:434 modules/commands/cs_entrymsg.cpp:116
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_news.cpp:156
-#: modules/commands/hs_request.cpp:305 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_session.cpp:514 modules/commands/bs_info.cpp:57
-#: modules/commands/os_akill.cpp:358
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_news.cpp:156
+#: modules/commands/hs_request.cpp:306 modules/commands/cs_akick.cpp:380
+#: modules/commands/os_session.cpp:514 modules/commands/bs_info.cpp:58
+#: modules/commands/os_akill.cpp:355
msgid "Created"
msgstr "Gemaakt"
@@ -3878,16 +3872,16 @@ msgstr "Gemaakt"
#: modules/commands/cs_mode.cpp:434 modules/commands/cs_entrymsg.cpp:116
#: modules/commands/os_ignore.cpp:266 modules/commands/os_forbid.cpp:346
#: modules/commands/os_news.cpp:156 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_akill.cpp:358
+#: modules/commands/os_akill.cpp:355
msgid "Creator"
msgstr "Door"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, c-format
msgid "Current %s list:"
msgstr "Huidige %s lijst:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
msgid "Current AKILL list:"
msgstr "Huidige AKILL lijst:"
@@ -3939,8 +3933,8 @@ msgstr "DEL [nick] vingerafdruk"
msgid "DEL [nickname] mask"
msgstr "DEL [nick] masker"
-#: modules/commands/os_sxline.cpp:426 modules/commands/os_sxline.cpp:660
-#: modules/commands/os_akill.cpp:387
+#: modules/commands/os_sxline.cpp:419 modules/commands/os_sxline.cpp:652
+#: modules/commands/os_akill.cpp:381
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {masker | nr | lijst | id}"
@@ -3950,7 +3944,7 @@ msgstr "DEL {masker | nr | lijst}"
#: modules/commands/os_ignore.cpp:343
msgid "DEL {nick|mask}"
-msgstr "DEL {nickname|masker}"
+msgstr "DEL {nick|masker}"
#: modules/commands/os_news.cpp:279
msgid "DEL {num | ALL}"
@@ -3960,23 +3954,23 @@ msgstr "DEL {nr | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} vermelding"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "DELIP server.name ip"
msgstr "DELIP server.naam ip"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "DELSERVER server.name [zone.name]"
msgstr "DELSERVER server.naam [domein.naam]"
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "DELZONE zone.name"
msgstr "DELZONE domein.naam"
-#: modules/commands/os_dns.cpp:669
+#: modules/commands/os_dns.cpp:668
msgid "DEPOOL server.name"
msgstr "DEPOOL server.naam"
-#: modules/commands/cs_seen.cpp:162
+#: modules/commands/cs_seen.cpp:163
#, c-format
msgid "Database cleared, removed %lu nicks that were added after %s."
msgstr "Database opgekuist, %lu nicks verwijderd die werden toegevoegd na %s."
@@ -3985,7 +3979,7 @@ msgstr "Database opgekuist, %lu nicks verwijderd die werden toegevoegd na %s."
msgid "Date/Time"
msgstr "Datum/Tijd"
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:46
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4095,7 +4089,8 @@ msgstr "Standaard SQLINE verlooptijd: Verloopt niet"
#: modules/commands/os_news.cpp:351
msgid "Define messages to be randomly shown to users at logon"
-msgstr "Stel de berichten in die gebruikers willekeurig krijgen als ze verbinden"
+msgstr ""
+"Stel de berichten in die gebruikers willekeurig krijgen als ze verbinden"
#: modules/commands/os_news.cpp:297
msgid "Define messages to be shown to users at logon"
@@ -4103,7 +4098,8 @@ msgstr "Stel de berichten in die gebruikers krijgen als ze verbinden"
#: modules/commands/os_news.cpp:324
msgid "Define messages to be shown to users who oper"
-msgstr "Stel de berichten in die gebruikers te zien krijgen wanneer ze OPER worden"
+msgstr ""
+"Stel de berichten in die gebruikers te zien krijgen wanneer ze OPER worden"
#: modules/commands/ms_del.cpp:41
msgid "Delete a memo or memos"
@@ -4136,7 +4132,8 @@ msgstr "%d vermeldingen verwijderd van %s slechtewoordenlijst."
#: modules/commands/os_session.cpp:149
#, c-format
msgid "Deleted %d entries from session-limit exception list."
-msgstr "%d vermeldingen verwijderd van de uitzonderingenlijst voor sessielimieten."
+msgstr ""
+"%d vermeldingen verwijderd van de uitzonderingenlijst voor sessielimieten."
#: modules/commands/os_sxline.cpp:32
#, c-format
@@ -4165,7 +4162,8 @@ msgstr "1 vermelding verwijderd van %s slechtewoordenlijst."
#: modules/commands/os_session.cpp:147
msgid "Deleted 1 entry from session-limit exception list."
-msgstr "1 vermelding verwijderd van de uitzonderingenlijst voor sessielimieten."
+msgstr ""
+"1 vermelding verwijderd van de uitzonderingenlijst voor sessielimieten."
#: modules/commands/os_sxline.cpp:30
#, c-format
@@ -4238,7 +4236,7 @@ msgstr ""
"Verwijdert de vHost voor alle nicks in dezelfde groep\n"
"als de opgegeven nick."
-#: modules/commands/os_dns.cpp:653
+#: modules/commands/os_dns.cpp:652
#, c-format
msgid "Depooled %s."
msgstr "Depooled %s."
@@ -4258,7 +4256,7 @@ msgstr "Beschrijving van %s veranderd naar %s."
msgid "Description of %s unset."
msgstr "Beschrijving van %s verwijderd."
-#: modules/commands/bs_kick.cpp:1115 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
msgid "Disabled"
msgstr "Uitgeschakeld"
@@ -4282,7 +4280,7 @@ msgstr ""
" \n"
"Op sommige netwerken is een reden verplicht."
-#: modules/commands/hs_request.cpp:337
+#: modules/commands/hs_request.cpp:338
#, c-format
msgid "Displayed %d records (%d total)."
msgstr "%d resultaten getoond (%d in totaal)."
@@ -4356,32 +4354,32 @@ msgstr "Toont jouw kanaalstatistieken"
msgid "Displays your Global Stats"
msgstr "Toont jouw globale statistieken"
-#: modules/commands/bs_kick.cpp:1463
+#: modules/commands/bs_kick.cpp:1452
msgid "Don't use AMSGs!"
msgstr "Geen AMSG gebruiken!"
-#: modules/commands/bs_kick.cpp:1266
+#: modules/commands/bs_kick.cpp:1255
msgid "Don't use bolds on this channel!"
msgstr "Gebruik geen vette karakters in dit kanaal!"
-#: modules/commands/bs_kick.cpp:1274
+#: modules/commands/bs_kick.cpp:1263
msgid "Don't use colors on this channel!"
msgstr "Gebruik geen kleuren in dit kanaal!"
-#: modules/commands/bs_kick.cpp:1290
+#: modules/commands/bs_kick.cpp:1279
msgid "Don't use italics on this channel!"
msgstr "Gebruik geen cursief in dit kanaal!"
-#: modules/commands/bs_kick.cpp:1282
+#: modules/commands/bs_kick.cpp:1271
msgid "Don't use reverses on this channel!"
msgstr "Gebruik geen inverteringen in dit kanaal!"
-#: modules/commands/bs_kick.cpp:1408
+#: modules/commands/bs_kick.cpp:1397
#, c-format
msgid "Don't use the word \"%s\" on this channel!"
msgstr "Het woord \"%s\" niet in dit kanaal gebruiken!"
-#: modules/commands/bs_kick.cpp:1298
+#: modules/commands/bs_kick.cpp:1287
msgid "Don't use underlines on this channel!"
msgstr "Gebruik geen onderlijningen in dit kanaal!"
@@ -4396,17 +4394,17 @@ msgstr ""
"is kan je al je toegangen en kanalen verliezen dat u bezit.\n"
"Iedereen kan dan deze nick opnieuw registreren."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:499
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mailadres voor %s gewijzigd naar %s."
-#: modules/commands/ns_set.cpp:511
+#: modules/commands/ns_set.cpp:505
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mailadres voor %s verwijderd."
-#: src/mail.cpp:79
+#: src/mail.cpp:80
#, c-format
msgid "E-mail for %s is invalid."
msgstr "E-mail voor %s is ongeldig."
@@ -4461,8 +4459,8 @@ msgstr "E-mailadres"
#: modules/commands/ns_getemail.cpp:41
#, c-format
-msgid "Email matched: %s (%s) to %s."
-msgstr "E-mail overeenkomst: %s (%s) met %s."
+msgid "Email matched: %s to %s."
+msgstr "E-mail %s komt overeen met %s."
#: modules/fantasy.cpp:19
msgid "Enable fantaisist commands"
@@ -4472,11 +4470,11 @@ msgstr "Activeer fantasie commando's"
msgid "Enable greet messages"
msgstr "Activeer begroetingen"
-#: modules/commands/ns_set.cpp:560
+#: modules/commands/ns_set.cpp:554
msgid "Enable or disable keep modes"
msgstr "Activeer of deactiveer KEEPMODES"
-#: modules/commands/bs_kick.cpp:1114 modules/commands/bs_info.cpp:89
+#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
msgid "Enabled"
msgstr "Ingeschakeld"
@@ -4502,7 +4500,7 @@ msgstr ""
"onthouden en pogen deze terug te zetten wanneer het kanaal\n"
"de volgende keer weer aangemaakt wordt."
-#: modules/commands/ns_set.cpp:635
+#: modules/commands/ns_set.cpp:629
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4513,7 +4511,7 @@ msgstr ""
"onthouden en pogen deze terug te zetten wanneer ze de\n"
"volgende keer identificeren."
-#: modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:604
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4525,19 +4523,21 @@ msgstr ""
"volgende keer identificeert."
#: modules/commands/cs_set.cpp:744
+#, c-format
msgid ""
"Enables or disables security features for a\n"
-"channel. When SECURE is set, only users who have\n"
-"identified to services, and are not only recognized, will be\n"
-"given access to channels from account-based access entries."
+"channel. When %s 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."
msgstr ""
"Zet veiligheidsfuncties aan of uit voor een kanaal.\n"
-"Wanneer SECURE aan staat zullen alleen gebruikers die\n"
-"geïdentificeerd zijn, en niet enkel herkend, toegang\n"
-"krijgen tot kanalen vanaf account-gebaseerde\n"
-"toegangsvermeldingen."
+"Wanneer %s aan staat zullen alleen gebruikers die\n"
+"hun nicks geregistreerd hebben en geïdentificeerd zijn\n"
+"met hun wachtwoord toegang krijgen tot het kanaal,\n"
+"zoals geregeld door de toegangslijst."
-#: modules/commands/cs_set.cpp:943
+#: modules/commands/cs_set.cpp:944
msgid ""
"Enables or disables signed kicks for a\n"
"channel. When SIGNKICK is set, kicks issued with\n"
@@ -4586,7 +4586,7 @@ msgstr ""
"die niet op de toegangslijst staan gekickt en gebant worden van het\n"
"kanaal."
-#: modules/commands/cs_set.cpp:807
+#: modules/commands/cs_set.cpp:808
msgid ""
"Enables or disables the secure founder option for a channel.\n"
"When secure founder is set, only the real founder will be\n"
@@ -4600,7 +4600,7 @@ msgstr ""
"opvolger veranderen, en niet diegenen die stichter-toegang\n"
"hebben."
-#: modules/commands/cs_set.cpp:871
+#: modules/commands/cs_set.cpp:872
msgid ""
"Enables or disables the secure ops option for a channel.\n"
"When secure ops is set, users who are not on the access list\n"
@@ -4670,7 +4670,7 @@ msgstr ""
"Bovendien zullen Services deze kanaalmode instellen of\n"
"verwijderen wanneer je PERSIST aan of uit zet."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
msgid "End of AKILL list."
msgstr "Einde van AKILL lijst."
@@ -4716,7 +4716,7 @@ msgstr "Einde van verbodslijst - %d/%d resultaten weergegeven."
msgid "End of forbid list."
msgstr "Einde van verbodslijst."
-#: modules/commands/ns_alist.cpp:119
+#: modules/commands/ns_alist.cpp:110
#, c-format
msgid "End of list - %d channels shown."
msgstr "Einde van lijst - %d kanalen weergegeven."
@@ -4763,14 +4763,16 @@ msgstr ""
"Gebruik SECUREOPS om de SECUREOPS optie af te dwingen, zelfs\n"
"als deze niet geactiveerd is. Gebruik RESTRICTED om de RESTRICTED\n"
"optie af te dwingen, ook wanneer deze niet geactiveerd is. Gebruik REGONLY\n"
-"om alle ongeregistreerde gebruikers te kicken van het kanaal. Gebruik SSLONLY\n"
-"om alle gebruikers die geen veilige/versleutelde verbinding gebruiken te kicken\n"
+"om alle ongeregistreerde gebruikers te kicken van het kanaal. Gebruik "
+"SSLONLY\n"
+"om alle gebruikers die geen veilige/versleutelde verbinding gebruiken te "
+"kicken\n"
"van het kanaal. BANS zal actieve bans afdwingen door gebruikers te kicken\n"
"die ermee overeenstemmen, en LIMIT zal gebruikers kicken tot het\n"
"gebruikersaantal onder de kanaallimiet zakt, indien ingesteld."
-#: src/language.cpp:43 modules/commands/ns_set.cpp:828
-#: modules/commands/ns_set.cpp:848 modules/commands/ns_set.cpp:883
+#: src/language.cpp:44 modules/commands/ns_set.cpp:839
+#: modules/commands/ns_set.cpp:874
msgid "English"
msgstr "Nederlands"
@@ -4809,21 +4811,23 @@ msgstr "Alle welkomstberichten voor %s zijn verwijderd."
msgid "Error reloading configuration file: %s"
msgstr "Fout bij laden configuratiebestand: %s"
-#: include/language.h:125
+#: include/language.h:126
#, c-format
msgid ""
"Error! The vHost ident is too long, please use an ident shorter than %d "
"characters."
msgstr ""
-"Fout! De vHost ident is te lang, gelieve een ident korter dan %d karakters op te "
-"geven."
+"Fout! De vHost ident is te lang, gelieve een ident korter dan %d karakters "
+"op te geven."
-#: include/language.h:124
+#: include/language.h:125
#, c-format
msgid ""
-"Error! The vHost is too long, please use a hostname shorter than %d characters."
+"Error! The vHost is too long, please use a hostname shorter than %d "
+"characters."
msgstr ""
-"Fout! De vHost is te lang, gelieve een host korter dan %d karakters op te geven."
+"Fout! De vHost is te lang, gelieve een host korter dan %d karakters op te "
+"geven."
#: modules/commands/ns_cert.cpp:325
msgid ""
@@ -4858,20 +4862,21 @@ msgstr ""
msgid "Exception for %s has been updated to %d."
msgstr "Uitzondering voor %s is geüpdatet naar %d."
-#: modules/pseudoclients/chanserv.cpp:463 modules/pseudoclients/nickserv.cpp:564
+#: modules/pseudoclients/chanserv.cpp:456
+#: modules/pseudoclients/nickserv.cpp:564
#: modules/pseudoclients/nickserv.cpp:569 modules/commands/os_ignore.cpp:266
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
#: modules/commands/os_session.cpp:514 modules/commands/ns_group.cpp:315
-#: modules/commands/os_akill.cpp:358
+#: modules/commands/os_akill.cpp:355
msgid "Expires"
msgstr "Verloopt"
-#: src/xline.cpp:397
+#: src/xline.cpp:368
#, c-format
msgid "Expiry and reason updated for %s."
msgstr "Verlooptijd en reden voor %s geüpdatet."
-#: src/xline.cpp:400
+#: src/xline.cpp:371
#, c-format
msgid "Expiry for %s updated."
msgstr "Verlooptijd voor %s geüpdatet."
@@ -4918,8 +4923,8 @@ msgstr "Vlaggen voor %s op %s gewijzigd naar +%s"
msgid "Flags list for %s"
msgstr "Vlaggenlijst voor %s"
-#: modules/commands/bs_kick.cpp:1161 modules/commands/bs_kick.cpp:1163
-#: modules/commands/bs_kick.cpp:1166
+#: modules/commands/bs_kick.cpp:1150 modules/commands/bs_kick.cpp:1152
+#: modules/commands/bs_kick.cpp:1155
msgid "Flood kicker"
msgstr "Floodkicker"
@@ -4989,7 +4994,7 @@ msgstr "Stichter van %s veranderd naar %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "GETPASS commando is onbeschikbaar omdat encryptie aanstaat."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Ghost met jouw nick is gekilld."
@@ -5015,7 +5020,7 @@ msgstr "Geeft jou of een gegeven nick %s status op een kanaal"
msgid "Greet"
msgstr "Begroeting"
-#: src/access.cpp:38
+#: src/access.cpp:39
msgid "Greet message displayed on join"
msgstr "Begroetingsbericht getoond bij betreden"
@@ -5060,7 +5065,7 @@ msgstr "Host"
msgid "Hosts with at least %d sessions:"
msgstr "Hosts met tenminste %d sessies:"
-#: modules/commands/cs_set.cpp:1034
+#: modules/commands/cs_set.cpp:1035
#, c-format
msgid ""
"However, if the successor already has too many\n"
@@ -5071,34 +5076,30 @@ msgstr ""
"heeft (%d), dan zal het kanaal verwijderd worden, net\n"
"alsof er geen opvolger ingesteld staat."
-#: modules/commands/cs_seen.cpp:207
+#: modules/commands/cs_seen.cpp:208
#, c-format
msgid "I don't know who %s is."
msgstr "Ik weet niet wie %s is."
-#: modules/commands/cs_seen.cpp:253
+#: modules/commands/cs_seen.cpp:249
#, c-format
msgid "I've never seen %s on this channel."
msgstr "Ik heb %s nooit gezien op dit kanaal."
-#: modules/commands/os_sxline.cpp:203 modules/commands/os_akill.cpp:360
-msgid "ID"
-msgstr "ID"
-
#: modules/commands/os_oper.cpp:72
msgid "INFO [type]"
msgstr "INFO [type]"
-#: modules/commands/os_dns.cpp:218
+#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr "IP"
-#: modules/commands/os_dns.cpp:500
+#: modules/commands/os_dns.cpp:499
#, c-format
msgid "IP %s already exists for %s."
msgstr "IP %s bestaat al voor %s."
-#: modules/commands/os_dns.cpp:562
+#: modules/commands/os_dns.cpp:561
#, c-format
msgid "IP %s does not exist for %s."
msgstr "IP %s bestaat niet voor %s."
@@ -5107,7 +5108,8 @@ msgstr "IP %s bestaat niet voor %s."
msgid "Identify yourself with your password"
msgstr "Identificeer jezelf met je wachtwoord"
-#: modules/pseudoclients/nickserv.cpp:205 modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:205
+#: modules/pseudoclients/nickserv.cpp:211
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Als je niet binnen %s je nick verandert, verander ik je nick."
@@ -5124,7 +5126,7 @@ msgstr "Negeerlijst is leeg."
msgid "Ignore list:"
msgstr "Negeerlijst:"
-#: modules/commands/ns_set.cpp:1296
+#: modules/commands/ns_set.cpp:1287
msgid "Immediate protection"
msgstr "Onmiddellijke berscherming"
@@ -5132,7 +5134,7 @@ msgstr "Onmiddellijke berscherming"
msgid "Incorrect email address."
msgstr "Onjuist e-mailadres."
-#: include/language.h:89
+#: include/language.h:90
msgid "Incorrect range specified. The correct syntax is #from-to."
msgstr "Ongeldig bereik. De correcte syntax is #van-naar."
@@ -5140,12 +5142,12 @@ msgstr "Ongeldig bereik. De correcte syntax is #van-naar."
msgid "Info about a loaded module"
msgstr "Info over een geladen module"
-#: modules/commands/bs_info.cpp:54
+#: modules/commands/bs_info.cpp:55
#, c-format
msgid "Information for bot %s:"
msgstr "Informatie voor bot %s:"
-#: include/language.h:108
+#: include/language.h:109
#, c-format
msgid "Information for channel %s:"
msgstr "Informatie voor kanaal %s:"
@@ -5155,47 +5157,48 @@ msgstr "Informatie voor kanaal %s:"
msgid "Invalid duration %s, using %d days."
msgstr "Ongeldige duratie %s, teruggevallen op %d dagen."
-#: include/language.h:68
+#: include/language.h:69
msgid "Invalid expiry time."
msgstr "Ongeldige verlooptijd."
#: modules/commands/os_session.cpp:346
msgid ""
-"Invalid hostmask. Only real hostmasks are valid, as exceptions are not matched "
-"against nicks or usernames."
+"Invalid hostmask. Only real hostmasks are valid, as exceptions are not "
+"matched against nicks or usernames."
msgstr ""
-"Ongeldig hostmasker. Alleen echte hostmaskers zijn geldig als uitzondering omdat "
-"deze niet worden vergeleken met nicks of idents."
+"Ongeldig hostmasker. Alleen echte hostmaskers zijn geldig als uitzondering "
+"omdat deze niet worden vergeleken met nicks of idents."
#: modules/commands/os_logsearch.cpp:71
#, c-format
msgid "Invalid limit %s, using %d."
msgstr "Ongeldig limiet %s, teruggevallen op %d."
-#: include/language.h:99
-msgid "Invalid passcode has been entered, please check the e-mail again, and retry."
+#: include/language.h:100
+msgid ""
+"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-"Ongeldige bevestigingscode, gelieve de e-mail opnieuw te controleren en nog eens "
-"te proberen."
+"Ongeldige bevestigingscode, gelieve de e-mail opnieuw te controleren en nog "
+"eens te proberen."
-#: modules/commands/ns_register.cpp:83 modules/commands/ns_register.cpp:86
+#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
msgid "Invalid passcode."
msgstr "Ongeldige bevestigingscode."
#: modules/commands/os_session.cpp:339
#, c-format
msgid ""
-"Invalid session limit. It must be a valid integer greater than or equal to zero "
-"and less than %d."
+"Invalid session limit. It must be a valid integer greater than or equal to "
+"zero and less than %d."
msgstr ""
-"Ongeldige sessielimiet. Het moet een geldig getal groter dan, of gelijk aan nul, "
-"en kleiner dan %d zijn."
+"Ongeldige sessielimiet. Het moet een geldig getal groter dan, of gelijk aan "
+"nul, en kleiner dan %d zijn."
#: modules/commands/os_session.cpp:188
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Ongeldige drempel waarde. Het moet een geldig getal groter dan 1 zijn."
-#: modules/commands/os_dns.cpp:591
+#: modules/commands/os_dns.cpp:590
msgid "Invalid value for LIMIT. Must be numerical."
msgstr "Ongeldige waarde voor LIMIT. Moet numeriek zijn."
@@ -5203,8 +5206,8 @@ msgstr "Ongeldige waarde voor LIMIT. Moet numeriek zijn."
msgid "Invites you or an optionally specified nick into a channel"
msgstr "Nodigt jou of een optionele nick naar een kanaal uit"
-#: modules/commands/bs_kick.cpp:1201 modules/commands/bs_kick.cpp:1203
-#: modules/commands/bs_kick.cpp:1206
+#: modules/commands/bs_kick.cpp:1190 modules/commands/bs_kick.cpp:1192
+#: modules/commands/bs_kick.cpp:1195
msgid "Italics kicker"
msgstr "Cursiefkicker"
@@ -5212,16 +5215,16 @@ msgstr "Cursiefkicker"
msgid "Join a group"
msgstr "Bij een groep aanmelden"
-#: modules/commands/cs_set.cpp:1350 modules/commands/ns_set.cpp:1310
+#: modules/commands/cs_set.cpp:1351 modules/commands/ns_set.cpp:1301
msgid "Keep modes"
msgstr "Behoud modes"
-#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:595
+#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:589
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Modes behouden voor %s is nu uit."
-#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:589
+#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:583
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Modes behouden voor %s is nu aan."
@@ -5239,7 +5242,7 @@ msgstr "Sleutel voor kanaal %s is %s."
msgid "Kick a user from a channel"
msgstr "Kick een gebruiker uit een kanaal"
-#: modules/commands/cs_ban.cpp:217 modules/commands/cs_kick.cpp:116
+#: modules/commands/cs_ban.cpp:218 modules/commands/cs_kick.cpp:116
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr "%d/%d gebruikers gekickd die overeenstemden met %s uit %s."
@@ -5278,8 +5281,8 @@ msgstr "LIMIT afgedwongen op %s, %d gebruikers werden verwijderd."
msgid "LIST threshold"
msgstr "LIST aantal"
-#: modules/commands/os_sxline.cpp:427 modules/commands/os_sxline.cpp:661
-#: modules/commands/os_akill.cpp:388
+#: modules/commands/os_sxline.cpp:420 modules/commands/os_sxline.cpp:653
+#: modules/commands/os_akill.cpp:382
msgid "LIST [mask | list | id]"
msgstr "LIST [masker | lijst | id]"
@@ -5296,15 +5299,10 @@ msgstr "LIST [nick]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [text|nr]"
-#: modules/commands/ns_set.cpp:826
+#: modules/commands/ns_set.cpp:819
msgid "Language changed to English."
msgstr "Taal gewijzigd naar Nederlands."
-#: modules/commands/ns_set.cpp:828
-#, c-format
-msgid "Language for %s changed to %s."
-msgstr "Taal voor %s gewijzigd naar %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5354,14 +5352,15 @@ msgstr "Niveau voor %s op kanaal %s gewijzigd naar enkel-stichter."
msgid "Level must be between %d and %d inclusive."
msgstr "Niveau moet tussen de %d en %d inclusief zijn."
-#: modules/commands/os_dns.cpp:218 modules/commands/os_session.cpp:506
+#: modules/commands/os_dns.cpp:217 modules/commands/os_session.cpp:506
#: modules/commands/os_session.cpp:514
msgid "Limit"
msgstr "Limiet"
#: modules/commands/ns_list.cpp:19
msgid "List all registered nicknames that match a given pattern"
-msgstr "Toon alle geregistreerde nicks die met het gegeven patroon overeenstemmen"
+msgstr ""
+"Toon alle geregistreerde nicks die met het gegeven patroon overeenstemmen"
#: modules/commands/ns_alist.cpp:24
msgid "List channels you have access on"
@@ -5427,7 +5426,7 @@ msgstr ""
"weergegeven die met patroon overeenkomen en de +s\n"
"of +p kanaalmodus actief hebben."
-#: modules/commands/ns_alist.cpp:127
+#: modules/commands/ns_alist.cpp:118
msgid ""
"Lists all channels you have access on.\n"
" \n"
@@ -5447,7 +5446,8 @@ msgstr "Toon alle nicks in je groep"
#: modules/commands/cs_list.cpp:20
msgid "Lists all registered channels matching the given pattern"
-msgstr "Toon alle geregistreerde kanalen overeenstemmend met het gegeven patroon"
+msgstr ""
+"Toon alle geregistreerde kanalen overeenstemmend met het gegeven patroon"
#: modules/commands/cs_list.cpp:137
msgid ""
@@ -5656,7 +5656,8 @@ msgstr "Loglijst voor %s:"
#, c-format
msgid "Logging changed for command %s on %s, now using log method %s%s%s."
msgstr ""
-"Logging gewijzigd voor commando %s op %s, maakt nu gebruik van logmethode %s%s%s."
+"Logging gewijzigd voor commando %s op %s, maakt nu gebruik van logmethode %s"
+"%s%s."
#: modules/commands/cs_log.cpp:220
#, c-format
@@ -5667,9 +5668,10 @@ msgstr "Logging voor commando %s op %s met logmethode %s%s%s werd verwijderd."
#, c-format
msgid "Logging is now active for command %s on %s, using log method %s%s%s."
msgstr ""
-"Logging is nu actief voor commando %s op %s, gebruikmakend van logmethode %s%s%s."
+"Logging is nu actief voor commando %s op %s, gebruikmakend van logmethode %s"
+"%s%s."
-#: modules/commands/os_login.cpp:60
+#: modules/commands/os_login.cpp:61
#, c-format
msgid "Login to %s"
msgstr "Meld aan bij %s"
@@ -5688,12 +5690,12 @@ msgstr "Login nieuwsbericht #%s niet gevonden!"
msgid "Logon news items:"
msgstr "Login nieuwsberichten:"
-#: modules/commands/os_login.cpp:102
+#: modules/commands/os_login.cpp:103
#, c-format
msgid "Logout from %s"
msgstr "Meld af bij %s"
-#: modules/commands/os_login.cpp:52
+#: modules/commands/os_login.cpp:53
#, c-format
msgid ""
"Logs you in to %s so you gain Services Operator privileges.\n"
@@ -5704,7 +5706,7 @@ msgstr ""
"krijgt. Dit commando kan overbodig zijn indien jouw operblok\n"
"zonder wachtwoord ingesteld is."
-#: modules/commands/os_login.cpp:94
+#: modules/commands/os_login.cpp:95
#, c-format
msgid ""
"Logs you out from %s so you lose Services Operator privileges.\n"
@@ -5715,7 +5717,7 @@ msgstr ""
"worden. Dit commando is enkel nuttig indien je operblok ingesteld\n"
"is met een wachtwoord."
-#: modules/commands/cs_seen.cpp:213
+#: modules/commands/cs_seen.cpp:214
#, c-format
msgid "Looking for yourself, eh %s?"
msgstr "Zoek je jezelf, %s?"
@@ -5727,17 +5729,18 @@ msgid ""
"access)\n"
"on a channel.\n"
" \n"
-"The %s LOCK command allows you to add, delete, and view mode locks on a channel.\n"
-"If a mode is locked on or off, services will not allow that mode to be changed. "
-"The SET\n"
-"command will clear all existing mode locks and set the new one given, while ADD "
-"and DEL\n"
+"The %s LOCK command allows you to add, delete, and view mode locks on a "
+"channel.\n"
+"If a mode is locked on or off, services will not allow that mode to be "
+"changed. The SET\n"
+"command will clear all existing mode locks and set the new one given, while "
+"ADD and DEL\n"
"modify the existing mode lock.\n"
"Example:\n"
" MODE #channel LOCK ADD +bmnt *!*@*aol*\n"
" \n"
-"The %s SET command allows you to set modes through services. Wildcards * and ? "
-"may\n"
+"The %s SET command allows you to set modes through services. Wildcards * "
+"and ? may\n"
"be given as parameters for list and status modes.\n"
"Example:\n"
" MODE #channel SET +v *\n"
@@ -5746,9 +5749,10 @@ msgid ""
" MODE #channel SET -b ~c:*\n"
" Clears all extended bans that start with ~c:\n"
" \n"
-"The %s CLEAR command is an easy way to clear modes on a channel. what may be\n"
-"any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and "
-"voices. If what\n"
+"The %s CLEAR command is an easy way to clear modes on a channel. what may "
+"be\n"
+"any mode name. Examples include bans, excepts, inviteoverrides, ops, "
+"halfops, and voices. If what\n"
"is not given then all basic modes are removed."
msgstr ""
"Controleert voornamelijk de mode-vergrendelingen en mode-toegang (welke "
@@ -5756,11 +5760,12 @@ msgstr ""
"is van kanaaltoegang) op een kanaal.\n"
" \n"
"Het %s LOCK commando laat je toe mode-vergrendelingen toe te voegen, te\n"
-"verwijderen, en te bekijken op een kanaal. Als een mode vergrendeld is dan zal "
-"Services\n"
+"verwijderen, en te bekijken op een kanaal. Als een mode vergrendeld is dan "
+"zal Services\n"
"wijzigingen van die mode niet toelaten. Het SET commando verwijdert alle "
"bestaande\n"
-"mode-vergrendelingen, en stelt de gegeven modes in als de nieuwe vergrendeling,\n"
+"mode-vergrendelingen, en stelt de gegeven modes in als de nieuwe "
+"vergrendeling,\n"
"en ADD en DEL passen de bestaande vergrendelingen aan.\n"
"Voorbeeld:\n"
" MODE #kanaal LOCK ADD +bmnt *!*@*aol*\n"
@@ -5777,7 +5782,8 @@ msgstr ""
" \n"
"Het %s CLEAR commando is een gemakkelijke manier om modes te verwijderen op\n"
"een kanaal. wat kan eender welke mode-naam zijn. Voorbeelden zijn: bans,\n"
-"excepts, inviteoverrides, ops, halfops, en voices. Als wat niet is gegeven, dan\n"
+"excepts, inviteoverrides, ops, halfops, en voices. Als wat niet is gegeven, "
+"dan\n"
"worden alle basismodes verwijderd."
#: modules/commands/cs_akick.cpp:422
@@ -5930,7 +5936,7 @@ msgstr ""
"waar de GREET optie aan staat, en als je daarop voldoende\n"
"toegang tot hebt."
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "Manage DNS zones for this network"
msgstr "Beheer DNS domeinnamen voor dit netwerk"
@@ -5946,12 +5952,12 @@ msgstr "Beheer de memo-negeerlijst"
msgid "Manage your auto join list"
msgstr "Beheer je autojoinlijst"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, c-format
msgid "Manipulate the %s list"
msgstr "Beheer de %s lijst"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
msgid "Manipulate the AKILL list"
msgstr "Beheer de AKILL lijst"
@@ -5966,12 +5972,12 @@ msgstr "Pas de topic van het gegeven kanaal aan"
#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
#: modules/commands/cs_access.cpp:472 modules/commands/cs_flags.cpp:301
#: modules/commands/cs_xop.cpp:385 modules/commands/os_ignore.cpp:266
-#: modules/commands/os_sxline.cpp:193 modules/commands/os_sxline.cpp:201
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
#: modules/commands/os_forbid.cpp:346 modules/commands/cs_akick.cpp:367
#: modules/commands/cs_akick.cpp:380 modules/commands/ms_ignore.cpp:86
#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/os_list.cpp:147 modules/commands/bs_info.cpp:55
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
+#: modules/commands/os_list.cpp:147 modules/commands/bs_info.cpp:56
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
msgid "Mask"
msgstr "Masker"
@@ -5980,14 +5986,15 @@ msgstr "Masker"
msgid "Mask %s already present on %s's access list."
msgstr "Masker %s bestaat al op %s's toegangslijst."
-#: include/language.h:67
+#: include/language.h:68
msgid "Mask must be in the form user@host."
msgstr "Masker moet in het ident@host formaat zijn."
#: modules/commands/cs_access.cpp:166 modules/commands/cs_flags.cpp:120
#: modules/commands/cs_xop.cpp:166
msgid "Masks and unregistered users may not be on access lists."
-msgstr "Maskers en ongeregistreerde gebruikers mogen niet op toegangslijsten staan."
+msgstr ""
+"Maskers en ongeregistreerde gebruikers mogen niet op toegangslijsten staan."
#: modules/commands/ns_getemail.cpp:23
msgid "Matches and returns all users that registered using given email"
@@ -6003,7 +6010,7 @@ msgstr "Overeenkomsten voor %s:"
msgid "Maximum users: %d (%s)"
msgstr "Maximum gebruikers: %d (%s)"
-#: modules/commands/ms_read.cpp:84 modules/commands/ms_read.cpp:86
+#: modules/commands/ms_read.cpp:75 modules/commands/ms_read.cpp:77
#, c-format
msgid "Memo %d from %s (%s)."
msgstr "Memo %d van %s (%s)."
@@ -6046,7 +6053,7 @@ msgstr "Memo's voor %s:"
msgid "Message"
msgstr "Bericht"
-#: modules/commands/ns_set.cpp:1304
+#: modules/commands/ns_set.cpp:1295
msgid "Message mode"
msgstr "Berichtenmodus"
@@ -6220,7 +6227,7 @@ msgstr "Module: %s [%s] [%s]"
msgid "Name"
msgstr "Naam"
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:152
msgid "Name Type"
msgstr "Naam Type"
@@ -6234,7 +6241,7 @@ msgid "Never"
msgstr "Nooit"
#: modules/commands/hs_list.cpp:58 modules/commands/bs_botlist.cpp:27
-#: modules/commands/hs_request.cpp:305 modules/commands/ns_list.cpp:75
+#: modules/commands/hs_request.cpp:306 modules/commands/ns_list.cpp:75
#: modules/commands/ns_group.cpp:315
msgid "Nick"
msgstr "Nick"
@@ -6285,12 +6292,12 @@ msgstr "Nick %s is geen Services Operator."
msgid "Nick %s is part of this Network's Services."
msgstr "Nick %s is deel van de Services van dit netwerk."
-#: include/language.h:79
+#: include/language.h:80
#, c-format
msgid "Nick %s isn't currently in use."
msgstr "Nick %s is momenteel niet in gebruik."
-#: include/language.h:78
+#: include/language.h:79
#, c-format
msgid "Nick %s isn't registered."
msgstr "Nick %s is niet geregistreerd."
@@ -6300,12 +6307,12 @@ msgstr "Nick %s is niet geregistreerd."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s werd verkort naar %d tekens."
-#: modules/commands/ns_set.cpp:1127
+#: modules/commands/ns_set.cpp:1118
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s zal verlopen."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1112
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s zal niet verlopen."
@@ -6325,7 +6332,7 @@ msgstr "Nick %s werd uitgelogd."
msgid "Nick %s has been ungrouped from %s."
msgstr "Nick %s werd uit groep %s gehaald."
-#: include/language.h:81
+#: include/language.h:82
#, c-format
msgid "Nick %s is currently suspended."
msgstr "Nick %s is momenteel geschorst."
@@ -6350,7 +6357,7 @@ msgstr "Nick %s is nu vrijgegeven."
msgid "Nick %s is now suspended."
msgstr "Nick %s is nu geschorst."
-#: modules/commands/cs_seen.cpp:274
+#: modules/commands/cs_seen.cpp:270
#, c-format
msgid "Nick too long, max length is %u characters."
msgstr "Nick te lang, maximum lengte is %u karakters."
@@ -6360,27 +6367,27 @@ msgstr "Nick te lang, maximum lengte is %u karakters."
msgid "Nickname %s has been dropped."
msgstr "Nickregistratie voor %s werd verwijderd."
-#: include/language.h:97
+#: include/language.h:98
#, c-format
msgid "Nickname %s is already registered!"
msgstr "Nick %s is al geregistreerd!"
-#: include/language.h:96
+#: include/language.h:97
#, c-format
msgid "Nickname %s may not be registered."
msgstr "Nick %s mag niet geregistreerd worden."
-#: modules/commands/ns_register.cpp:226
+#: modules/commands/ns_register.cpp:212
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Nick %s is geregistreerd onder jouw gebruikersmasker: %s"
-#: modules/commands/ns_register.cpp:228
+#: modules/commands/ns_register.cpp:214
#, c-format
msgid "Nickname %s registered."
msgstr "Nick %s is geregistreerd."
-#: modules/commands/cs_set.cpp:1352
+#: modules/commands/cs_set.cpp:1353
msgid "No auto-op"
msgstr "Geen auto-op"
@@ -6388,7 +6395,7 @@ msgstr "Geen auto-op"
msgid "No bot"
msgstr "Geen bot"
-#: modules/commands/cs_set.cpp:1348 modules/commands/ns_set.cpp:1308
+#: modules/commands/cs_set.cpp:1349 modules/commands/ns_set.cpp:1299
msgid "No expire"
msgstr "Verloopt niet"
@@ -6441,12 +6448,12 @@ msgstr "Geen overeenkomsten op %s slechtewoordenlijst."
msgid "No matching entries on session-limit exception list."
msgstr "Geen overeenkomsten op de uitzonderingenlijst voor sessielimieten."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, c-format
msgid "No matching entries on the %s list."
msgstr "Geen overeenkomsten op de %s lijst."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Geen overeenkomsten op de AKILL lijst."
@@ -6454,19 +6461,21 @@ msgstr "Geen overeenkomsten op de AKILL lijst."
msgid "No memo was cancelable."
msgstr "Geen annuleerbare memo's gevonden."
-#: modules/commands/ms_read.cpp:65
-msgid "No memos to display."
-msgstr "Geen memo's om weer te geven."
-
#: modules/commands/os_modinfo.cpp:187
msgid "No modules currently loaded matching that criteria."
msgstr "Geen modules geladen die overeenkomen met die criteria."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, c-format
+msgid "No nick registrations matching %s found."
+msgstr "Geen nickregistraties overeenkomend met %s gevonden."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
-msgstr "Er is niemand die je nick gebruikt, en Services blokkeert het ook niet."
+msgstr ""
+"Er is niemand die je nick gebruikt, en Services blokkeert het ook niet."
-#: modules/commands/os_login.cpp:30 modules/commands/os_login.cpp:77
+#: modules/commands/os_login.cpp:31 modules/commands/os_login.cpp:78
msgid "No oper block for your nick."
msgstr "Geen operblok voor jouw nick."
@@ -6482,17 +6491,12 @@ msgstr "Geen willekeurige nieuwsberichten om te verwijderen!"
msgid "No records to display."
msgstr "Geen resultaten om weer te geven."
-#: modules/commands/ns_getemail.cpp:47
-#, c-format
-msgid "No registrations matching %s were found."
-msgstr "Geen nicknameregistraties overeenkomend met %s gevonden."
-
-#: modules/commands/hs_request.cpp:220 modules/commands/hs_request.cpp:276
+#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
#, c-format
msgid "No request for nick %s found."
msgstr "Geen aanvraag voor nick %s gevonden."
-#: src/access.cpp:55
+#: src/access.cpp:56
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr "Geen ondertekende kicks wanneer SIGNKICK LEVEL gebruikt word"
@@ -6507,7 +6511,7 @@ msgstr "Geen statistieken voor %s."
msgid "No such info \"%s\" on %s."
msgstr "Geen zulke info \"%s\" over %s."
-#: modules/commands/cs_ban.cpp:219 modules/commands/cs_kick.cpp:118
+#: modules/commands/cs_ban.cpp:220 modules/commands/cs_kick.cpp:118
#, c-format
msgid "No users on %s match %s."
msgstr "Geen gebruikers op %s die overeenkomen met %s."
@@ -6527,7 +6531,7 @@ msgstr "Geen-botmodus staat nu aan op kanaal %s."
msgid "Non-status modes cleared on %s."
msgstr "Niet-statusmodes weggehaald op %s."
-#: modules/commands/os_dns.cpp:226 modules/commands/bs_info.cpp:58
+#: modules/commands/os_dns.cpp:225 modules/commands/bs_info.cpp:59
msgid "None"
msgstr "Geen"
@@ -6538,13 +6542,13 @@ msgstr "Niets te doen."
#: modules/commands/hs_list.cpp:58 modules/commands/cs_access.cpp:459
#: modules/commands/cs_access.cpp:472 modules/commands/cs_flags.cpp:301
#: modules/commands/cs_xop.cpp:385 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/ms_list.cpp:64
#: modules/commands/bs_badwords.cpp:194 modules/commands/os_news.cpp:156
-#: modules/commands/hs_request.cpp:305 modules/commands/cs_akick.cpp:367
+#: modules/commands/hs_request.cpp:306 modules/commands/cs_akick.cpp:367
#: modules/commands/cs_akick.cpp:380 modules/commands/cs_log.cpp:127
#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
#: modules/commands/ns_ajoin.cpp:100
msgid "Number"
msgstr "Nummer"
@@ -6557,15 +6561,6 @@ msgstr "OPERNEWS {ADD|DEL|LIST} [text|nr]"
msgid "Online from"
msgstr "Is online vanaf"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by this "
-"command."
-msgstr ""
-"Oper %s is ingesteld in de configuratiebestanden en kan niet worden verwijderd "
-"met dit commando."
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr "Oper info"
@@ -6589,12 +6584,12 @@ msgstr "Operator nieuwsbericht #%s niet gevonden!"
msgid "Oper news items:"
msgstr "Operator nieuwsberichten:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:147
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr "Operator privileges ontnomen van %s (%s)."
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:188
#, c-format
msgid "Oper type %s has not been configured."
msgstr "Opertype %s werd niet ingesteld."
@@ -6609,30 +6604,30 @@ msgstr "Opervlaggen %s zijn toegevoegd voor %s."
msgid "Operflags %s have been removed from %s."
msgstr "Opervlaggen %s zijn verwijderd van %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:192
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr "Opertype %s heeft geen toegestane commando's."
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:214
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr "Opertype %s heeft geen toegestane privileges."
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:236
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr "Opertype %s ontvangt modes %s eens geïdentificeerd."
-#: modules/commands/bs_kick.cpp:1219
+#: modules/commands/bs_kick.cpp:1208
msgid "Ops protection"
msgstr "Ops bescherming"
-#: src/misc.cpp:258 modules/commands/bs_info.cpp:58
+#: src/misc.cpp:259 modules/commands/bs_info.cpp:59
msgid "Options"
msgstr "Opties"
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
msgid "POOL server.name"
msgstr "POOL server.naam"
@@ -6644,11 +6639,11 @@ msgstr "Param"
msgid "Password accepted - you are now recognized."
msgstr "Wachtwoord aanvaard - je wordt nu herkend."
-#: modules/commands/os_login.cpp:44
+#: modules/commands/os_login.cpp:45
msgid "Password accepted."
msgstr "Wachtwoord aanvaard."
-#: include/language.h:85
+#: include/language.h:86
msgid "Password authentication required for that command."
msgstr "Wachtwoord authenticatie vereist voor dat commando."
@@ -6667,7 +6662,7 @@ msgstr "Wachtwoord voor %s gewijzigd."
msgid "Password for %s is %s."
msgstr "Wachtwoord voor %s is %s."
-#: include/language.h:71
+#: include/language.h:72
msgid "Password incorrect."
msgstr "Fout wachtwoord."
@@ -6676,7 +6671,7 @@ msgstr "Fout wachtwoord."
msgid "Password reset email for %s has been sent."
msgstr "Wachtwoord reset e-mail voor %s werd verstuurd."
-#: modules/commands/cs_set.cpp:1334
+#: modules/commands/cs_set.cpp:1335
msgid "Peace"
msgstr "Vrede"
@@ -6690,17 +6685,17 @@ msgstr "Vrede-optie voor %s is nu uit."
msgid "Peace option for %s is now on."
msgstr "Vrede-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1346
+#: modules/commands/cs_set.cpp:1347
msgid "Persistent"
msgstr "Permanent"
-#: include/language.h:126
+#: include/language.h:127
msgid "Please contact an Operator to get a vHost assigned to this nick."
msgstr ""
"Gelieve een Operator te contacteren om een vHost aan je nick toegewezen te "
"krijgen."
-#: include/language.h:73
+#: include/language.h:74
msgid ""
"Please try again with a more obscure password. Passwords should be at least\n"
"five characters long, should not be something easily guessed\n"
@@ -6709,26 +6704,28 @@ msgid ""
msgstr ""
"Gelieve opnieuw te proberen met een moeilijker wachtwoord. Wachtwoorden\n"
"moeten tenminste 5 karakters lang zijn, iets dat niet makkelijk geraden kan\n"
-"worden (zoals bijvoorbeeld je echte naam of nick), en kan geen spaties of tab-\n"
+"worden (zoals bijvoorbeeld je echte naam of nick), en kan geen spaties of "
+"tab-\n"
"karakters bevatten."
#: modules/commands/os_jupe.cpp:30
msgid "Please use a valid server name when juping."
msgstr "Gelieve een geldige servernaam te gebruiken bij het blokkeren."
-#: include/language.h:104
+#: include/language.h:105
msgid "Please use the symbol of # when attempting to register."
msgstr "Gelieve het #-symbool te gebruiken bij het registreren."
-#: src/mail.cpp:77
+#: src/mail.cpp:78
#, c-format
msgid "Please wait %d seconds and retry."
msgstr "Gelieve %d seconden te wachten en opnieuw te proberen."
-#: modules/commands/hs_request.cpp:158
+#: modules/commands/hs_request.cpp:159
#, c-format
msgid "Please wait %d seconds before requesting a new vHost."
-msgstr "Gelieve %d seconden te wachten alvorens een nieuwe vHost aan te vragen."
+msgstr ""
+"Gelieve %d seconden te wachten alvorens een nieuwe vHost aan te vragen."
#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:57
#, c-format
@@ -6740,25 +6737,26 @@ msgstr ""
#, c-format
msgid "Please wait %d seconds before using the GROUP command again."
msgstr ""
-"Gelieve %d seconden te wachten alvorens het GROUP commando opnieuw te gebruiken."
+"Gelieve %d seconden te wachten alvorens het GROUP commando opnieuw te "
+"gebruiken."
-#: modules/commands/ns_register.cpp:198
+#: modules/commands/ns_register.cpp:184
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Gelieve %d seconden te wachten alvorens het REGISTER commando opnieuw te "
"gebruiken."
-#: modules/commands/os_dns.cpp:628
+#: modules/commands/os_dns.cpp:627
#, c-format
msgid "Pooled %s."
msgstr "Pooled %s."
-#: modules/commands/os_dns.cpp:237
+#: modules/commands/os_dns.cpp:236
msgid "Pooled/Active"
msgstr "Pooled/Actief"
-#: modules/commands/os_dns.cpp:239
+#: modules/commands/os_dns.cpp:238
msgid "Pooled/Not Active"
msgstr "Pooled/Niet actief"
@@ -6776,7 +6774,7 @@ msgstr ""
"Voorkom gebruik van een kanaal terwijl de data en instellingen ervan toch "
"behouden blijven"
-#: modules/commands/cs_set.cpp:1046
+#: modules/commands/cs_set.cpp:1047
msgid "Prevent the channel from expiring"
msgstr "Voorkom dat het kanaal verloopt"
@@ -6784,16 +6782,16 @@ msgstr "Voorkom dat het kanaal verloopt"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Voorkom dat de nick in het LIST commando verschijnt"
-#: modules/commands/ns_set.cpp:1096
+#: modules/commands/ns_set.cpp:1087
msgid "Prevent the nickname from expiring"
msgstr "Voorkom dat de nick verloopt"
-#: src/access.cpp:46
+#: src/access.cpp:47
msgid "Prevents users being kicked by Services"
msgstr "Voorkomt dat gebruikers gekickt worden door Services"
#: modules/commands/ns_list.cpp:297 modules/commands/cs_list.cpp:262
-#: modules/commands/bs_info.cpp:58
+#: modules/commands/bs_info.cpp:59
msgid "Private"
msgstr "Privé"
@@ -6837,31 +6835,31 @@ msgstr "Privilege %s toegevoegd bij %s op %s, nieuwe vlaggen zijn +%s"
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Privilege %s verwijderd van %s op %s, nieuwe vlaggen zijn +%s"
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1291
msgid "Protection"
msgstr "Bescherming"
-#: modules/commands/ns_set.cpp:713
+#: modules/commands/ns_set.cpp:707
#, c-format
msgid "Protection is now off for %s."
msgstr "Bescherming is nu uit voor %s."
-#: modules/commands/ns_set.cpp:692
+#: modules/commands/ns_set.cpp:686
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Bescherming is nu aan voor %s, met een kortere vertraging."
-#: modules/commands/ns_set.cpp:702
+#: modules/commands/ns_set.cpp:696
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Bescherming is nu aan voor %s, zonder vertraging."
-#: modules/commands/ns_set.cpp:684
+#: modules/commands/ns_set.cpp:678
#, c-format
msgid "Protection is now on for %s."
msgstr "Bescherming is nu aan voor %s."
-#: modules/commands/os_chankill.cpp:100
+#: modules/commands/os_chankill.cpp:96
msgid ""
"Puts an AKILL for every nick on the specified channel. It\n"
"uses the entire real ident@host for every nick, and\n"
@@ -6871,7 +6869,7 @@ msgstr ""
"gebruikt de volledige echte ident@host voor elke nick,\n"
"en dwingt dan de AKILL af."
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1289
msgid "Quick protection"
msgstr "Snelle bescherming"
@@ -6905,28 +6903,28 @@ msgstr "Willekeurig nieuwsbericht #%s niet gevonden!"
msgid "Random news items:"
msgstr "Willekeurige nieuwsberichten:"
-#: modules/commands/ms_read.cpp:112
+#: modules/commands/ms_read.cpp:103
msgid "Read a memo or memos"
msgstr "Lees een of meerdere memo's"
-#: modules/commands/bs_info.cpp:56
+#: modules/commands/bs_info.cpp:57
msgid "Real name"
msgstr "Echte naam"
-#: modules/commands/os_ignore.cpp:266 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_ignore.cpp:266 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_session.cpp:514 modules/commands/os_akill.cpp:344
-#: modules/commands/os_akill.cpp:361
+#: modules/commands/os_session.cpp:514 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355
msgid "Reason"
msgstr "Reden"
-#: src/xline.cpp:386
+#: src/xline.cpp:357
#, c-format
msgid "Reason for %s updated."
msgstr "Reden voor %s geüpdatet."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:193
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -6946,17 +6944,17 @@ msgstr ""
msgid "Redefine the meanings of access levels"
msgstr "Verander de betekenissen van toegangsniveaus"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:131
msgid "Regains control of your nick"
msgstr "Neemt de controle van je nick weer over"
-#: modules/commands/os_sxline.cpp:330 modules/commands/os_sxline.cpp:545
+#: modules/commands/os_sxline.cpp:324 modules/commands/os_sxline.cpp:538
#: modules/commands/os_akill.cpp:129
msgid "Regex is disabled."
msgstr "Regex is uitgeschakeld."
-#: modules/commands/os_sxline.cpp:459 modules/commands/os_sxline.cpp:694
-#: modules/commands/os_akill.cpp:444
+#: modules/commands/os_sxline.cpp:452 modules/commands/os_sxline.cpp:686
+#: modules/commands/os_akill.cpp:438
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -6980,7 +6978,7 @@ msgstr ""
msgid "Register a channel"
msgstr "Registreer een kanaal"
-#: modules/commands/ns_register.cpp:120
+#: modules/commands/ns_register.cpp:106
msgid "Register a nickname"
msgstr "Registreer een nickname"
@@ -6991,18 +6989,21 @@ msgstr "Geregistreerd"
#: modules/commands/os_stats.cpp:184
#, c-format
msgid "Registered channels: %lu entries, %lu buckets, longest chain is %d"
-msgstr "Geregistreerde kanalen: %lu vermeldingen, %lu emmers, langste ketting is %d"
+msgstr ""
+"Geregistreerde kanalen: %lu vermeldingen, %lu emmers, langste ketting is %d"
#: modules/commands/os_stats.cpp:190
#, c-format
msgid "Registered nick groups: %lu entries, %lu buckets, longest chain is %d"
msgstr ""
-"Geregistreerde nickgroepen: %lu vermeldingen, %lu emmers, langste ketting is %d"
+"Geregistreerde nickgroepen: %lu vermeldingen, %lu emmers, langste ketting is "
+"%d"
#: modules/commands/os_stats.cpp:187
#, c-format
msgid "Registered nicknames: %lu entries, %lu buckets, longest chain is %d"
-msgstr "Geregistreerde nicks: %lu vermeldingen, %lu emmers, langste ketting is %d"
+msgstr ""
+"Geregistreerde nicks: %lu vermeldingen, %lu emmers, langste ketting is %d"
#: modules/commands/cs_enforce.cpp:105
#, c-format
@@ -7036,7 +7037,7 @@ msgstr ""
"%s zal ook automatisch de stichter kanaaloperator\n"
"status geven wanneer deze het kanaal binnenkomt."
-#: modules/commands/ns_register.cpp:262
+#: modules/commands/ns_register.cpp:248
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7076,7 +7077,7 @@ msgstr ""
"dat minstens 5 karakters lang is. Als laatste, de spatie kan niet\n"
"gebruikt worden in wachtwoorden."
-#: modules/commands/ns_register.cpp:145
+#: modules/commands/ns_register.cpp:131
msgid "Registration is currently disabled."
msgstr "Registratie is momenteel uitgeschakeld."
@@ -7084,11 +7085,11 @@ msgstr "Registratie is momenteel uitgeschakeld."
msgid "Regulate the use of critical commands"
msgstr "Reguleer het gebruik van kritieke commando's"
-#: modules/commands/hs_request.cpp:283
+#: modules/commands/hs_request.cpp:284
msgid "Reject the requested vHost for the given nick."
msgstr "Wijs de aangevraagde vHost van de opgegeven nick af."
-#: modules/commands/hs_request.cpp:240
+#: modules/commands/hs_request.cpp:241
msgid "Reject the requested vHost of a user"
msgstr "Wijs de aangevraagde vHost van een gebruiker af"
@@ -7124,17 +7125,17 @@ msgstr "Haal alle bans weg die een gebruiker voorkomen een kanaal te betreden"
msgid "Remove all operators from a server remotely"
msgstr "Verwijder op afstand alle operators van een server"
-#: modules/commands/os_dns.cpp:543
+#: modules/commands/os_dns.cpp:542
#, c-format
msgid "Removed IP %s from %s."
msgstr "IP %s verwijderd van %s."
-#: modules/commands/os_dns.cpp:460
+#: modules/commands/os_dns.cpp:459
#, c-format
msgid "Removed server %s from zone %s."
msgstr "Server %s verwijderd van domein %s."
-#: modules/commands/os_dns.cpp:483
+#: modules/commands/os_dns.cpp:482
#, c-format
msgid "Removed server %s."
msgstr "Server %s verwijderd."
@@ -7168,21 +7169,21 @@ msgstr ""
"verwijderd. Indien kanaal niet is opgegeven, dan word je\n"
"status op elk kanaal waar je aanwezig bent verwijderd."
-#: src/xline.cpp:412
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr "%s verwijderd want %s dekt dit al."
-#: modules/commands/bs_kick.cpp:1171 modules/commands/bs_kick.cpp:1173
-#: modules/commands/bs_kick.cpp:1176
+#: modules/commands/bs_kick.cpp:1160 modules/commands/bs_kick.cpp:1162
+#: modules/commands/bs_kick.cpp:1165
msgid "Repeat kicker"
msgstr "Herhalingskicker"
-#: modules/commands/hs_request.cpp:78
+#: modules/commands/hs_request.cpp:79
msgid "Request a vHost for your nick"
msgstr "Vraag een vHost voor je nick aan"
-#: modules/commands/hs_request.cpp:179
+#: modules/commands/hs_request.cpp:180
msgid ""
"Request the given vHost to be activated for your nick by the\n"
"network administrators. Please be patient while your request\n"
@@ -7192,7 +7193,7 @@ msgstr ""
"door de netwerkbeheerders. Gelieve geduldig te wachten\n"
"terwijl uw aanvraag lopende is."
-#: modules/commands/ns_register.cpp:305
+#: modules/commands/ns_register.cpp:291
msgid "Resend registration confirmation email"
msgstr "Registratiebevestigings-e-mail opnieuw verzenden"
@@ -7200,7 +7201,7 @@ msgstr "Registratiebevestigings-e-mail opnieuw verzenden"
msgid "Restrict access to the channel"
msgstr "Beperk de toegang tot het kanaal"
-#: modules/commands/cs_set.cpp:1336
+#: modules/commands/cs_set.cpp:1337
msgid "Restricted access"
msgstr "Beperkte toegang"
@@ -7231,7 +7232,7 @@ msgstr "Onthoud het topic wanneer het kanaal niet in gebruik is"
msgid "Retrieve the password for a nickname"
msgstr "Vraag het wachtwoord van een nick op"
-#: modules/commands/hs_request.cpp:296
+#: modules/commands/hs_request.cpp:297
msgid "Retrieves the vhost requests"
msgstr "Vraag de vHost-aanvraaglijst op"
@@ -7244,9 +7245,17 @@ msgid "Returns the key of the given channel."
msgstr "Toont de sleutel voor het gegeven kanaal."
#: modules/commands/ns_getemail.cpp:58
-msgid "Returns the matching accounts that used given email."
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
msgstr ""
-"Geeft geregistreerde gebruikers weer die het gegeven e-mailadres gebruikt hebben."
+"Geeft de bijpassende nicks weer dat de gegeven e-mail gebruikt hebben.\n"
+"Merk op dat er geen jokertekens mogen worden gebruikt.\n"
+"Elke keer als dit commando wordt gebruikt wordt er een bericht\n"
+"gelogd met de persoon die dit commando uitvoerde samen met\n"
+"het e-mailadres waarop het werd gebruikt."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7300,8 +7309,8 @@ msgstr ""
" \n"
"Indien geen nick is gegeven, wordt je eigen status weergegeven."
-#: modules/commands/bs_kick.cpp:1181 modules/commands/bs_kick.cpp:1183
-#: modules/commands/bs_kick.cpp:1186
+#: modules/commands/bs_kick.cpp:1170 modules/commands/bs_kick.cpp:1172
+#: modules/commands/bs_kick.cpp:1175
msgid "Reverses kicker"
msgstr "Inverteringskicker"
@@ -7313,16 +7322,17 @@ msgstr "Doet het omgekeerde van het IDENTIFY commando"
msgid "SET server"
msgstr "SET server"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
msgid "SET server.name option value"
msgstr "SET server.naam optie waarde"
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
-msgstr "SSL certificaatvingerafdruk aanvaard, je bent nu geïdentificeerd voor %s."
+msgstr ""
+"SSL certificaatvingerafdruk aanvaard, je bent nu geïdentificeerd voor %s."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "SSL certificaatvingerafdruk aanvaard, je bent nu geïdentificeerd."
@@ -7343,30 +7353,30 @@ msgstr "Sla de database op en herstart Services"
msgid "Searches logs for a matching pattern"
msgstr "Doorzoekt logs voor een overeenstemmend patroon"
-#: modules/commands/cs_set.cpp:1340
+#: modules/commands/cs_set.cpp:1341
msgid "Secure founder"
msgstr "Strikte stichter controle"
-#: modules/commands/cs_set.cpp:797
+#: modules/commands/cs_set.cpp:798
#, c-format
msgid "Secure founder option for %s is now off."
msgstr "Strikte stichter controle-optie voor %s is nu uit."
-#: modules/commands/cs_set.cpp:791
+#: modules/commands/cs_set.cpp:792
#, c-format
msgid "Secure founder option for %s is now on."
msgstr "Strikte stichter controle-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1342
+#: modules/commands/cs_set.cpp:1343
msgid "Secure ops"
msgstr "Strikte operator controle"
-#: modules/commands/cs_set.cpp:861
+#: modules/commands/cs_set.cpp:862
#, c-format
msgid "Secure ops option for %s is now off."
msgstr "Strikte operator controle-optie voor %s is nu uit."
-#: modules/commands/cs_set.cpp:855
+#: modules/commands/cs_set.cpp:856
#, c-format
msgid "Secure ops option for %s is now on."
msgstr "Strikte operator controle-optie voor %s is nu aan."
@@ -7381,12 +7391,12 @@ msgstr "Veiligheidsoptie voor %s is nu uit."
msgid "Secure option for %s is now on."
msgstr "Veiligheidsoptie voor %s is nu aan."
-#: modules/commands/ns_set.cpp:1036
+#: modules/commands/ns_set.cpp:1027
#, c-format
msgid "Secure option is now off for %s."
msgstr "Veiligheidsoptie is nu uit voor %s."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1021
#, c-format
msgid "Secure option is now on for %s."
msgstr "Veiligheidsoptie is nu aan voor %s."
@@ -7396,7 +7406,7 @@ msgstr "Veiligheidsoptie is nu aan voor %s."
msgid "Secureops enforced on %s."
msgstr "SECUREOPS afgedwongen op %s."
-#: modules/commands/cs_set.cpp:1338 modules/commands/ns_set.cpp:1302
+#: modules/commands/cs_set.cpp:1339 modules/commands/ns_set.cpp:1293
msgid "Security"
msgstr "Veiligheid"
@@ -7490,7 +7500,7 @@ msgstr ""
"een memo teruggestuurd worden naar degene die de memo verstuurd\n"
"heeft om hem/haar te informeren dat de memo gelezen is."
-#: modules/commands/ms_read.cpp:192
+#: modules/commands/ms_read.cpp:183
msgid ""
"Sends you the text of the memos specified. If LAST is\n"
"given, sends you the memo you most recently received. If\n"
@@ -7510,69 +7520,69 @@ msgstr ""
" READ 2-5,7-9\n"
" Geeft de memo's genummerd 2 t/m 5 en 7 t/m 9 weer."
-#: modules/commands/os_dns.cpp:218
+#: modules/commands/os_dns.cpp:217
msgid "Server"
msgstr "Server"
-#: modules/commands/os_dns.cpp:375
+#: modules/commands/os_dns.cpp:374
#, c-format
msgid "Server %s added to zone %s."
msgstr "Server %s toegevoegd aan domein %s."
-#: modules/commands/os_dns.cpp:345
+#: modules/commands/os_dns.cpp:344
#, c-format
msgid "Server %s already exists."
msgstr "Server %s bestaat reeds."
-#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:430
-#: modules/commands/os_dns.cpp:493 modules/commands/os_dns.cpp:532
-#: modules/commands/os_dns.cpp:571 modules/commands/os_dns.cpp:604
-#: modules/commands/os_dns.cpp:639
+#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
+#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
+#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
+#: modules/commands/os_dns.cpp:638
#, c-format
msgid "Server %s does not exist."
msgstr "Server %s bestaat niet."
-#: modules/commands/os_dns.cpp:619
+#: modules/commands/os_dns.cpp:618
#, c-format
msgid "Server %s has no configured IPs."
msgstr "Server %s heeft geen geconfigureerde IP-adressen."
-#: modules/commands/os_dns.cpp:357
+#: modules/commands/os_dns.cpp:356
#, c-format
msgid "Server %s is already in zone %s."
msgstr "Server %s is reeds in domein %s."
-#: modules/commands/os_dns.cpp:614
+#: modules/commands/os_dns.cpp:613
#, c-format
msgid "Server %s is already pooled."
msgstr "Server %s is reeds pooled."
-#: modules/commands/os_dns.cpp:609
+#: modules/commands/os_dns.cpp:608
#, c-format
msgid "Server %s is not currently linked."
msgstr "Server %s is momenteel niet gelinkt."
-#: modules/commands/os_dns.cpp:443
+#: modules/commands/os_dns.cpp:442
#, c-format
msgid "Server %s is not in zone %s."
msgstr "Server %s is niet in domein %s."
-#: modules/commands/os_dns.cpp:384
+#: modules/commands/os_dns.cpp:383
#, c-format
msgid "Server %s is not linked to the network."
msgstr "Server %s is niet gelinkt aan het netwerk."
-#: modules/commands/os_dns.cpp:644
+#: modules/commands/os_dns.cpp:643
#, c-format
msgid "Server %s is not pooled."
msgstr "Server %s is niet pooled."
-#: modules/commands/os_dns.cpp:465
+#: modules/commands/os_dns.cpp:464
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr "Server %s moet gequit zijn alvorens het verwijderd kan worden."
-#: modules/commands/os_dns.cpp:255
+#: modules/commands/os_dns.cpp:254
msgid "Servers"
msgstr "Servers"
@@ -7585,12 +7595,12 @@ msgstr "Servers gevonden: %d"
msgid "Service"
msgstr "Service"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, c-format
msgid "Service's hold on %s has been released."
msgstr "Nick %s werd vrijgegeven."
-#: data/nickserv.example.conf:235 data/chanserv.example.conf:827
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:827
msgid "Services Operator commands"
msgstr "Services Operator commando's"
@@ -7600,7 +7610,7 @@ msgstr "Services Operator commando's"
msgid "Services are in DefCon mode, please try again later."
msgstr "Services zijn in DefCon modus, probeer later opnieuw."
-#: include/language.h:70
+#: include/language.h:71
msgid "Services are in read-only mode!"
msgstr "Services zijn in alleen-lezen modus!"
@@ -7638,7 +7648,7 @@ msgstr "Services zijn nu in alleen-lezen modus."
msgid "Services are now in read-write mode."
msgstr "Services zijn nu in lezen-schrijven modus."
-#: src/mail.cpp:75
+#: src/mail.cpp:76
msgid "Services have been configured to not send mail."
msgstr "Services zijn geconfigureerd om geen e-mails te versturen."
@@ -7667,7 +7677,8 @@ msgstr "Services zal vanaf nu status modes geven aan %s in kanalen."
#: modules/commands/cs_set.cpp:111
#, c-format
msgid "Services will no longer automatically give modes to users in %s."
-msgstr "Services zal nu niet langer automatisch modes geven aan gebruikers in %s."
+msgstr ""
+"Services zal nu niet langer automatisch modes geven aan gebruikers in %s."
#: modules/commands/ns_set.cpp:269
#, c-format
@@ -7679,12 +7690,12 @@ msgstr "Services zal niet langer status modes geven aan %s in kanalen."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services zal nu automatisch modes geven aan gebruikers in %s."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:923
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services zal nu antwoorden sturen naar %s via privé berichten."
-#: modules/commands/ns_set.cpp:938
+#: modules/commands/ns_set.cpp:929
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services zal nu antwoorden sturen naar %s via notice."
@@ -7747,17 +7758,17 @@ msgstr "Stel de weergave van je groep in Services in"
msgid "Set the founder of a channel"
msgstr "Stelt de stichter van een kanaal in"
-#: modules/commands/ns_set.cpp:785
+#: modules/commands/ns_set.cpp:779
msgid "Set the language Services will use when messaging you"
msgstr ""
-"Selecteer de taal die Services zal gebruiken voor het versturen van berichten "
-"naar jou"
+"Selecteer de taal die Services zal gebruiken voor het versturen van "
+"berichten naar jou"
#: modules/commands/ns_set.cpp:169
msgid "Set the nickname password"
msgstr "Verander het wachtwoord van de nick"
-#: modules/commands/cs_set.cpp:960
+#: modules/commands/cs_set.cpp:961
msgid "Set the successor for a channel"
msgstr "Stelt de opvolger voor het kanaal in"
@@ -7777,7 +7788,7 @@ msgstr "Stel verscheidene globale Services opties in"
msgid "Set your nickname password"
msgstr "Verander het wachtwoord van je nick"
-#: modules/commands/bs_kick.cpp:271
+#: modules/commands/bs_kick.cpp:273
#, c-format
msgid ""
"Sets the AMSG kicker on or off. When enabled, the bot will\n"
@@ -7796,7 +7807,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:307
+#: modules/commands/bs_kick.cpp:309
#, c-format
msgid ""
"Sets the bad words kicker on or off. When enabled, this\n"
@@ -7843,7 +7854,7 @@ msgstr ""
"2: ban in het formaat *!*@host\n"
"3: ban in het formaat *!*ident@*.domein"
-#: modules/commands/bs_kick.cpp:345
+#: modules/commands/bs_kick.cpp:347
msgid ""
"Sets the bolds kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use bolds.\n"
@@ -7859,7 +7870,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:436
+#: modules/commands/bs_kick.cpp:438
#, c-format
msgid ""
"Sets the caps kicker on or off. When enabled, this\n"
@@ -7885,7 +7896,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:475
+#: modules/commands/bs_kick.cpp:477
msgid ""
"Sets the colors kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use colors.\n"
@@ -7909,7 +7920,7 @@ msgstr ""
"Stelt de beschrijving van het kanaal in, die weergegeven\n"
"wordt door de LIST en INFO commando's."
-#: modules/commands/bs_kick.cpp:571
+#: modules/commands/bs_kick.cpp:573
msgid ""
"Sets the flood kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are flooding\n"
@@ -7929,7 +7940,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:607
+#: modules/commands/bs_kick.cpp:609
msgid ""
"Sets the italics kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use italics.\n"
@@ -7945,7 +7956,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:706
+#: modules/commands/bs_kick.cpp:695
msgid ""
"Sets the repeat kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are repeating\n"
@@ -7964,7 +7975,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:742
+#: modules/commands/bs_kick.cpp:731
msgid ""
"Sets the reverses kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use reverses.\n"
@@ -7981,7 +7992,7 @@ msgstr ""
"worden voordat deze geband wordt. Geef geen ttb op om het\n"
"bansysteem uit te schakelen als deze kicker geactiveerd is."
-#: modules/commands/bs_kick.cpp:776
+#: modules/commands/bs_kick.cpp:765
msgid ""
"Sets the underlines kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use underlines.\n"
@@ -8074,10 +8085,12 @@ msgid "Sets various nickname options. option can be one of:"
msgstr "Stelt verscheidene nick opties in. optie kan een van de volgende zijn:"
#: modules/commands/ns_set.cpp:234
-msgid "Sets whether services should set channel status modes on you automatically."
-msgstr "Stelt in of Services je automatisch je status modes geeft op het kanaal."
+msgid ""
+"Sets whether services should set channel status modes on you automatically."
+msgstr ""
+"Stelt in of Services je automatisch je status modes geeft op het kanaal."
-#: modules/commands/cs_set.cpp:1093
+#: modules/commands/cs_set.cpp:1094
msgid ""
"Sets whether the given channel will expire. Setting this\n"
"to ON prevents the channel from expiring."
@@ -8099,7 +8112,7 @@ msgstr ""
"te zetten wanneer de nick kanalen betreed. Let op dat afhankelijk van de\n"
"kanaalinstellingen sommige modes niet automatisch gezet kunnen worden."
-#: modules/commands/ns_set.cpp:1137
+#: modules/commands/ns_set.cpp:1128
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8122,7 +8135,8 @@ msgstr ""
#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
#, c-format
-msgid "Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
+msgid ""
+"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
msgstr ""
"Instelling %s onbekend. Typ %s%s HELP LEVELS voor een lijst van geldige "
"instellingen."
@@ -8156,16 +8170,16 @@ msgstr "Geef de status van Services en het netwerk weer"
msgid "Showed %d/%d matches for %s."
msgstr "%d/%d overeenkomsten getoond voor %s."
-#: modules/commands/cs_set.cpp:883
+#: modules/commands/cs_set.cpp:884
msgid "Sign kicks that are done with the KICK command"
msgstr "Onderteken kicks die worden uitgevoerd met het KICK commando"
-#: modules/commands/cs_set.cpp:932
+#: modules/commands/cs_set.cpp:933
#, c-format
msgid "Signed kick option for %s is now off."
msgstr "Ondertekende kicks-optie voor %s is nu uit."
-#: modules/commands/cs_set.cpp:924
+#: modules/commands/cs_set.cpp:925
#, c-format
msgid ""
"Signed kick option for %s is now on, but depends of the\n"
@@ -8174,28 +8188,30 @@ msgstr ""
"Ondertekende kicks-optie voor %s is nu aan, maar hangt af\n"
"van het niveau van de gebruiker die het commando uitvoert."
-#: modules/commands/cs_set.cpp:917
+#: modules/commands/cs_set.cpp:918
#, c-format
msgid "Signed kick option for %s is now on."
msgstr "Ondertekende kicks-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1344
+#: modules/commands/cs_set.cpp:1345
msgid "Signed kicks"
msgstr "Ondertekende kicks"
#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:59
#, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
-msgstr "Sorry, %s heeft momenteel te veel memo's en kan er geen meer ontvangen."
+msgstr ""
+"Sorry, %s heeft momenteel te veel memo's en kan er geen meer ontvangen."
-#: modules/commands/cs_seen.cpp:293
+#: modules/commands/cs_seen.cpp:289
#, c-format
msgid "Sorry, I have not seen %s."
msgstr "Sorry, ik heb %s niet gezien."
#: modules/commands/bs_badwords.cpp:404
msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Sorry, het wijzigen van de slechtewoordenlijst is tijdelijk uitgeschakeld."
+msgstr ""
+"Sorry, het wijzigen van de slechtewoordenlijst is tijdelijk uitgeschakeld."
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
msgid "Sorry, bot assignment is temporarily disabled."
@@ -8205,8 +8221,8 @@ msgstr "Sorry, bot toewijzing is tijdelijk uitgeschakeld."
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Sorry, bot wijzigingen zijn tijdelijk uitgeschakeld."
-#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:813
-#: modules/commands/bs_kick.cpp:878
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Sorry, bot opties instellen is tijdelijk uitgeschakeld."
@@ -8236,7 +8252,7 @@ msgstr "Sorry, kanalen kunnen tijdelijk niet verwijderd worden."
msgid "Sorry, channel registration is temporarily disabled."
msgstr "Sorry, kanaal registratie is tijdelijk uitgeschakeld."
-#: modules/commands/bs_kick.cpp:181
+#: modules/commands/bs_kick.cpp:183
msgid "Sorry, kicker configuration is temporarily disabled."
msgstr "Sorry, kicker configuratie is tijdelijk uitgeschakeld."
@@ -8244,7 +8260,7 @@ msgstr "Sorry, kicker configuratie is tijdelijk uitgeschakeld."
msgid "Sorry, memo option setting is temporarily disabled."
msgstr "Sorry, memo opties instellen is tijdelijk uitgeschakeld."
-#: include/language.h:116
+#: include/language.h:117
msgid "Sorry, memo sending is temporarily disabled."
msgstr "Sorry, het versturen van memo's is tijdelijk uitgeschakeld."
@@ -8256,7 +8272,7 @@ msgstr "Sorry, nicknames kunnen tijdelijk niet verwijderd worden."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Sorry, nickname groeperingen zijn tijdelijk uitgeschakeld."
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:125
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Sorry, nickname registratie is tijdelijk uitgeschakeld."
@@ -8284,8 +8300,8 @@ msgstr "Sorry, de memo negeerlijst voor %s is vol."
#: modules/commands/cs_xop.cpp:205
#, c-format
msgid ""
-"Sorry, you can only have %d access entries on a channel, including access entries "
-"from other channels."
+"Sorry, you can only have %d access entries on a channel, including access "
+"entries from other channels."
msgstr ""
"Sorry, je kan maar %d toegangsvermeldingen hebben op een kanaal, inclusief "
"toegangsvermeldingen van andere kanalen."
@@ -8300,21 +8316,21 @@ msgstr "Sorry, je kan maar %d autokick maskers op een kanaal hebben."
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Sorry, je kan maar %d slechte woorden per kanaal instellen."
-#: include/language.h:103
+#: include/language.h:104
#, c-format
msgid "Sorry, you have already exceeded your limit of %d channels."
msgstr "Sorry, je hebt het maximum aantal kanalen van %d al overschreden."
-#: include/language.h:102
+#: include/language.h:103
#, c-format
msgid "Sorry, you have already reached your limit of %d channels."
msgstr "Sorry, je hebt het maximum aantal kanalen van %d al bereikt."
-#: modules/commands/os_dns.cpp:218
+#: modules/commands/os_dns.cpp:217
msgid "State"
msgstr "Staat"
-#: modules/commands/cs_seen.cpp:117
+#: modules/commands/cs_seen.cpp:118
msgid "Statistics and maintenance for seen data"
msgstr "Statistieken en onderhoud van seen gegevens"
@@ -8326,19 +8342,19 @@ msgstr "Statistieken gereset."
msgid "Status updated (memos, vhost, chmodes, flags)."
msgstr "Status geüpdatet (memo's, vHost, kanaalmodes, vlaggen)."
-#: modules/commands/bs_kick.cpp:1432
+#: modules/commands/bs_kick.cpp:1421
msgid "Stop flooding!"
msgstr "Stop met flooden!"
-#: modules/commands/bs_kick.cpp:1448
+#: modules/commands/bs_kick.cpp:1437
msgid "Stop repeating yourself!"
msgstr "Stop met jezelf te herhalen!"
-#: modules/commands/cs_set.cpp:757
+#: modules/commands/cs_set.cpp:758
msgid "Stricter control of channel founder status"
msgstr "Striktere controle van de kanaalstichter status"
-#: modules/commands/cs_set.cpp:821
+#: modules/commands/cs_set.cpp:822
msgid "Stricter control of chanop status"
msgstr "Striktere controle van de kanaaloperator status"
@@ -8346,20 +8362,22 @@ msgstr "Striktere controle van de kanaaloperator status"
msgid "Successor"
msgstr "Opvolger"
-#: modules/commands/cs_set.cpp:1017
+#: modules/commands/cs_set.cpp:1018
#, c-format
msgid "Successor for %s changed to %s."
msgstr "Opvolger voor %s veranderd naar %s."
-#: modules/commands/cs_set.cpp:1019
+#: modules/commands/cs_set.cpp:1020
#, c-format
msgid "Successor for %s unset."
msgstr "Opvolger voor %s verwijderd."
#: modules/commands/os_set.cpp:81
-msgid "Super admin can not be set because it is not enabled in the configuration."
+msgid ""
+"Super admin can not be set because it is not enabled in the configuration."
msgstr ""
-"Super Administrator instelling is niet ingeschakeld in het configuratiebestand."
+"Super Administrator instelling is niet ingeschakeld in het "
+"configuratiebestand."
#: modules/commands/ns_suspend.cpp:60
msgid "Suspend a given nick"
@@ -8413,7 +8431,7 @@ msgstr ""
msgid "Syncs the vhost for all nicks in a group"
msgstr "Stelt de vHost voor alle nicks in een groep gelijk"
-#: src/command.cpp:146
+#: src/command.cpp:147
msgid "Syntax"
msgstr "Gebruik"
@@ -8711,7 +8729,7 @@ msgstr ""
"informatie veld de text \"Juped by <nick>\" bevatten, waar\n"
"<nick> vervangen wordt door de nick die de server blokkeerde."
-#: modules/commands/cs_seen.cpp:261
+#: modules/commands/cs_seen.cpp:257
msgid "Tells you about the last time a user was seen"
msgstr "Vertelt je wanneer iemand het laatst gezien is"
@@ -8793,22 +8811,24 @@ msgstr ""
#: modules/commands/cs_flags.cpp:447
msgid ""
-"The CLEAR command clears the channel access list. This requires channel founder "
-"access."
+"The CLEAR command clears the channel access list. This requires channel "
+"founder access."
msgstr ""
"Het CLEAR commando maakt de toegangslijst leeg, dit vereist stichter rechten."
-#: modules/commands/cs_seen.cpp:173
+#: modules/commands/cs_seen.cpp:174
#, c-format
msgid ""
-"The CLEAR command lets you clean the database by removing all entries from the\n"
+"The CLEAR command lets you clean the database by removing all entries from "
+"the\n"
"database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-"Het CLEAR commando laat je de database opkuisen door het verwijderen van alle\n"
+"Het CLEAR commando laat je de database opkuisen door het verwijderen van "
+"alle\n"
"vermeldingen die binnen tijd zijn toegevoegd.\n"
" \n"
"Voorbeeld:\n"
@@ -8890,7 +8910,7 @@ msgstr ""
"Het ENTRYMSG LIST commando toont een lijst van berichten\n"
"die naar gebruikers gestuurd worden wanneer ze het kanaal betreden."
-#: modules/commands/ns_set.cpp:705
+#: modules/commands/ns_set.cpp:699
msgid "The IMMED option is not available on this network."
msgstr "De IMMED optie is niet beschikbaar op dit netwerk."
@@ -8939,31 +8959,34 @@ msgstr ""
#: modules/commands/cs_flags.cpp:442
msgid ""
-"The LIST command allows you to list existing entries on the channel access list.\n"
-"If a mask is given, the mask is wildcard matched against all existing entries on "
-"the\n"
-"access list, and only those entries are returned. If a set of flags is given, "
-"only those\n"
+"The LIST command allows you to list existing entries on the channel access "
+"list.\n"
+"If a mask is given, the mask is wildcard matched against all existing "
+"entries on the\n"
+"access list, and only those entries are returned. If a set of flags is "
+"given, only those\n"
"on the access list with the specified flags are returned."
msgstr ""
-"The LIST command allows you to list existing entries on the channel access list.\n"
-"If a mask is given, the mask is wildcard matched against all existing entries on "
-"the\n"
-"access list, and only those entries are returned. If a set of flags is given, "
-"only those\n"
+"The LIST command allows you to list existing entries on the channel access "
+"list.\n"
+"If a mask is given, the mask is wildcard matched against all existing "
+"entries on the\n"
+"access list, and only those entries are returned. If a set of flags is "
+"given, only those\n"
"on the access list with the specified flags are returned."
#: modules/commands/cs_flags.cpp:435
msgid ""
"The MODIFY command allows you to modify the access list. If the mask is\n"
"not already on the access list it is added, then the changes are applied.\n"
-"If the mask has no more flags, then the mask is removed from the access list.\n"
-"Additionally, you may use +* or -* to add or remove all flags, respectively. You "
-"are\n"
+"If the mask has no more flags, then the mask is removed from the access "
+"list.\n"
+"Additionally, you may use +* or -* to add or remove all flags, respectively. "
+"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of what "
-"your access is."
+"and even then you can only give other people access to the equivalent of "
+"what your access is."
msgstr ""
"Het MODIFY commando laat je toe de toegangslijst aan te passen.\n"
"Als het masker nog niet op de lijst staat, dan wordt deze toegevoegd en\n"
@@ -8974,12 +8997,14 @@ msgstr ""
"hiertoe hebt op het kanaal, en dan nog kan je enkel maar anderen\n"
"toevoegen tot maximum het toegangsniveau dat je zelf hebt."
-#: modules/commands/cs_seen.cpp:172
-msgid "The STATS command prints out statistics about stored nicks and memory usage."
+#: modules/commands/cs_seen.cpp:173
+msgid ""
+"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-"Het STATS commando toont statistieken over opgeslagen nicks en geheugenverbruik."
+"Het STATS commando toont statistieken over opgeslagen nicks en "
+"geheugenverbruik."
-#: modules/commands/ns_register.cpp:284
+#: modules/commands/ns_register.cpp:270
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -9038,17 +9063,17 @@ msgstr ""
" Dit zou een bericht sturen naar alle kanaal operators wanneer\n"
" iemand het ACCESS commando in ChanServ gebruikt op het kanaal."
-#: modules/commands/cs_ban.cpp:64
+#: modules/commands/cs_ban.cpp:65
#, c-format
msgid "The %s list for %s is full."
msgstr "De %s-lijst voor %s is vol."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, c-format
msgid "The %s list has been cleared."
msgstr "De %s lijst is leeggemaakt."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "De AKILL lijst is leeggemaakt."
@@ -9066,7 +9091,8 @@ msgstr ""
#: modules/commands/ns_info.cpp:172
#, c-format
msgid "The E-mail address of %s will now be shown in %s INFO displays."
-msgstr "Het e-mailadres van %s zal vanaf nu getoond worden in %s INFO opvragingen."
+msgstr ""
+"Het e-mailadres van %s zal vanaf nu getoond worden in %s INFO opvragingen."
#: modules/commands/cs_flags.cpp:449
msgid "The available flags are:"
@@ -9082,12 +9108,12 @@ msgstr ""
"set van restricties op de services toe te passen tijdens een\n"
"aanval op het netwerk."
-#: modules/ns_maxemail.cpp:51
+#: modules/ns_maxemail.cpp:30
#, c-format
msgid "The email address %s has reached its usage limit of %d users."
msgstr "Het e-mailadres %s heeft de limiet bereikt van %d gebruikers."
-#: modules/ns_maxemail.cpp:49
+#: modules/ns_maxemail.cpp:28
#, c-format
msgid "The email address %s has reached its usage limit of 1 user."
msgstr "Het e-mailadres %s heeft de limiet bereikt van 1 gebruiker."
@@ -9112,11 +9138,11 @@ msgstr ""
#: modules/commands/os_session.cpp:240
#, c-format
msgid ""
-"The host %s currently has %d sessions with a limit of %d because it matches entry:"
-" %s."
+"The host %s currently has %d sessions with a limit of %d because it matches "
+"entry: %s."
msgstr ""
-"Host %s heeft momenteel %d sessies met een limiet van %d omdat het overeenstemt "
-"met: %s."
+"Host %s heeft momenteel %d sessies met een limiet van %d omdat het "
+"overeenstemt met: %s."
#: modules/commands/ms_check.cpp:54
#, c-format
@@ -9126,33 +9152,38 @@ msgstr "De laatste memo die je naar %s gestuurd hebt (op %s) is gelezen."
#: modules/commands/ms_check.cpp:52
#, c-format
msgid "The last memo you sent to %s (sent on %s) has not yet been read."
-msgstr "De laatste memo die je naar %s gestuurd hebt (op %s) is nog niet gelezen."
+msgstr ""
+"De laatste memo die je naar %s gestuurd hebt (op %s) is nog niet gelezen."
#: modules/commands/ns_info.cpp:189
#, c-format
msgid "The last quit message of %s will now be hidden from %s INFO displays."
msgstr ""
-"De laatste quit reden van %s zal vanaf nu verborgen worden in %s INFO opvragingen."
+"De laatste quit reden van %s zal vanaf nu verborgen worden in %s INFO "
+"opvragingen."
#: modules/commands/ns_info.cpp:190
#, c-format
msgid "The last quit message of %s will now be shown in %s INFO displays."
msgstr ""
-"De laatste quit reden van %s zal vanaf nu getoond worden in %s INFO opvragingen."
+"De laatste quit reden van %s zal vanaf nu getoond worden in %s INFO "
+"opvragingen."
#: modules/commands/ns_info.cpp:177
#, c-format
-msgid "The last seen user@host mask of %s will now be hidden from %s INFO displays."
+msgid ""
+"The last seen user@host mask of %s will now be hidden from %s INFO displays."
msgstr ""
-"Het laatst geziene ident@host masker van %s zal vanaf nu verborgen worden in %s "
-"INFO opvragingen."
+"Het laatst geziene ident@host masker van %s zal vanaf nu verborgen worden in "
+"%s INFO opvragingen."
#: modules/commands/ns_info.cpp:178
#, c-format
-msgid "The last seen user@host mask of %s will now be shown in %s INFO displays."
+msgid ""
+"The last seen user@host mask of %s will now be shown in %s INFO displays."
msgstr ""
-"Het laatst geziene ident@host masker van %s zal vanaf nu getoond worden in %s "
-"INFO opvragingen."
+"Het laatst geziene ident@host masker van %s zal vanaf nu getoond worden in "
+"%s INFO opvragingen."
#: modules/commands/cs_enforce.cpp:190
#, c-format
@@ -9178,7 +9209,7 @@ msgstr "De mode blokkeerlijst van %s is vol."
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr "De nieuwe weergave MOET een nick zijn van de nick-groep %s."
-#: include/language.h:98
+#: include/language.h:99
#, c-format
msgid "The new display is now %s."
msgstr "De nieuwe weergave is nu %s."
@@ -9204,7 +9235,8 @@ msgstr "De oper infolijst voor %s is vol."
#: modules/commands/ns_info.cpp:183
#, c-format
-msgid "The services access status of %s will now be hidden from %s INFO displays."
+msgid ""
+"The services access status of %s will now be hidden from %s INFO displays."
msgstr ""
"Het services toegangsniveau van %s zal vanaf nu verborgen worden in %s INFO "
"opvragingen."
@@ -9220,7 +9252,7 @@ msgstr ""
msgid "The session exception list is empty."
msgstr "De uitzonderingenlijst voor sessielimieten is leeg."
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:104
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9228,7 +9260,7 @@ msgstr ""
"De gebruiker met jouw nick werd verwijderd. Gebruik dit commando\n"
"opnieuw om Services' blokkade op jouw nick op te heffen."
-#: modules/pseudoclients/memoserv.cpp:184
+#: modules/pseudoclients/memoserv.cpp:183
#, c-format
msgid "There are %d memos on channel %s."
msgstr "Er zijn %d memo's op kanaal %s."
@@ -9241,7 +9273,7 @@ msgstr ""
"Er zijn momenteel geen bots beschikbaar.\n"
"Vraag een Services Operator om er een te maken!"
-#: modules/commands/os_dns.cpp:213
+#: modules/commands/os_dns.cpp:212
msgid "There are no configured servers."
msgstr "Er zijn geen servers ingesteld."
@@ -9259,12 +9291,12 @@ msgstr "Er zijn teveel nicks in je groep."
msgid "There currently are no logging configurations for %s."
msgstr "Er zijn momenteel geen log instellingen voor %s."
-#: modules/pseudoclients/memoserv.cpp:182
+#: modules/pseudoclients/memoserv.cpp:181
#, c-format
msgid "There is %d memo on channel %s."
msgstr "Er is %d memo op kanaal %s."
-#: include/language.h:110
+#: include/language.h:111
#, c-format
msgid ""
"There is a new memo on channel %s.\n"
@@ -9321,24 +9353,28 @@ msgstr "Dit kanaal is geschorst."
msgid "This channel may not be used."
msgstr "Dit kanaal mag niet gebruikt worden."
-#: modules/commands/os_dns.cpp:702
+#: modules/commands/os_dns.cpp:701
msgid ""
-"This command allows managing DNS zones used for controlling what servers users\n"
-"are directed to when connecting. Omitting all parameters prints out the status "
-"of\n"
+"This command allows managing DNS zones used for controlling what servers "
+"users\n"
+"are directed to when connecting. Omitting all parameters prints out the "
+"status of\n"
"the DNS zone.\n"
" \n"
-"ADDZONE adds a zone, eg us.yournetwork.tld. Servers can then be added to this\n"
+"ADDZONE adds a zone, eg us.yournetwork.tld. Servers can then be added to "
+"this\n"
"zone with the ADDSERVER command.\n"
" \n"
-"The ADDSERVER command adds a server to the given zone. When a query is done, the\n"
+"The ADDSERVER command adds a server to the given zone. When a query is done, "
+"the\n"
"zone in question is served if it exists, else all servers in all zones are "
"served.\n"
"A server may be in more than one zone.\n"
" \n"
"The ADDIP command associates an IP with a server.\n"
" \n"
-"The POOL and DEPOOL commands actually add and remove servers to their given zones."
+"The POOL and DEPOOL commands actually add and remove servers to their given "
+"zones."
msgstr ""
"Dit commando laat toe om domeinnamen te beheren voor het beheren van\n"
"naar welke servers gebruikers worden doorverwezen wanneer ze verbinden.\n"
@@ -9366,7 +9402,7 @@ msgstr ""
"HUIDIGE nick de vHost van alle nicks in dezelfde groep te\n"
"laten zijn."
-#: modules/commands/ns_register.cpp:292
+#: modules/commands/ns_register.cpp:278
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9377,12 +9413,12 @@ msgstr ""
"dit zal je toelaten andere nicks te registreren die dan je instellingen,\n"
"memo's en kanaalrechten delen."
-#: modules/m_rewrite.cpp:145
+#: modules/m_rewrite.cpp:144
#, c-format
msgid "This command is an alias to the command %s."
msgstr "Dit commando is een alias voor het commando %s."
-#: modules/commands/ns_register.cpp:95
+#: modules/commands/ns_register.cpp:81
msgid ""
"This command is used by several commands as a way to confirm\n"
"changes made to your account.\n"
@@ -9499,19 +9535,19 @@ msgstr ""
"Services Operators kunnen een nick opgeven om anderen hun\n"
"autojoinlijsten aan te passen."
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:661
+#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
msgstr ""
-"Dit commando mag niet gebruikt worden op dit netwerk om dat eigenaarschap over "
-"nicknames uitgeschakeld is."
+"Dit commando mag niet gebruikt worden op dit netwerk om dat eigenaarschap "
+"over nicknames uitgeschakeld is."
#: modules/commands/os_module.cpp:118
msgid "This command reloads the module named modname."
msgstr "Dit commando herlaad de module genaamd modnaam."
-#: modules/commands/hs_request.cpp:344
+#: modules/commands/hs_request.cpp:345
msgid "This command retrieves the vhost requests."
msgstr "Dit commando toont de aangevraagde vHosts."
@@ -9540,7 +9576,7 @@ msgstr ""
" Doorzoekt de laatste 21 dagen aan log voor berichten\n"
" die Anope bevatten en toont de 500 recentste resultaten."
-#: modules/commands/cs_status.cpp:106
+#: modules/commands/cs_status.cpp:91
msgid ""
"This command tells you what a users access is on a channel\n"
"and what access entries, if any, they match. Additionally it\n"
@@ -9571,11 +9607,12 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "Dit commando ontlaadt de module genaamd modnaam."
-#: modules/commands/ns_register.cpp:346
+#: modules/commands/ns_register.cpp:332
msgid "This command will resend you the registration confirmation email."
-msgstr "Dit commando zal je de registratiebevestigings-e-mail opnieuw toezenden."
+msgstr ""
+"Dit commando zal je de registratiebevestigings-e-mail opnieuw toezenden."
-#: include/language.h:90
+#: include/language.h:91
#, c-format
msgid ""
"This nick is owned by someone else. Please choose another.\n"
@@ -9589,12 +9626,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Deze nickname is verboden: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, c-format
msgid "This nickname has been recovered by %s."
msgstr "Deze nickname werd opgeëist door %s."
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -9603,7 +9640,7 @@ msgstr ""
"Deze nickname werd opgeëist door %s. Indien jij dit niet deed,\n"
"dan kan het zijn dat %s je wachtwoord heeft, en wijzig je deze best."
-#: include/language.h:95
+#: include/language.h:96
msgid "This nickname has been registered; you may not use it."
msgstr "Deze nickname is geregistreerd; je mag het niet gebruiken."
@@ -9611,7 +9648,7 @@ msgstr "Deze nickname is geregistreerd; je mag het niet gebruiken."
msgid "This nickname is suspended."
msgstr "Deze nick is geschorst."
-#: include/language.h:92
+#: include/language.h:93
#, c-format
msgid ""
"This nickname is registered and protected. If it is your\n"
@@ -9622,21 +9659,21 @@ msgstr ""
"jouw nickname is, typ %s%s IDENTIFY wachtwoord.\n"
"Gelieve anders een andere nickname te kiezen."
-#: modules/commands/ms_read.cpp:95
+#: modules/commands/ms_read.cpp:86
#, c-format
msgid "To delete, type: %s%s %s %d"
msgstr "Om te verwijderen, typ: %s%s %s %d"
-#: modules/commands/ms_read.cpp:93
+#: modules/commands/ms_read.cpp:84
#, c-format
msgid "To delete, type: %s%s %s %s %d"
msgstr "Om te verwijderen, typ: %s%s %s %s %d"
-#: modules/commands/bs_kick.cpp:791
+#: modules/commands/bs_kick.cpp:780
msgid "To protect ops against bot kicks"
msgstr "Om operators te beschermen tegen bot kicks"
-#: modules/commands/bs_kick.cpp:856
+#: modules/commands/bs_kick.cpp:845
msgid "To protect voices against bot kicks"
msgstr "Om voices te beschermen tegen bot kicks"
@@ -9690,19 +9727,20 @@ msgstr "Topicbehoud-optie voor %s is nu geactiveerd."
msgid "Topic set by"
msgstr "Topic gezet door"
-#: modules/commands/bs_kick.cpp:1323
+#: modules/commands/bs_kick.cpp:1312
msgid "Turn caps lock OFF!"
msgstr "Zet hoofdletters UIT!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
msgid "Turn chanstats statistics on or off"
msgstr "Zet chanstats statistieken aan of uit"
-#: modules/commands/ns_set.cpp:1001
+#: modules/commands/ns_set.cpp:992
msgid "Turn nickname security on or off"
msgstr "Zet nickname beveiliging aan of uit"
-#: modules/commands/ns_set.cpp:647
+#: modules/commands/ns_set.cpp:641
msgid "Turn protection on or off"
msgstr "Zet bescherming aan of uit"
@@ -9736,7 +9774,7 @@ msgstr ""
"iedereen die je nick weet kan nog steeds informatie krijgen\n"
"via het INFO commando."
-#: modules/commands/ns_set.cpp:1051 modules/commands/ns_set.cpp:1080
+#: modules/commands/ns_set.cpp:1042 modules/commands/ns_set.cpp:1071
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9763,7 +9801,7 @@ msgstr "Zet chanstats statistieken aan of uit."
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr "Zet chanstats kanaal statistieken aan of uit voor deze gebruiker."
-#: modules/commands/ns_set.cpp:764
+#: modules/commands/ns_set.cpp:758
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9793,7 +9831,7 @@ msgstr ""
"Deze optie kan ook uitgeschakeld zijn door de netwerk\n"
"administrators."
-#: modules/commands/ns_set.cpp:730
+#: modules/commands/ns_set.cpp:724
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -9836,7 +9874,7 @@ msgstr ""
"Typ %s%s HELP %s optie voor meer informatie\n"
"over een specifieke optie."
-#: modules/commands/bs_kick.cpp:151
+#: modules/commands/bs_kick.cpp:153
#, c-format
msgid ""
"Type %s%s HELP %s option for more information\n"
@@ -9886,7 +9924,7 @@ msgstr ""
msgid "Un-Load a module"
msgstr "Ontlaad een module"
-#: modules/commands/os_sxline.cpp:337 modules/commands/os_sxline.cpp:552
+#: modules/commands/os_sxline.cpp:331 modules/commands/os_sxline.cpp:545
#: modules/commands/os_akill.cpp:136
#, c-format
msgid "Unable to find regex engine %s."
@@ -9921,12 +9959,12 @@ msgstr ""
"zodat je later de bot altijd opnieuw aan het kanaal kan\n"
"toewijzen zonder dat je deze opnieuw hoeft te configureren."
-#: modules/commands/bs_kick.cpp:1191 modules/commands/bs_kick.cpp:1193
-#: modules/commands/bs_kick.cpp:1196
+#: modules/commands/bs_kick.cpp:1180 modules/commands/bs_kick.cpp:1182
+#: modules/commands/bs_kick.cpp:1185
msgid "Underlines kicker"
msgstr "Onderlijningskicker"
-#: modules/commands/os_dns.cpp:595
+#: modules/commands/os_dns.cpp:594
msgid "Unknown SET option."
msgstr "Onbekende SET optie."
@@ -9935,12 +9973,12 @@ msgstr "Onbekende SET optie."
msgid "Unknown STATS option: %s"
msgstr "Onbekende STATS optie %s"
-#: src/command.cpp:222 src/command.cpp:233
+#: src/command.cpp:223 src/command.cpp:234
#, c-format
msgid "Unknown command %s."
msgstr "Onbekend commando %s."
-#: src/command.cpp:220 src/command.cpp:231
+#: src/command.cpp:221 src/command.cpp:232
#, c-format
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Onbekend commando %s. \"%s%s HELP\" voor hulp."
@@ -9955,7 +9993,7 @@ msgstr "Onbekende mode karakter %c genegeerd."
msgid "Unknown parameter: %s"
msgstr "Onbekend parameter: %s"
-#: modules/commands/os_dns.cpp:241
+#: modules/commands/os_dns.cpp:240
msgid "Unpooled"
msgstr "Niet pooled"
@@ -10001,7 +10039,8 @@ msgstr "Werkt de gegeven nick's status bij op een kanaal"
#: modules/commands/ns_update.cpp:19
msgid "Updates your current status, i.e. it checks for new memos"
-msgstr "Werkt je huidige status bij, het controleert bijvoorbeeld op nieuwe memo's"
+msgstr ""
+"Werkt je huidige status bij, het controleert bijvoorbeeld op nieuwe memo's"
#: modules/commands/ns_update.cpp:43
msgid ""
@@ -10033,7 +10072,7 @@ msgid "Use the %s ALL command to list all commands and their descriptions."
msgstr ""
"Gebruik het %s ALL commando om alle commando's en hun omschrijving te tonen."
-#: modules/commands/bs_info.cpp:59
+#: modules/commands/bs_info.cpp:60
msgid "Used on"
msgstr "Gebruikt op"
@@ -10049,16 +10088,16 @@ msgstr "Dient om de lijst van gebruikers met privileges te beheren"
msgid "Used to modify the channel status of you or other users"
msgstr "Dient om de kanaalstatus van jezelf of anderen aan te passen"
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:559
msgid "User has been banned from the channel"
msgstr "Gebruiker werd verbannen van het kanaal"
-#: modules/commands/os_dns.cpp:587
+#: modules/commands/os_dns.cpp:586
#, c-format
msgid "User limit for %s removed."
msgstr "Gebruikerslimiet voor %s verwijderd."
-#: modules/commands/os_dns.cpp:585
+#: modules/commands/os_dns.cpp:584
#, c-format
msgid "User limit for %s set to %d."
msgstr "Gebruikerslimiet voor %s gewijzigd naar %d."
@@ -10109,8 +10148,8 @@ msgstr "vHost voor groep %s gewijzigd naar %s@%s."
msgid "VIEW host"
msgstr "VIEW host"
-#: modules/commands/os_sxline.cpp:428 modules/commands/os_sxline.cpp:662
-#: modules/commands/os_akill.cpp:389
+#: modules/commands/os_sxline.cpp:421 modules/commands/os_sxline.cpp:654
+#: modules/commands/os_akill.cpp:383
msgid "VIEW [mask | list | id]"
msgstr "VIEW [masker | lijst | id]"
@@ -10127,7 +10166,7 @@ msgstr "Waarde"
msgid "Value of %s:%s changed to %s"
msgstr "Waarde van %s:%s gewijzigd naar %s"
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:305
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
msgid "Vhost"
msgstr "vHost"
@@ -10148,11 +10187,11 @@ msgstr "Bekijk en wijzig configuratiebestand's instellingen"
msgid "View the list of host sessions"
msgstr "Bekijk de host sessielijst"
-#: modules/commands/bs_kick.cpp:1221
+#: modules/commands/bs_kick.cpp:1210
msgid "Voices protection"
msgstr "Voices bescherming"
-#: modules/commands/bs_kick.cpp:1406
+#: modules/commands/bs_kick.cpp:1395
msgid "Watch your language!"
msgstr "Let op je taal!"
@@ -10165,7 +10204,7 @@ msgstr ""
"Wanneer private geactiveerd is, zal het kanaal niet verschijnen in\n"
"%s's %s commando."
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
msgid ""
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
@@ -10255,7 +10294,7 @@ msgstr "Woord"
msgid "You are already a member of the group of %s."
msgstr "Je bent al lid van de groep van %s."
-#: modules/commands/os_login.cpp:34 modules/commands/ns_identify.cpp:87
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:87
msgid "You are already identified."
msgstr "Je bent al geïdentificeerd."
@@ -10268,11 +10307,11 @@ msgstr "Je bent al op %s!"
msgid "You are no longer a super admin."
msgstr "Je bent geen super administrator meer."
-#: modules/commands/os_login.cpp:81
+#: modules/commands/os_login.cpp:82
msgid "You are not identified."
msgstr "Je bent niet geïdentificeerd."
-#: include/language.h:100
+#: include/language.h:101
msgid "You are not permitted to be on this channel."
msgstr "Je hebt geen toestemming om op dit kanaal aanwezig te zijn."
@@ -10301,14 +10340,14 @@ msgstr "Je bent nu geïdentificeerd voor je nick. Wijzig nu je wachtwoord."
msgid "You are now in the group of %s."
msgstr "Je zit nu in de groep van %s."
-#: modules/pseudoclients/memoserv.cpp:136
+#: modules/pseudoclients/memoserv.cpp:135
#, c-format
msgid ""
-"You are over your maximum number of memos (%d). You will be unable to receive any "
-"new memos until you delete some of your current ones."
+"You are over your maximum number of memos (%d). You will be unable to "
+"receive any new memos until you delete some of your current ones."
msgstr ""
-"Je hebt je maximum aantal memo's overschreden (%d). Je kan geen nieuwe memo's "
-"ontvangen totdat je enkele van je huidige memo's verwijdert."
+"Je hebt je maximum aantal memo's overschreden (%d). Je kan geen nieuwe "
+"memo's ontvangen totdat je enkele van je huidige memo's verwijdert."
#: modules/commands/os_noop.cpp:33
msgid "You can not NOOP Services."
@@ -10319,8 +10358,8 @@ msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
msgstr ""
-"Je kan de stichter privilege niet uitschakelen, want het zou onmogelijk zijn dit "
-"later weer in te schakelen."
+"Je kan de stichter privilege niet uitschakelen, want het zou onmogelijk zijn "
+"dit later weer in te schakelen."
#: modules/commands/os_jupe.cpp:34
msgid "You can not jupe an already juped server."
@@ -10342,7 +10381,7 @@ msgstr ""
"Je kan geen ontvangstbevestiging aanvragen voor een memo die je naar jezelf "
"stuurt."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/ns_recover.cpp:145
#, c-format
msgid "You can't %s yourself!"
msgstr "Je kan geen %s doen op jezelf!"
@@ -10357,7 +10396,7 @@ msgstr "Je kan geen kanaal toevoegen op zijn eigen toegangslijst."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Je kan %s niet uitloggen omdat hij een Services Operator is."
-#: modules/commands/ns_set.cpp:919
+#: modules/commands/ns_set.cpp:910
#, c-format
msgid "You cannot %s on this network."
msgstr "Je kan geen %s doen op dit netwerk."
@@ -10380,10 +10419,10 @@ msgstr "Je kan je memolimiet niet hoger dan %d zetten."
#: modules/commands/bs_assign.cpp:124
msgid "You cannot unassign bots while persist is set on the channel."
msgstr ""
-"Je kan geen bottoewijzingen ongedaan maken zolang persist geactiveerd is op het "
-"kanaal."
+"Je kan geen bottoewijzingen ongedaan maken zolang persist geactiveerd is op "
+"het kanaal."
-#: modules/commands/ns_set.cpp:475
+#: modules/commands/ns_set.cpp:469
msgid "You cannot unset the e-mail on this network."
msgstr "Je kan het e-mailadres niet verwijderen op dit netwerk."
@@ -10433,21 +10472,21 @@ msgstr "Je hebt geen toegang om mode %c te zetten."
msgid "You do not have the access to change %s's modes."
msgstr "Je hebt geen toegang om %s's modes te veranderen."
-#: modules/commands/cs_seen.cpp:198
+#: modules/commands/cs_seen.cpp:199
#, c-format
msgid "You found me, %s!"
msgstr "Je hebt me gevonden, %s!"
-#: modules/pseudoclients/memoserv.cpp:132
+#: modules/pseudoclients/memoserv.cpp:131
#, c-format
msgid "You have %d new memos."
msgstr "Je hebt %d nieuwe memo's."
-#: modules/pseudoclients/memoserv.cpp:132
+#: modules/pseudoclients/memoserv.cpp:131
msgid "You have 1 new memo."
msgstr "Je hebt 1 nieuwe memo."
-#: include/language.h:112
+#: include/language.h:113
#, c-format
msgid ""
"You have a new memo from %s.\n"
@@ -10466,12 +10505,12 @@ msgstr "Je bent uitgenodigd naar %s door %s."
msgid "You have been invited to %s."
msgstr "Je bent uitgenodigd naar %s."
-#: modules/protocol/ratbox.cpp:137 modules/commands/ns_recover.cpp:96
+#: modules/protocol/ratbox.cpp:137
#, c-format
msgid "You have been logged in as %s."
msgstr "Je bent ingelogd als %s."
-#: modules/commands/os_login.cpp:86
+#: modules/commands/os_login.cpp:87
msgid "You have been logged out."
msgstr "Je bent uitgelogd."
@@ -10489,27 +10528,27 @@ msgstr "Je ban werd op %d kana(a)l(en) opgeheven."
msgid "You have no limit on the number of memos you may keep."
msgstr "Je hebt geen limiet op het aantal memo's dat je mag hebben."
-#: include/language.h:114
+#: include/language.h:115
msgid "You have no memos."
msgstr "Je hebt geen memo's."
-#: include/language.h:117
+#: include/language.h:118
msgid "You have no new memos."
msgstr "Je hebt geen nieuwe memo's."
-#: modules/pseudoclients/memoserv.cpp:138
+#: modules/pseudoclients/memoserv.cpp:137
#, c-format
msgid ""
-"You have reached your maximum number of memos (%d). You will be unable to receive "
-"any new memos until you delete some of your current ones."
+"You have reached your maximum number of memos (%d). You will be unable to "
+"receive any new memos until you delete some of your current ones."
msgstr ""
"Je hebt je maximum aantal memo's bereikt (%d). Je kan geen nieuwe memo's "
"ontvangen totdat je enkele van je huidige memo's verwijdert."
-#: modules/commands/ns_recover.cpp:117
+#: modules/commands/ns_recover.cpp:101
#, c-format
-msgid "You have regained control of %s."
-msgstr "Je hebt weer de controle over %s."
+msgid "You have regained control of %s and are now identified as %s."
+msgstr "Je hebt weer de controle over %s en bent nu geïdentificeerd als %s."
#: modules/commands/ns_drop.cpp:66
msgid "You may drop any nick within your group."
@@ -10520,11 +10559,11 @@ msgstr "Je kan de registraties van nicks in je groep verwijderen."
msgid "You may not (un)lock mode %c."
msgstr "Je mag mode %c niet (de)blokkeren."
-#: modules/commands/ns_set.cpp:480
+#: modules/commands/ns_set.cpp:474
msgid "You may not change the e-mail of other Services Operators."
msgstr "Je mag het e-mailadres van andere Services Operators niet wijzigen."
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:463
msgid "You may not change the email of an unconfirmed account."
msgstr "Je mag het e-mailadres van een onbevestigde account niet wijzigen."
@@ -10534,7 +10573,8 @@ msgstr "Je mag het wachtwoord van andere Services Operators niet wijzigen."
#: modules/commands/ns_drop.cpp:45
msgid "You may not drop other Services Operators' nicknames."
-msgstr "Je mag de nickregistraties van andere Services Operators niet verwijderen."
+msgstr ""
+"Je mag de nickregistraties van andere Services Operators niet verwijderen."
#: modules/commands/ns_getpass.cpp:32
msgid "You may not get the password of other Services Operators."
@@ -10545,7 +10585,8 @@ msgid "You may not suspend other Services Operators' nicknames."
msgstr "Je kan de nicks van andere Services Operators niet schorsen."
#: modules/commands/ns_access.cpp:136
-msgid "You may view but not modify the access list of other Services Operators."
+msgid ""
+"You may view but not modify the access list of other Services Operators."
msgstr ""
"Je kan de toegangslijst van andere Services Operators bekijken, maar niet "
"aanpassen."
@@ -10557,12 +10598,12 @@ msgstr ""
"Je kan de certificaatlijst van andere Services Operators bekijken, maar niet "
"aanpassen."
-#: modules/commands/cs_seen.cpp:286
+#: modules/commands/cs_seen.cpp:282
#, c-format
msgid "You might see yourself in the mirror, %s."
msgstr "Je kan jezelf misschien zien in de spiegel, %s."
-#: include/language.h:120
+#: include/language.h:121
msgid "You must assign a bot to the channel before using this command."
msgstr ""
"Je moet een bot toewijzen aan het kanaal alvorens dit commando te gebruiken."
@@ -10580,7 +10621,7 @@ msgstr "Je moet in %s zijn om dit commando te gebruiken."
msgid "You must confirm your account before you can register a channel."
msgstr "Je moet je nick bevestigen voor je een kanaal kan registreren."
-#: modules/commands/hs_request.cpp:100
+#: modules/commands/hs_request.cpp:101
msgid "You must confirm your account before you may request a vhost."
msgstr "Je moet je nick bevestigen voor je een vhost kan aanvragen."
@@ -10591,12 +10632,13 @@ msgstr "Je moet je nick bevestigen voor je een memo kan versturen."
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
-"You must enter the channel name twice as a confirmation that you wish to drop %s."
+"You must enter the channel name twice as a confirmation that you wish to drop"
+" %s."
msgstr ""
-"Je moet de kanaalnaam twee keer opgeven als bevestiging dat je de registratie van"
-" %s wenst ongedaan te maken."
+"Je moet de kanaalnaam twee keer opgeven als bevestiging dat je de "
+"registratie van %s wenst ongedaan te maken."
-#: modules/commands/ns_register.cpp:153
+#: modules/commands/ns_register.cpp:139
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr "Je moet deze nick tenminste %d seconden gebruiken om te registreren."
@@ -10605,7 +10647,8 @@ msgstr "Je moet deze nick tenminste %d seconden gebruiken om te registreren."
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
-"Je moet het %s(ME) privilege hebben op het kanaal om dit commando te gebruiken."
+"Je moet het %s(ME) privilege hebben op het kanaal om dit commando te "
+"gebruiken."
#: modules/pseudoclients/nickserv.cpp:358
msgid ""
@@ -10621,37 +10664,17 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "Je moet geïdentificeerd zijn om dit commando te gebruiken."
-#: modules/commands/ms_info.cpp:182
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr ""
-"Je wordt geïnformeerd over nieuwe memo's via berichten en e-mail wanneer deze "
-"aankomen."
-
-#: modules/commands/ms_info.cpp:175
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail when "
-"they arrive."
-msgstr ""
-"Je wordt geïnformeerd over nieuwe memo's wanneer je inlogt en wanneer deze "
-"aankomen, en via e-mail wanneer deze aankomen."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Je wordt geïnformeerd over nieuwe memo's wanneer je inlogt en wanneer deze "
"aankomen."
-#: modules/commands/ms_info.cpp:189
-msgid "You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Je wordt geïnformeerd over nieuwe memo's wanneer je inlogt, en via e-mail wanneer "
-"deze aankomen."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Je wordt geïnformeerd over nieuwe memo's wanneer je inlogt."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Je wordt geïnformeerd over nieuwe memo's wanneer deze aankomen."
@@ -10663,13 +10686,14 @@ msgstr "Je zal niet langer memo's ontvangen."
msgid "You will no longer be informed via email."
msgstr "Je wordt niet langer geïnformeerd via e-mail."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Je wordt niet op de hoogte gehouden over nieuwe memo's."
#: modules/commands/ms_set.cpp:49
msgid "You will now be informed about new memos via email."
-msgstr "Je zal zal nu op de hoogte worden gehouden van nieuwe memo's via e-mail."
+msgstr ""
+"Je zal zal nu op de hoogte worden gehouden van nieuwe memo's via e-mail."
#: modules/commands/os_svs.cpp:86
msgid "Your IRCd does not support SVSJOIN."
@@ -10683,30 +10707,30 @@ msgstr "Je IRCd ondersteunt geen SVSNICK."
msgid "Your IRCd does not support SVSPART."
msgstr "Je IRCd ondersteunt geen SVSPART."
-#: include/language.h:127
+#: include/language.h:128
msgid ""
-"Your IRCd does not support vIdent's, if this is incorrect, please report this as "
-"a possible bug"
+"Your IRCd does not support vIdent's, if this is incorrect, please report "
+"this as a possible bug"
msgstr ""
"Je IRCd ondersteunt geen vIdent's, indien dit niet klopt, gelieve dit dan te "
"melden als een fout"
-#: modules/extra/m_ldap_authentication.cpp:110
-#: modules/extra/m_sql_authentication.cpp:55
+#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Je account %s is succesvol aangemaakt."
-#: modules/commands/ns_register.cpp:321
+#: modules/commands/ns_register.cpp:307
msgid "Your account is already confirmed."
msgstr "Je account is reeds bevestigd."
-#: modules/commands/ns_register.cpp:389
+#: modules/commands/ns_register.cpp:375
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Je account verloopt, indien niet bevestigd, over %s."
-#: modules/commands/ns_set.cpp:1265
+#: modules/commands/ns_set.cpp:1256
#, c-format
msgid "Your email address has been changed to %s."
msgstr "Je e-mailadres werd gewijzigd naar %s."
@@ -10715,25 +10739,25 @@ msgstr "Je e-mailadres werd gewijzigd naar %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Je e-mailadres is niet toegelaten, kies een andere."
-#: modules/commands/ns_register.cpp:384
+#: modules/commands/ns_register.cpp:370
msgid ""
-"Your email address is not confirmed. To confirm it, follow the instructions that "
-"were emailed to you."
+"Your email address is not confirmed. To confirm it, follow the instructions "
+"that were emailed to you."
msgstr ""
-"Je e-mailadres is niet bevestigd. Om deze te bevestigen dien je de instructies te "
-"volgen in de toegezonden e-mail."
+"Je e-mailadres is niet bevestigd. Om deze te bevestigen dien je de "
+"instructies te volgen in de toegezonden e-mail."
-#: modules/commands/ns_register.cpp:67
+#: modules/commands/ns_register.cpp:53
#, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Je e-mailadres %s werd bevestigd."
-#: modules/extra/m_ldap_authentication.cpp:159
+#: modules/extra/m_ldap_authentication.cpp:151
#, c-format
msgid "Your email has been updated to %s"
msgstr "Je e-mail werd geüpdatet naar %s."
-#: modules/extra/m_sql_authentication.cpp:62
+#: modules/extra/m_sql_authentication.cpp:54
#, c-format
msgid "Your email has been updated to %s."
msgstr "Je e-mail werd geüpdatet naar %s."
@@ -10763,11 +10787,11 @@ msgstr "Je memolimiet is 0; je zal geen nieuwe memo's ontvangen."
#: modules/commands/ms_info.cpp:157
msgid ""
-"Your memo limit is 0; you will not receive any new memos. You cannot change this "
-"limit."
+"Your memo limit is 0; you will not receive any new memos. You cannot change "
+"this limit."
msgstr ""
-"Je memolimiet is 0; je zal geen nieuwe memo's ontvangen. Je kan deze limiet niet "
-"veranderen."
+"Je memolimiet is 0; je zal geen nieuwe memo's ontvangen. Je kan deze limiet "
+"niet veranderen."
#: modules/commands/ns_logout.cpp:50
msgid "Your nick has been logged out."
@@ -10781,7 +10805,7 @@ msgstr "Je nick is al geregistreerd."
msgid "Your nick is not grouped to anything, you can't ungroup it."
msgstr "Je nick behoort tot geen enkele groep, je kan dit dus niet uitvoeren."
-#: include/language.h:77
+#: include/language.h:78
msgid "Your nick isn't registered."
msgstr "Je nickname is niet geregistreerd."
@@ -10790,21 +10814,21 @@ msgstr "Je nickname is niet geregistreerd."
msgid "Your nickname is now being changed to %s"
msgstr "Je nickname wordt nu veranderd in %s"
-#: modules/commands/os_login.cpp:32 modules/commands/os_login.cpp:79
+#: modules/commands/os_login.cpp:33 modules/commands/os_login.cpp:80
msgid "Your oper block doesn't require logging in."
msgstr "Je oper blok vereist geen aanmelding."
-#: modules/commands/ns_register.cpp:329
+#: modules/commands/ns_register.cpp:315
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Je bevestingscode is opnieuw gestuurd naar %s."
-#: modules/commands/ns_register.cpp:232
+#: modules/commands/ns_register.cpp:218
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Je wachtwoord is %s - onthoudt dit voor later gebruik."
-#: include/language.h:76
+#: include/language.h:77
#, c-format
msgid "Your password is too long. It must not exceed %u characters."
msgstr "Je wachtwoord is te lang. Het mag niet langer zijn dan %u karakters."
@@ -10813,42 +10837,42 @@ msgstr "Je wachtwoord is te lang. Het mag niet langer zijn dan %u karakters."
msgid "Your password reset request has expired."
msgstr "Je wachtwoord-reset aanvraag is verlopen."
-#: modules/commands/hs_request.cpp:170
+#: modules/commands/hs_request.cpp:171
msgid "Your vHost has been requested."
msgstr "Je vHost werd aangevraagd."
-#: modules/pseudoclients/hostserv.cpp:64 modules/pseudoclients/hostserv.cpp:103
-#: modules/commands/hs_on.cpp:37
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Je vHost %s is nu geactiveerd."
-#: modules/pseudoclients/hostserv.cpp:62 modules/pseudoclients/hostserv.cpp:101
-#: modules/commands/hs_on.cpp:35
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Je vHost %s@%s is nu geactiveerd."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:36
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Je vHost werd verwijderd en de normale cloaking hersteld."
-#: modules/commands/os_dns.cpp:255
+#: modules/commands/os_dns.cpp:254
msgid "Zone"
msgstr "Domein"
-#: modules/commands/os_dns.cpp:290
+#: modules/commands/os_dns.cpp:289
#, c-format
msgid "Zone %s already exists."
msgstr "Domein %s bestaat al."
-#: modules/commands/os_dns.cpp:310 modules/commands/os_dns.cpp:352
-#: modules/commands/os_dns.cpp:402 modules/commands/os_dns.cpp:438
+#: modules/commands/os_dns.cpp:309 modules/commands/os_dns.cpp:351
+#: modules/commands/os_dns.cpp:401 modules/commands/os_dns.cpp:437
#, c-format
msgid "Zone %s does not exist."
msgstr "Domein %s bestaat niet."
-#: modules/commands/os_dns.cpp:332
+#: modules/commands/os_dns.cpp:331
#, c-format
msgid "Zone %s removed."
msgstr "Domein %s verwijderd."
@@ -10904,7 +10928,7 @@ msgstr "[kanaal] [nick]"
msgid "[channel] {num | list | LAST | ALL}"
msgstr "[kanaal] {nr | lijst | LAST | ALL}"
-#: modules/commands/ms_read.cpp:113
+#: modules/commands/ms_read.cpp:104
msgid "[channel] {num | list | LAST | NEW}"
msgstr "[kanaal] {nr | lijst | LAST | NEW}"
@@ -10953,20 +10977,20 @@ msgstr "[geschorst]"
msgid "[Unconfirmed]"
msgstr "[onbevestigd]"
-#: modules/commands/hs_request.cpp:213
+#: modules/commands/hs_request.cpp:214
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto memo] Uw aanvraag voor de vHost werd goedgekeurd."
-#: modules/commands/hs_request.cpp:267
+#: modules/commands/hs_request.cpp:268
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto memo] Uw aanvraag voor de vHost werd geweigerd."
-#: modules/commands/hs_request.cpp:265
+#: modules/commands/hs_request.cpp:266
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[auto memo] Uw aanvraag voor de vHost werd geweigerd. Reden: %s"
-#: modules/commands/hs_request.cpp:388
+#: modules/commands/hs_request.cpp:389
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] vHost %s aangevraagd door %s."
@@ -10979,67 +11003,67 @@ msgstr "[{patroon | kanaal} [INVISIBLE]]"
msgid "[{pattern | nick} [SECRET]]"
msgstr "[{patroon | nick} [SECRET]]"
-#: src/misc.cpp:337
+#: src/misc.cpp:338
msgid "day"
msgstr "dag"
-#: src/misc.cpp:337
+#: src/misc.cpp:338
msgid "days"
msgstr "dagen"
-#: include/language.h:88
+#: include/language.h:89
msgid "does not expire"
msgstr "verloopt niet"
-#: src/misc.cpp:384
+#: src/misc.cpp:385
#, c-format
msgid "expires in %d day"
msgstr "verloopt over %d dag"
-#: src/misc.cpp:384
+#: src/misc.cpp:385
#, c-format
msgid "expires in %d days"
msgstr "verloopt over %d dagen"
-#: src/misc.cpp:398
+#: src/misc.cpp:399
#, c-format
msgid "expires in %d hour, %d minute"
msgstr "verloopt over %d uur, %d minuut"
-#: src/misc.cpp:398
+#: src/misc.cpp:399
#, c-format
msgid "expires in %d hour, %d minutes"
msgstr "verloopt over %d uur, %d minuten"
-#: src/misc.cpp:398
+#: src/misc.cpp:399
#, c-format
msgid "expires in %d hours, %d minute"
msgstr "verloopt over %d uur, %d minuut"
-#: src/misc.cpp:398
+#: src/misc.cpp:399
#, c-format
msgid "expires in %d hours, %d minutes"
msgstr "verloopt over %d uur, %d minuten"
-#: src/misc.cpp:391
+#: src/misc.cpp:392
#, c-format
msgid "expires in %d minute"
msgstr "verloopt over %d minuut"
-#: src/misc.cpp:391
+#: src/misc.cpp:392
#, c-format
msgid "expires in %d minutes"
msgstr "verloopt over %d minuten"
-#: src/misc.cpp:375
+#: src/misc.cpp:376
msgid "expires momentarily"
msgstr "verloopt elk moment"
-#: src/misc.cpp:343
+#: src/misc.cpp:344
msgid "hour"
msgstr "uur"
-#: src/misc.cpp:343
+#: src/misc.cpp:344
msgid "hours"
msgstr "uur"
@@ -11048,37 +11072,37 @@ msgstr "uur"
msgid "letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"
msgstr "letters: %s, woorden: %s, lijnen: %s, smileys: %s, acties: %s"
-#: src/misc.cpp:349
+#: src/misc.cpp:350
msgid "minute"
msgstr "minuut"
-#: src/misc.cpp:349
+#: src/misc.cpp:350
msgid "minutes"
msgstr "minuten"
-#: modules/commands/bs_info.cpp:87
+#: modules/commands/bs_info.cpp:88
msgid "not assigned yet"
msgstr "nog niet toegewezen"
-#: src/misc.cpp:324
+#: src/misc.cpp:325
msgid "second"
msgstr "seconde"
-#: src/misc.cpp:324
+#: src/misc.cpp:325
msgid "seconds"
msgstr "seconden"
-#: modules/commands/hs_request.cpp:215
+#: modules/commands/hs_request.cpp:216
#, c-format
msgid "vHost for %s has been activated."
msgstr "vHost voor %s is geactiveerd."
-#: modules/commands/hs_request.cpp:272
+#: modules/commands/hs_request.cpp:273
#, c-format
msgid "vHost for %s has been rejected."
msgstr "vHost voor %s is geweigerd."
-#: modules/commands/hs_request.cpp:79
+#: modules/commands/hs_request.cpp:80
msgid "vhost"
msgstr "vHost"
@@ -11087,11 +11111,11 @@ msgstr "vHost"
msgid "vhosts for group %s have been removed."
msgstr "vHosts voor groep %s zijn verwijderd."
-#: src/misc.cpp:331
+#: src/misc.cpp:332
msgid "year"
msgstr "jaar"
-#: src/misc.cpp:331
+#: src/misc.cpp:332
msgid "years"
msgstr "jaar"
@@ -11099,7 +11123,7 @@ msgstr "jaar"
msgid "{MODIFY|VIEW} [block name item name item value]"
msgstr "{MODIFY|VIEW} [blok naam item naam item waarde]"
-#: modules/commands/bs_info.cpp:41
+#: modules/commands/bs_info.cpp:42
msgid "{channel | nickname}"
msgstr "{kanaal | nick}"
diff --git a/language/anope.pl_PL.po b/language/anope.pl_PL.po
index 1360bbb5d..a6b4026e6 100644
--- a/language/anope.pl_PL.po
+++ b/language/anope.pl_PL.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 20:57-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Polish\n"
@@ -27,19 +27,19 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "Twój nick został odrejestrowany."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "%s dodano do listy AKILL."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr ""
"%s dodano do listy dostępu kanału %s z\n"
"poziomem %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr ""
@@ -51,7 +51,7 @@ msgstr ""
msgid "%s added to %s autokick list."
msgstr "%s dodano do listy AKICK kanału %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s dodano do listy zakazanych słów kanału %s."
@@ -66,17 +66,17 @@ msgstr "%s dodano do Twojej listy dostępu."
msgid "%s added to %s's certificate list."
msgstr "%s dodano do Twojej listy dostępu."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s dodano do Twojej listy dostępu."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "%s dodano do listy AKILL."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s dodano do listy AKILL."
@@ -112,7 +112,7 @@ msgstr ""
"Aby uzyskać szczegółowy opis polecenia wpisz:\n"
"/msg %s HELP komenda"
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -129,7 +129,7 @@ msgstr ""
"Aby uzyskać szczegółowy opis polecenia wpisz:\n"
"/msg %s HELP komenda"
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -145,7 +145,7 @@ msgstr ""
"Aby uzyskać szczegółowy opis polecenia wpisz:\n"
"/msg %s HELP komenda"
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -164,7 +164,7 @@ msgstr ""
"Aby uzyskać szczegółowy opis polecenia wpisz:\n"
"/msg %s HELP komenda"
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s już istnieje na liście zakazanych słów kanału %s."
@@ -185,7 +185,7 @@ msgstr "%s już istnieje na liście wyjątków."
msgid "%s cannot be taken as times to ban."
msgstr "%s nie może być wzięty jako ilość wykroczeń do założenia bana."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s zmienia Twoje flagi użytkownika."
@@ -195,12 +195,12 @@ msgstr "%s zmienia Twoje flagi użytkownika."
msgid "%s channel list:"
msgstr "Koniec listy kanałów."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s usunięto z listy AOP kanału %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s usunięto z listy dostępu kanału %s."
@@ -210,7 +210,7 @@ msgstr "%s usunięto z listy dostępu kanału %s."
msgid "%s deleted from %s autokick list."
msgstr "%s usunięto z listy AKICK %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s usunięto z listy zakazanych słów kanału %s."
@@ -235,12 +235,12 @@ msgstr "%s usunięto z listy wyjątków limitów sesji."
msgid "%s deleted from the %s list."
msgstr "%s usunięto z listy AOP kanału %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s usunięto z listy AKILL."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s wyłączono na kanale %s."
@@ -316,7 +316,7 @@ msgstr "Przebywasz już na kanale %s! "
msgid "%s is already in %s."
msgstr "Przebywasz już na kanale %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s dodano do Twojej listy dostępu."
@@ -326,7 +326,7 @@ msgstr "%s dodano do Twojej listy dostępu."
msgid "%s is already suspended."
msgstr "Przebywasz już na kanale %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s nie jest prawidłową nazwą bota lub kanału."
@@ -356,7 +356,7 @@ msgstr "%s wyłączono na kanale %s."
msgid "%s is not in %s."
msgstr "Przebywasz już na kanale %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "%s nie znaleziono na liście ignorowanych."
@@ -388,12 +388,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s dodano do listy AKICK kanału %s."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "%s nie znaleziono na liście AOP kanału %s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s nie znaleziono na liście dostępu kanału %s."
@@ -403,7 +403,7 @@ msgstr "%s nie znaleziono na liście dostępu kanału %s."
msgid "%s not found on %s autokick list."
msgstr "%s nie znaleziono na liście AKICK kanału %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s nie znaleziono na liście zakazanych słów kanału %s."
@@ -440,17 +440,17 @@ msgstr "%s nie znaleziono na liście wyjątków limitów sesji."
msgid "%s not found on the %s list."
msgstr "%s nie znaleziono na liście AOP kanału %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s nie znaleziono na liście AKILL."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "%s usunięto z listy dostępu kanału %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s usunięto z Twojej listy dostępu."
@@ -482,11 +482,11 @@ msgstr ""
"Aby uzyskać więcej informacji o danej opcji wpisz:\n"
"/msg %s HELP SET opcja"
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -494,12 +494,12 @@ msgstr ""
"BOT CHANGE stary-nick nowy-nick [user [host [real]]]\n"
"BOT DEL nick"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <nick>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -514,6 +514,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -564,7 +567,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -582,18 +585,18 @@ msgstr "[auto-memo] Wysłana przez Ciebie wiadomość do %s została przeczyta
msgid "[target] [password]"
msgstr "GROUP nazwa hasło"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET nick AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -636,7 +639,7 @@ msgstr "UNBAN kanał [nick]"
msgid "channel nick [reason]"
msgstr "BAN #kanał nick [powód]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR kanał co"
@@ -646,7 +649,7 @@ msgstr "CLEAR kanał co"
msgid "channel text"
msgstr "ACT kanał tekst"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT kanał tekst"
@@ -661,12 +664,12 @@ msgstr "KICK kanał nick powód"
msgid "channel what"
msgstr "TOPIC kanał [temat]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE kanał flagi"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -675,7 +678,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE kanał flagi"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -684,19 +687,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #kanał nick [powód]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC kanał [temat]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP kanał"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC kanał [temat]"
@@ -711,7 +714,7 @@ msgstr "DROP kanał"
msgid "channel DEL num"
msgstr "MODE kanał flagi"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [kanał] {numer | list | ALL}"
@@ -721,7 +724,7 @@ msgstr "DEL [kanał] {numer | list | ALL}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP kanał {ADD|DEL|LIST|CLEAR} [nick | pozycja]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [kanał] {numer | list | ALL}"
@@ -730,7 +733,7 @@ msgstr "DEL [kanał] {numer | list | ALL}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP kanał"
@@ -740,41 +743,50 @@ msgstr "DROP kanał"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP kanał {ADD|DEL|LIST|CLEAR} [nick | pozycja]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP kanał {ADD|DEL|LIST|CLEAR} [nick | pozycja]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP kanał {ADD|DEL|LIST|CLEAR} [nick | pozycja]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET kanał GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE kanał flagi"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC kanał [temat]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP kanał {ADD|DEL|LIST|CLEAR} [nick | pozycja]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [kanał] {numer | list | ALL}"
@@ -784,7 +796,7 @@ msgstr "DEL [kanał] {numer | list | ALL}"
msgid "channel [description]"
msgstr "REGISTER kanał opis"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN kanał [nick]"
@@ -794,7 +806,7 @@ msgstr "UNBAN kanał [nick]"
msgid "channel [parameters]"
msgstr "CLEAR kanał co"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN kanał [nick]"
@@ -809,23 +821,13 @@ msgstr "BAN #kanał nick [powód]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #kanał nick [powód]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #kanał nick [powód]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC kanał [temat]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP kanał"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET kanał XOP {ON | OFF}"
@@ -853,7 +855,7 @@ msgstr "KICK kanał opcja {ON|OFF} [ustawienia]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET kanał XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -877,27 +879,27 @@ msgstr "SET kanał XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE numer"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF treść wiadomości"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL treść wiadomości"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -907,8 +909,9 @@ msgid "new-password"
msgstr "GROUP nazwa hasło"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO nick"
@@ -938,18 +941,18 @@ msgstr "SET <nick> <maska-hosta>."
msgid "nick newnick"
msgstr "SVSNICK nick nowy-nick"
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #kanał nick [powód]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK nick"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID nick powód"
@@ -959,7 +962,7 @@ msgstr "FORBID nick powód"
msgid "nickname email"
msgstr "FORBID nick powód"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID nick powód"
@@ -969,12 +972,12 @@ msgstr "FORBID nick powód"
msgid "nickname message"
msgstr "FORBID nick powód"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID nick powód"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST nick [hasło]"
@@ -984,7 +987,7 @@ msgstr "GHOST nick [hasło]"
msgid "nickname [parameter]"
msgstr "GHOST nick [hasło]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST nick [hasło]"
@@ -999,15 +1002,15 @@ msgstr "FORBID nick powód"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET nick AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET nick KILL {ON | QUICK | IMMED | OFF}"
@@ -1051,12 +1054,12 @@ msgstr "REGISTER hasło email"
msgid "password"
msgstr "GROUP nazwa hasło"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER hasło email"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER hasło email"
@@ -1076,7 +1079,7 @@ msgstr "LIST wzorzec [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE serwer [powód]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE kanał flagi"
@@ -1086,7 +1089,7 @@ msgstr "MODE kanał flagi"
msgid "user [reason]"
msgstr "JUPE serwer [powód]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1103,7 +1106,7 @@ msgstr ""
"złośliwych akcji. Nadużycia będą skutkowały co najmniej\n"
"utratÄ… zarejestrowanego nicka."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1159,7 +1162,7 @@ msgstr ""
"\n"
"AKILL CLEAR usuwa wszystkie wpisy z listy AKILL."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1212,7 +1215,7 @@ msgstr ""
"\n"
"AKILL CLEAR usuwa wszystkie wpisy z listy AKILL."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1321,7 +1324,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1343,7 +1346,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1357,7 +1360,7 @@ msgstr ""
"oraz przeglądać listę dostępu do każdego nicka\n"
"(/msg %s ACCESS LIST nick)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1371,7 +1374,7 @@ msgstr ""
"Mogą przeglądać listę dostępu każdego kanału,\n"
"listę AKICK, ustawienia poziomów dostępu itd."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1380,7 +1383,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1440,7 +1453,7 @@ msgstr ""
"Aby dowiedzieć się jak włączyć tryb xOP wpisz:\n"
"/msg %s HELP SET XOP"
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1464,7 +1477,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1525,7 +1538,7 @@ msgstr ""
"Aby dowiedzieć się jak włączyć tryb xOP wpisz:\n"
"/msg %s HELP SET XOP"
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1586,7 +1599,7 @@ msgstr ""
"Aby dowiedzieć się jak włączyć tryb xOP wpisz:\n"
"/msg %s HELP SET XOP"
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1651,9 +1664,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"Składnia: SET kanał NOBOT {ON|OFF}\n"
"\n"
@@ -1661,7 +1674,7 @@ msgstr ""
"nie wolno przypisywać botów. Jeśli w danej chwili\n"
"bot jest przypisany do kanału, zostanie usunięty."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1682,7 +1695,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1697,7 +1710,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "Dodane komendy: /msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1711,7 +1724,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1722,7 +1735,7 @@ msgstr "\"/msg %s\" nie jest już obsługiwane. Użyj \"/msg %s@%s\" lub \"/%s\"
msgid "\"Jupiter\" a server"
msgstr " JUPE Blokuje podłączanie podanego serwera"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1741,17 +1754,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s nie otrzymuje powiadomień o nowych wiadomościach."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
@@ -1776,8 +1789,8 @@ msgstr "%d nicków w grupie."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "Lista AOP kanału %s jest pusta."
@@ -1869,9 +1882,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr " Kopanie za capsa: %s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "Lista dostępu kanału %s jest pusta."
@@ -1881,7 +1894,7 @@ msgstr "Lista dostępu kanału %s jest pusta."
msgid "%s added to %s's auto join list."
msgstr "%s dodano do listy AKICK kanału %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "Bot %s już istnieje."
@@ -1892,7 +1905,7 @@ msgstr "Bot %s już istnieje."
msgid "%s autokick list is empty."
msgstr "Lista AKICK kanału %s jest pusta."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "Lista zakazanych słów dla kanału %s jest pusta."
@@ -1903,8 +1916,8 @@ msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr ""
"%s nie może być zastępcą na kanale %s, ponieważ jest jego właścicielem."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Komendy %s:"
@@ -2004,7 +2017,7 @@ msgstr "%s jest teraz online."
msgid "%s is a network service."
msgstr "%s jest teraz online."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "%s już jest obejmowane przez %s."
@@ -2019,7 +2032,7 @@ msgstr "%s dodano do Twojej listy dostępu."
msgid "%s is an unconfirmed nickname."
msgstr "Ten nick nie wygaśnie."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2043,7 +2056,7 @@ msgstr "%s jest wyłączone"
msgid "%s is enabled"
msgstr "%s jest włączone"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s nie jest prawidłowym rodzajem bana."
@@ -2091,7 +2104,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s wyłączono na kanale %s."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "Lista dostępu dla %s:"
@@ -2101,7 +2114,7 @@ msgstr "Lista dostępu dla %s:"
msgid "%s list is empty."
msgstr "Lista AOP kanału %s jest pusta."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s nie otrzymuje powiadomień o nowych wiadomościach."
@@ -2157,7 +2170,7 @@ msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr ""
"%s powiadomi Cię o wiadomościach podczas logowania oraz po wyłączeniu /away."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) dodano do listy botów."
@@ -2211,12 +2224,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s jest włączone"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2283,7 +2296,7 @@ msgstr "%s jest teraz online."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2296,13 +2309,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Wiadomość została wysłana do wszystkich zarejestrowanych użytkowników."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2339,7 +2352,7 @@ msgstr "GROUP nazwa hasło"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
@@ -2359,12 +2372,12 @@ msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID nick powód"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
@@ -2374,15 +2387,15 @@ msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2398,8 +2411,8 @@ msgstr ""
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL AKILL wszystkich użytkowników na kanale"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "Lista AKILL jest pusta."
@@ -2435,17 +2448,17 @@ msgstr "Poziom musi być pomiędzy %d a %d włącznie."
msgid "Access level must be non-zero."
msgstr "Poziom dostępu nie może być zerem."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Ustawienia poziomów dostępu kanału %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Poziomy dostępu kanału %s zostały zresetowane do domyślnych."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "Lista dostępu dla %s:"
@@ -2459,24 +2472,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE Włącza lub wyłącza bezpieczeństwo kanału"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2501,7 +2506,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2541,13 +2546,7 @@ msgstr "Podłączony do: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2568,7 +2567,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Wszystkie O:linie %s zostały zresetowane."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
@@ -2578,16 +2577,11 @@ msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
msgid "All available commands for %s:"
msgstr "Brak dostępnej pomocy dla %s."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Wszystkie wiadomości powitalne został skasowane."
@@ -2597,12 +2591,12 @@ msgstr "Wszystkie wiadomości powitalne został skasowane."
msgid "All memos for channel %s have been deleted."
msgstr "Wszystkie wiadomości kanału %s zostały usunięte."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2625,7 +2619,7 @@ msgstr "Wszystkie O:linie %s zostały usunięte."
msgid "All random news items deleted."
msgstr "Wszystkie losowe wiadomości zostały skasowane."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
@@ -2637,12 +2631,12 @@ msgstr "Wszystkie O:linie %s zostały zresetowane."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Wszystkie vhosty w grupie %s zostały zmienione na %s@%s"
#: src/access.cpp:41
@@ -2776,7 +2770,7 @@ msgstr ""
"Pozwala administratorom wysyłać wiadomości do wszystkich\n"
"użytkowników. Wiadomość zostanie wysłana z nicka %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2789,7 +2783,7 @@ msgstr ""
"Pozwala operatorom serwisów na zmianę flag dla wskazanego\n"
"kanału. Parametry są identyczne jak dla komendy /MODE."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2800,7 +2794,7 @@ msgstr ""
"Pozwala operatorom serwisów na zmianę flag dla wskazanego\n"
"kanału. Parametry są identyczne jak dla komendy /MODE."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2811,13 +2805,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2885,7 +2879,7 @@ msgstr ""
"\n"
"Ignores will not be enforced on IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2946,7 +2940,7 @@ msgstr ""
"\n"
"AKILL CLEAR usuwa wszystkie wpisy z listy AKILL."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2954,19 +2948,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3011,7 +3003,7 @@ msgstr ""
"Więcej informacji na temat ograniczania liczby sesji\n"
"znajduje siÄ™ w pomocy polecenia EXCEPTION."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3019,12 +3011,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3058,7 +3049,7 @@ msgstr ""
"\n"
"Dostępne opcje:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3076,7 +3067,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3090,7 +3081,7 @@ msgstr ""
"włączona serwisy będą wysyłać wiadomości prywatne\n"
"w przeciwnym wypadku będą wysyłać powiadomienia."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3104,7 +3095,7 @@ msgstr ""
"wysyłać wiadomości prywatne (query), w przeciwnym\n"
"wypadku będą wysyłać powiadomienia (notice)."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3186,13 +3177,13 @@ msgstr ""
"pokazane informacje takie jak: data utworzenia,\n"
"ilość obsługiwanych kanałów itp."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Usuwa vhost wskazanego użytkownika"
@@ -3202,15 +3193,10 @@ msgstr " DEL Usuwa vhost wskazanego użytkownika"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s jest operatorem serwisów typu %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr " ASSIGN Przydziela bota na kanał"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3218,16 +3204,21 @@ msgstr ""
"\n"
"Przydziela bota o wskazanym nicku na kanał."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr " ASSIGN Przydziela bota na kanał"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr " ASSIGN Przydziela bota na kanał"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET Przypisuje komunikat powitalny do nicka"
@@ -3237,12 +3228,12 @@ msgstr " GREET Przypisuje komunikat powitalny do nicka"
msgid "Associate a greet message with your nickname"
msgstr " GREET Przypisuje komunikat powitalny do nicka"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL Przypisuje adres e-mail do nicka"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL Przypisuje adres e-mail do nicka"
@@ -3252,12 +3243,12 @@ msgstr " EMAIL Przypisuje adres e-mail do nicka"
msgid "Associate oper info with a nick or channel"
msgstr " ASSIGN Przydziela bota na kanał"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL Przypisuje adres e-mail do nicka"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3270,7 +3261,7 @@ msgstr ""
"będzie wyświetlany przy opisie Twojego nicka\n"
"dostępnym przy użyciu komendy INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "AUTOOP"
@@ -3299,17 +3290,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "Brak dostępnej pomocy dla %s."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Brak dostępnej pomocy dla %s."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3324,20 +3310,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr " Kopanie za słowa: %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "Lista dostępu dla %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Lista zakazanych słów została wyczyszczona."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "Bot %s już istnieje."
@@ -3356,7 +3342,7 @@ msgstr "Rodzajem bana dla kanału %s jest teraz #%d."
msgid "Bans a given nick or mask on a channel"
msgstr " BAN Banuje wskazanÄ… osobÄ™ na kanale"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3384,7 +3370,7 @@ msgstr "%s nie otrzymuje powiadomień o nowych wiadomościach."
msgid "Bolds kicker"
msgstr " Kopanie za pogrubienia: %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Bot %s już istnieje."
@@ -3399,12 +3385,12 @@ msgstr "Bot %s już istnieje."
msgid "Bot %s has been assigned to %s."
msgstr "Bot %s został przypisany do %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot %s został zmieniony na %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot %s został usunięty."
@@ -3434,43 +3420,43 @@ msgstr "Bot nie będzie kopał operatorów na kanale %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot nie będzie kopał voiców na kanale %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Opcja NOBOT została włączona na kanale %s."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "Bot %s został usunięty."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr ""
"Serwisy nie będą już automatycznie nadawały uprawnień dla użytkownika %s."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Host bota może się składać maksymalnie z %d znaków."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Host bota może zawierać tylko prawidłowe znaki."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Ident bota może się składać maksymalnie z %d znaków."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Ident bota może zawierać tylko prawidłowe znaki."
@@ -3488,12 +3474,12 @@ msgstr "Lista botów:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Ident bota może się składać maksymalnie z %d znaków."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Nick bota może zawierać tylko prawidłowe znaki."
@@ -3588,8 +3574,8 @@ msgstr "Bot nie będzie kopał za flood."
msgid "Bot won't kick for repeats anymore."
msgstr "Bot nie będzie kopał za powtórzenia."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3627,12 +3613,12 @@ msgstr ""
"Wycofuje ostatnią wysłaną wiadomość,\n"
"o ile nie została przeczytana."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Bot będzie teraz kopał operatorów na kanale %s."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Nie mogę wysłać teraz maila. Spróbuj za chwilę."
@@ -3714,22 +3700,22 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s zmienia Twoje flagi użytkownika."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr " MSG Zmienia sposób komunikacji serwisów"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s zmienia Twoje flagi użytkownika."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Zmieniono flagi użytkownika dla %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3741,7 +3727,7 @@ msgstr ""
"serwisach na nową. Nazwa MUSI być jednym z nicków\n"
"należących do Twojej grupy."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3764,7 +3750,7 @@ msgstr ""
"Zmienia właściciela kanału.\n"
"Nowy nick musi być zarejestrowany."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3779,7 +3765,7 @@ msgstr ""
"wysłaną przez Ciebie komendę). Numer może być \n"
"wybrany z poniższej listy obsługiwanych języków:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3794,7 +3780,7 @@ msgstr ""
"wysłaną przez Ciebie komendę). Numer może być \n"
"wybrany z poniższej listy obsługiwanych języków:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3802,7 +3788,7 @@ msgstr ""
"\n"
"Zmienia Twoje hasło do nicka."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3828,7 +3814,7 @@ msgstr ""
"Jeżeli spadkobierca jest właścicielem zbyt dużej\n"
"liczby kanałów (%d) to kanał zostanie odrejestrowany."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP kanał"
@@ -3908,12 +3894,12 @@ msgstr "Kanał %s od teraz podlega prawu wygasania."
msgid "Channel %s will not expire."
msgstr "Kanał %s nie wygaśnie."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Lista AOP kanału %s została wyczyszczona."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Lista dostępu kanału %s została wyczyszczona."
@@ -3923,7 +3909,7 @@ msgstr "Lista dostępu kanału %s została wyczyszczona."
msgid "Channel %s akick list has been cleared."
msgstr "Lista AKICK kanału %s została wyczyszczona."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "Kanał %s został uwolniony."
@@ -3950,8 +3936,8 @@ msgstr ""
"Kanały, na których %s jest na liście dostępu:\n"
" Nr Kanał Poziom Opis"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s nie znaleziono na liście dostępu kanału %s."
@@ -4017,7 +4003,7 @@ msgstr " CHECK Sprawdza czy ostatnia wiadomość została przeczytana"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Składnia: CHECK nick\n"
"\n"
@@ -4116,7 +4102,7 @@ msgstr " KICK Konfiguruje opcje kopania"
msgid "Configures reverses kicker"
msgstr " KICK Konfiguruje opcje kopania"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr " SET Konfiguruje bota"
@@ -4131,7 +4117,7 @@ msgstr " KICK Konfiguruje opcje kopania"
msgid "Confirm a passcode"
msgstr " CONFIRM Potwierdza rejestracjÄ™ nicka"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES Usuwa wszystkie flagi z kanału"
@@ -4141,50 +4127,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr " Utworzony: %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr " Utworzony: %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Aktualna lista AKILL:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Aktualna lista AKILL:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Aktualna lista wyjątków limitów sesji:"
@@ -4238,13 +4224,13 @@ msgstr "FORBID nick powód"
msgid "DEL [nickname] mask"
msgstr "MODE kanał flagi"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [kanał] {numer | list | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [kanał] {numer | list | ALL}"
@@ -4263,19 +4249,19 @@ msgstr "OPERNEWS DEL {numer | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} serwer"
@@ -4289,7 +4275,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4420,17 +4406,22 @@ msgstr " OPERNEWS Zarządza wiadomościami dla operatorów"
msgid "Delete a memo or memos"
msgstr " DEL Kasuje jedną lub więcej wiadomości"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Usuwa vhosty wszystkich nicków w grupie"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Usuwa vhost wskazanego użytkownika"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Usunięto %d wpisów(y) z listy AOP kanału %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Usunięto %d wpisów(y) z listy dostępu kanału %s."
@@ -4440,7 +4431,7 @@ msgstr "Usunięto %d wpisów(y) z listy dostępu kanału %s."
msgid "Deleted %d entries from %s autokick list."
msgstr "Usunięto %d wpisów z listy AKICK kanału %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr ""
@@ -4462,7 +4453,7 @@ msgstr "Usunięto %d wpisów(y) z listy AOP kanału %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "Usunięto %d wpisy(ów) z listy AKILL."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "Usunięto 1 wpis z listy dostępu kanału %s."
@@ -4472,7 +4463,7 @@ msgstr "Usunięto 1 wpis z listy dostępu kanału %s."
msgid "Deleted 1 entry from %s autokick list."
msgstr "Usunięto 1 wpis z listy AKICK kanału %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Usunięto 1 wpis z listy zakazanych słów kanału %s."
@@ -4495,7 +4486,7 @@ msgstr "Usunięto 1 wpis z listy AKILL."
msgid "Deleted info from %s."
msgstr "Usunięto 1 wpis z listy AKILL."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Usunięto 1 wpis z listy AOP kanału %s."
@@ -4545,11 +4536,6 @@ msgstr ""
"\n"
"Usuwa vhosta przypisanego do wskazanego nicka."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Usuwa vhosty wszystkich nicków w grupie"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4560,13 +4546,13 @@ msgstr ""
"\n"
"Usuwa wszystkie vhosty grupy, do której należy wskazany nick."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "Opis kanału %s został zmieniony na %s."
@@ -4581,7 +4567,7 @@ msgstr "Opis kanału %s został zmieniony na %s."
msgid "Description of %s unset."
msgstr "Opis kanału %s został zmieniony na %s."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "%s jest włączone"
@@ -4606,7 +4592,7 @@ msgstr ""
"\n"
"W niektórych sieciach wymagane jest podanie powodu."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Wyświetlono wszystkie wpisy (Liczba: %d)"
@@ -4727,12 +4713,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "Adres e-mail osoby %s został zmieniony na %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "Adres e-mail osoby %s został usunięty."
@@ -4808,7 +4794,7 @@ msgstr " Adres e-mail: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Adresy e-mail %s pasujÄ…ce do %s."
#: modules/fantasy.cpp:19
@@ -4819,11 +4805,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "%s jest włączone"
@@ -4856,14 +4842,14 @@ msgstr ""
"temat za każdym razem, gdy na kanał będzie wchodzić\n"
"pierwsza osoba."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4967,8 +4953,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Składnia: %s kanał SECUREOPS {ON | OFF}\n"
"\n"
@@ -5012,7 +4998,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5037,22 +5023,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Koniec listy użytkowników."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "Koniec listy dostępu."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Koniec listy - %d/%d wpisów wyświetlono."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Koniec listy dostępu."
@@ -5061,7 +5047,7 @@ msgstr "Koniec listy dostępu."
msgid "End of autokick list"
msgstr "Koniec listy dostępu."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Koniec listy użytkowników."
@@ -5094,7 +5080,7 @@ msgstr "Koniec listy użytkowników."
msgid "End of list - %d channels shown."
msgstr "Koniec listy - %d/%d wpisów wyświetlono."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Koniec listy - %d/%d wpisów wyświetlono."
@@ -5129,8 +5115,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Polski"
@@ -5187,44 +5173,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "WyjÄ…tek dla %s (#%d) przeniesiono na pozycjÄ™ %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Wyjątek dla %s został zaktualizowany do %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr " Wygasa: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Wyjątek dla %s został zaktualizowany do %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Zmieniono czas wygasania %s."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "FANTASY"
@@ -5253,18 +5244,18 @@ msgstr "Maska %s jest już w Twojej liście dostępu."
msgid "Fingerprint %s is already in use."
msgstr "Przebywasz już na kanale %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr ""
"Poziom dostępu dla %s na kanale %s\n"
"zmieniono na %d."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "Lista dostępu dla %s:"
@@ -5352,7 +5343,7 @@ msgstr "Właścicielem kanału %s jest teraz %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "Komenda GETPASS nie działa, bo hasła są szyfrowane."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Nick został usunięty z sieci."
@@ -5361,14 +5352,14 @@ msgstr "Nick został usunięty z sieci."
msgid "Give Operflags to a certain user"
msgstr " OLINE Daje flagi operatora wybranemu użytkownikowi"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Nadaje Tobie status właściciela kanału"
@@ -5446,24 +5437,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Nie używaj odwracania kolorów!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "Bot %s już istnieje."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "Bot %s już istnieje."
@@ -5473,8 +5460,8 @@ msgstr "Bot %s już istnieje."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Identyfikuje właściciela nicka"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Masz 20 sekund na zmianę nicka, potem zostanie zmieniony siłą."
@@ -5487,12 +5474,12 @@ msgstr "Lista ignorowanych została wyczyszczona."
msgid "Ignore list is empty."
msgstr "Lista ignorowanych jest pusta."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "Lista botów:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "DONTKICKVOICES"
@@ -5548,7 +5535,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5564,7 +5551,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Nieprawidłowa wartość progu. Musi być liczbą całkowitą większą niż 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5584,17 +5571,17 @@ msgstr " Italics kicker : %s"
msgid "Join a group"
msgstr " GROUP Dołącza nick do wskazanej grupy"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "MSG"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Opcja PEACE dla kanału %s została włączona."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Opcja PEACE dla kanału %s została włączona."
@@ -5613,7 +5600,7 @@ msgstr "Kluczem do kanału %s jest %s."
msgid "Kick a user from a channel"
msgstr " KICK Wyrzuca użytkownika z kanału"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5623,13 +5610,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Wyrzuca wskazany nick z kanału"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Składnia: KICK kanał nick [powód]\n"
"\n"
@@ -5656,19 +5643,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [kanał] [lista | NEW]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [kanał] [lista | NEW]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK nick"
@@ -5679,15 +5666,10 @@ msgstr ""
"LOGONNEWS {ADD|DEL|LIST} [tekst|numer]\n"
"LOGONNEWS {ADD|DEL|LIST} [tekst|numer]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Język został zmieniony na Polski."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Zastępcę dla kanału %s zmieniono na %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5698,7 +5680,7 @@ msgstr "Ostatnia wiadomość do %s została odwołana."
msgid "Last quit message"
msgstr " Ostatni QUIT: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr " Widziano: %s"
@@ -5708,11 +5690,11 @@ msgstr " Widziano: %s"
msgid "Last seen address"
msgstr " Ostatni host: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr " Widziano: %s"
@@ -5722,29 +5704,29 @@ msgstr " Widziano: %s"
msgid "Last usermask"
msgstr " Widziano: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr ""
"Wymagany poziom dla %s\n"
"na kanale %s zmieniono teraz na %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Poziom musi być pomiędzy %d a %d włącznie."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5759,7 +5741,7 @@ msgstr " LIST Listuje zarejestrowane nicki pasujÄ…ce do wzorca"
msgid "List channels you have access on"
msgstr " ALIST Listuje kanały na których masz uprawnienia"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5769,7 +5751,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST Listuje załadowane moduły"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "Lista nicków grupy %s:"
@@ -6021,18 +6003,18 @@ msgstr " MODLIST Listuje załadowane moduły"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Pokazuje informacje o zarejestrowanym kanale"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Składnia: INFO kanał\n"
"\n"
@@ -6119,7 +6101,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6158,12 +6144,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK ZarzÄ…dza listÄ… AKICK"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr " BOT Zarządza sieciową listą botów"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6171,7 +6157,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6189,7 +6175,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6201,7 +6187,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6251,7 +6237,7 @@ msgstr ""
"\n"
"BADWORDS CLEAR usuwa wszystkie wpisy z listy."
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr " BADWORDS Zarządza listą zakazanych słów"
@@ -6265,7 +6251,7 @@ msgstr " ACT Wyraża przez bota akcję (komenda /me)"
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Składnia: ACT kanał tekst\n"
"\n"
@@ -6274,12 +6260,12 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr " SAY Wypowiada przez bota tekst na kanale"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr " SAY Wypowiada przez bota tekst na kanale"
#: modules/commands/greet.cpp:157
@@ -6312,7 +6298,7 @@ msgstr ""
"użytkowników oraz masz odpowiedni poziom dostępu to\n"
"wtedy ta wiadomość będzie wysyłana na kanał przez bota."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "Nie możesz usuwać adresu e-mail w tej sieci."
@@ -6332,12 +6318,12 @@ msgstr " IGNORE ZarzÄ…dza listÄ… ignorowanych przez serwisy"
msgid "Manage your auto join list"
msgstr " AKICK ZarzÄ…dza listÄ… AKICK"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL ZarzÄ…dza listÄ… AKILL"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL ZarzÄ…dza listÄ… AKILL"
@@ -6347,20 +6333,20 @@ msgstr " AKILL ZarzÄ…dza listÄ… AKILL"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Modyfikuje poziom systemu DefCon"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Zmienia temat podanego kanału"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6373,8 +6359,8 @@ msgstr "Maska %s jest już w Twojej liście dostępu."
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "Maska %s jest już w Twojej liście dostępu."
@@ -6406,7 +6392,7 @@ msgstr "Blokowane tryby: %s"
msgid "Memo %d has been deleted."
msgstr "Wiadomość %d została usunięta."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Lista ignorowanych jest pusta."
@@ -6426,7 +6412,7 @@ msgstr "Limit wiadomości dla %s zmieniono na %d."
msgid "Memo limit for %s set to 0."
msgstr "Limit wiadomości dla %s ustawiono na 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Wiadomość została wysłana do %s."
@@ -6441,7 +6427,7 @@ msgstr "Blokowane tryby: %s"
msgid "Message"
msgstr "GLOBAL treść wiadomości"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "MSG"
@@ -6449,26 +6435,26 @@ msgstr "MSG"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "%s nie znaleziono na liście ignorowanych."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr "Blokowane tryby: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr "Blokowane tryby: %s"
@@ -6477,11 +6463,6 @@ msgstr "Blokowane tryby: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6531,7 +6512,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6542,7 +6523,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE ZarzÄ…dza listÄ… ignorowanych przez serwisy"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP Zarządza listą AOP (operatorów)"
@@ -6552,7 +6533,7 @@ msgstr " AOP Zarządza listą AOP (operatorów)"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS Zarządza listą dostępu"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS Zarządza listą dostępu"
@@ -6562,7 +6543,7 @@ msgstr " ACCESS Zarządza listą dostępu"
msgid "Modify the nickname client certificate list"
msgstr " IGNORE ZarzÄ…dza listÄ… ignorowanych przez serwisy"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Zarządza listą wyjątków dla limitów sesji"
@@ -6611,14 +6592,14 @@ msgstr "Moduł: %s Wersja: %s Autor: %s Załadowano: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Moduł: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6631,19 +6612,19 @@ msgstr "Lista dostępu dla %s:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "Nick %s został odrejestrowany."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "Nick %s jest już zarejestrowany!"
@@ -6658,7 +6639,6 @@ msgstr "Nick %s jest już zarejestrowany!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s jest nieprawidłowy i nie może być używany."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6674,7 +6654,7 @@ msgstr "Nick %s jest aktualnie w użyciu."
msgid "Nick %s is forbidden."
msgstr "Nick %s nie jest zajęty przez serwisy."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s jest operatorem serwisów typu %s."
@@ -6699,12 +6679,12 @@ msgstr "Nick %s został zarejestrowany."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s został skrócony do %d znaków."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s od teraz podlega zasadom wygasania."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s nie wygaśnie."
@@ -6769,17 +6749,17 @@ msgstr "Kanał %s jest już zarejestrowany!"
msgid "Nickname %s may not be registered."
msgstr "Kanału %s nie można rejestrować."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Nick %s został zarejestrowany z maską: %s."
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Nick %s został zarejestrowany."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "AUTOOP"
@@ -6788,7 +6768,7 @@ msgstr "AUTOOP"
msgid "No bot"
msgstr "NOBOT"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "nie wygasa"
@@ -6817,13 +6797,13 @@ msgstr "Nie ma wiadomości powitalnych do skasowania!"
msgid "No matches for %s found."
msgstr "Nie ma użytkowników z adresem e-mail %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "Nie znaleziono wpisów w liście AOP kanału %s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Nie znaleziono wpisów na liście dostępu kanału %s."
@@ -6833,21 +6813,21 @@ msgstr "Nie znaleziono wpisów na liście dostępu kanału %s."
msgid "No matching entries on %s autokick list."
msgstr "Nie znaleziono wpisów na liście AKICK kanału %s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Nie znaleziono pasujących wpisów na liście zakazanych słów kanału %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "Nie znaleziono wpisów na liście wyjątków limitów sesji."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Nie znaleziono wpisów w liście AOP kanału %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Nie znaleziono pasujących wpisów na liście AKILL."
@@ -6860,7 +6840,12 @@ msgstr "Brak wiadomości do odwołania."
msgid "No modules currently loaded matching that criteria."
msgstr "Aktualnie nie ma załadowanych modułów."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Wyłącza rejestrowanie nicków"
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6880,12 +6865,7 @@ msgstr "Nie ma losowych wiadomości do skasowania!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Wyłącza rejestrowanie nicków"
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6894,8 +6874,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "Lista dostępu dla %s:"
@@ -6905,7 +6885,7 @@ msgstr "Lista dostępu dla %s:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Zmieniono flagi użytkownika dla %s."
@@ -6920,7 +6900,7 @@ msgstr "Opcja NOBOT została włączona na kanale %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Opcja NOBOT została włączona na kanale %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6929,21 +6909,21 @@ msgstr ""
msgid "None"
msgstr "Brak"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -6951,18 +6931,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [tekst|numer]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Nic się nie zmieniło."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Jest online z: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -6986,12 +6963,12 @@ msgstr "Wiadomość dla operatorów #%d nie została znaleziona!"
msgid "Oper news items:"
msgstr "Wiadomości dla operatorów:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "Nick %s został odrejestrowany."
@@ -7006,17 +6983,17 @@ msgstr "Flagi operatora %s zostały przyznane dla %s."
msgid "Operflags %s have been removed from %s."
msgstr "Flagi operatora %s zostały przyznane dla %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7030,12 +7007,12 @@ msgstr "DONTKICKOPS"
msgid "Options"
msgstr "\tOpcje: %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} serwer"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7052,12 +7029,12 @@ msgstr "Nieprawidłowe hasło."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "Zastępcę dla kanału %s zmieniono na %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "Hasło do nicka %s zostało wysłane."
@@ -7077,7 +7054,7 @@ msgstr "Nieprawidłowe hasło."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "PEACE"
@@ -7091,7 +7068,7 @@ msgstr "Opcja PEACE dla kanału %s została włączona."
msgid "Peace option for %s is now on."
msgstr "Opcja PEACE dla kanału %s została włączona."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7122,12 +7099,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Proszę odczekać %d sekund(y) i ponowić próbę."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Odczekaj %d sekund(y) przed ponownym użyciem komendy SEND."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Odczekaj %d sekund(y) przed ponownym użyciem komendy SEND."
@@ -7137,12 +7114,12 @@ msgstr "Odczekaj %d sekund(y) przed ponownym użyciem komendy SEND."
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Odczekaj %d sekund przed ponownym użyciem komendy GROUP."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr "Odczekaj %d sekund przed ponownym użyciem komendy REGISTER."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7155,7 +7132,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7185,7 +7162,7 @@ msgstr ""
" PRIVATE Zapobiega wyświetlaniu nicka po wydaniu\n"
" polecenia: /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE Zapobiega wygaśnięciu nicka"
@@ -7194,17 +7171,17 @@ msgstr " NOEXPIRE Zapobiega wygaśnięciu nicka"
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "PRIVATE"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Opcja PRIVATE bota %s została włączona."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Opcja PRIVATE bota %s została włączona."
@@ -7229,36 +7206,36 @@ msgstr "Opcja prywatności dla %s została włączona."
msgid "Private option is now on for %s."
msgstr "Opcja prywatności dla %s została włączona."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "KILL"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Ochrona dla %s jest teraz włączona."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Ochrona dla %s ze zredukowanym opóźnieniem jest teraz włączona."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Natychmiastowa ochrona dla %s jest teraz włączona"
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Ochrona dla %s jest teraz włączona."
@@ -7276,7 +7253,7 @@ msgstr ""
"Na listÄ™ zostajÄ… dodane prawdziwe adresy (ident@host),\n"
"po czym AKILL zostaje wykonany."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "DONTKICKVOICES"
@@ -7322,20 +7299,20 @@ msgstr " READ Wyświetla jedną lub więcej wiadomości"
msgid "Real name"
msgstr "\tNazwa: %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "Zastępcę dla kanału %s usunięto."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7345,33 +7322,33 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS Zarządza poziomami dostępu"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr " RELEASE Zwalnia nick po użyciu komendy RECOVER"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s jest włączone"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7383,12 +7360,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Rejestruje nicka"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Rejestruje nicka"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr "Zarejestrowano: %s"
@@ -7447,7 +7424,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7499,7 +7476,7 @@ msgstr ""
"Aby uzyskać więcej informacji napisz: \n"
"/msg %s HELP GROUP."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Rejestracja kanałów jest tymczasowo wyłączona."
@@ -7509,12 +7486,12 @@ msgstr "Rejestracja kanałów jest tymczasowo wyłączona."
msgid "Regulate the use of critical commands"
msgstr " PEACE Reguluje użycie krytycznych komend"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Podaje status właściciela podanego nicka"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Usuwa vhost wskazanego użytkownika"
@@ -7561,46 +7538,46 @@ msgstr ""
msgid "Remove all operators from a server remotely"
msgstr " NOOP Tymczasowo usuwa wszystkie O:linie na serwerze"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr "Blokowane tryby: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr " OP Nadaje wskazanej osobie uprawnienia operatora"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Wyrzuca wskazany nick z kanału"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7616,14 +7593,14 @@ msgstr " Kopanie za powtarzanie: %s"
msgid "Request a vHost for your nick"
msgstr "Twój nick nie ma ustawionego adresu e-mail."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Åaduje na nowo plik konfiguracyjny"
@@ -7633,7 +7610,7 @@ msgstr " RELOAD Åaduje na nowo plik konfiguracyjny"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Ogranicza dostęp do kanału"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "RESTRICTED"
@@ -7668,7 +7645,7 @@ msgstr " KEEPTOPIC Zapamiętuje temat kiedy kanał jest pusty"
msgid "Retrieve the password for a nickname"
msgstr " GETPASS Podaje hasło do wskazanego nicka"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7684,8 +7661,17 @@ msgstr " GETKEY Podaje klucz do wskazanego kanału"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Podaje klucz do wskazanego kanału"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Składnia: GETEMAIL uzytkownik@serwer.com\n"
+"\n"
+"Listuje nicki, które mają ustawiony podany adres e-mail.\n"
+"Uwaga: nie można używać symboli wieloznacznych (* lub ?).\n"
+"Każdy przypadek użycia tej komendy jest logowany."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7765,16 +7751,16 @@ msgstr " LOGOUT Odwraca działanie komendy IDENTIFY"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} serwer"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Hasło przyjęte - jesteś zidentyfikowany(a)."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Hasło przyjęte - jesteś zidentyfikowany(a)."
@@ -7797,7 +7783,7 @@ msgstr " RESTART Zapisuje bazy i restartuje serwisy"
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "SECUREFOUNDER"
@@ -7812,7 +7798,7 @@ msgstr "Status właściciela kanału %s będzie teraz chroniony."
msgid "Secure founder option for %s is now on."
msgstr "Status właściciela kanału %s będzie teraz chroniony."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "SECUREOPS"
@@ -7837,12 +7823,12 @@ msgstr "Opcja bezpieczeństwa dla kanału %s została włączona."
msgid "Secure option for %s is now on."
msgstr "Opcja bezpieczeństwa dla kanału %s została włączona."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Opcja bezpieczeństwa dla %s została włączona."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Opcja bezpieczeństwa dla %s została włączona."
@@ -7852,11 +7838,11 @@ msgstr "Opcja bezpieczeństwa dla %s została włączona."
msgid "Secureops enforced on %s."
msgstr "Opcja bezpieczeństwa dla %s została włączona."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "SECURE"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7865,7 +7851,7 @@ msgstr ""
"Aby uzyskać więcej informacji o danej opcji wpisz:\n"
"/msg %s HELP SET opcja"
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7939,7 +7925,7 @@ msgstr ""
"wpisani jednocześnie na kilka list otrzymają\n"
"wiadomości kilka razy."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8014,14 +8000,14 @@ msgid "Server %s already exists."
msgstr "Bot %s już istnieje."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "Nick %s został odrejestrowany."
@@ -8031,12 +8017,12 @@ msgstr "Nick %s został odrejestrowany."
msgid "Server %s is already in zone %s."
msgstr "Przebywasz już na kanale %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s jest teraz online."
@@ -8051,12 +8037,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "Nie ma żadnych botów przydzielonych do %s."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8076,19 +8062,18 @@ msgstr "Serwerów : %d"
msgid "Service"
msgstr "Serwerów : %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Serwisy właśnie zwolniły twojego nicka."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s jest operatorem serwisów typu %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr "Serwisy są w trybie defcon, spróbuj ponownie później."
@@ -8143,7 +8128,7 @@ msgstr "Serwisy zostały skonfigurowane tak, aby nie wysyłać poczty."
msgid "Services ignore list:"
msgstr " IGNORE ZarzÄ…dza listÄ… ignorowanych przez serwisy"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8157,7 +8142,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Serwerów : %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr ""
@@ -8169,7 +8154,7 @@ msgid "Services will no longer automatically give modes to users in %s."
msgstr ""
"Serwisy nie będą już automatycznie nadawały uprawnień dla użytkownika %s."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr ""
@@ -8180,12 +8165,12 @@ msgstr ""
msgid "Services will now automatically give modes to users in %s."
msgstr "Serwisy będą automatycznie nadawały uprawnienia dla użytkownika %s."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Serwisy będą teraz wysyłać do %s wiadomości."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Serwisy będą teraz wysyłać do %s powiadomienia."
@@ -8204,7 +8189,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Limit sesji dla %s zmieniono na %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Limitowanie sesji jest wyłączone."
@@ -8248,7 +8233,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC Ustawia opis kanału"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Ustawia nick reprezentujący grupę nicków"
@@ -8258,14 +8243,14 @@ msgstr " DISPLAY Ustawia nick reprezentujący grupę nicków"
msgid "Set the founder of a channel"
msgstr " FOUNDER Ustawia nick właściciela kanału"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE Ustawia język w którym serwisy będą\n"
" wysyłały komunikaty"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Ustawia hasło do nicka"
@@ -8630,7 +8615,7 @@ msgstr ""
"\n"
"Ustawia różne opcje nicka. Dostępne opcje to:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8646,7 +8631,7 @@ msgstr ""
"Włącza lub wyłącza automatyczne usunięcie kanału,\n"
"jeśli nie będzie on używany."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8660,7 +8645,7 @@ msgstr ""
"Włącza lub wyłącza automatyczne nadawanie uprawnień\n"
"wskazanemu użytkownikowi przy wchodzeniu na kanał."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8671,7 +8656,7 @@ msgstr ""
"Włącza lub wyłącza automatyczne usunięcie nicka,\n"
"jeśli nie będzie on używany."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8684,7 +8669,7 @@ msgstr ""
"Włącza lub wyłącza automatyczne nadawanie uprawnień\n"
"przy wchodzeniu na kanał."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8751,11 +8736,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Podpisywanie komendy KICK na kanale %s zostało włączone."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "SIGNKICK"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s ma zbyt dużo wiadomości i nie może otrzymywać nowych."
@@ -8765,44 +8750,38 @@ msgstr "%s ma zbyt dużo wiadomości i nie może otrzymywać nowych."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Modyfikacja listy zakazanych słów jest tymczasowo wyłączona."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Konfigurowanie bota jest tymczasowo wyłączone."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Modyfikacja botów jest tymczasowo wyłączona."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Konfigurowanie bota jest tymczasowo wyłączone."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Konfigurowanie bota jest tymczasowo wyłączone."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Modyfikacja listy AOP jest tymczasowo wyłączona."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Modyfikacja listy dostępu jest tymczasowo wyłączona."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Modyfikacja listy AKICK jest tymczasowo wyłączona."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Modyfikacja listy zakazanych słów jest tymczasowo wyłączona."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Usuwanie kanałów jest tymczasowo wyłączone."
@@ -8832,7 +8811,7 @@ msgstr "Usuwanie nicków jest tymczasowo wyłączone."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Grupowanie nicków jest tymczasowo wyłączone."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Rejestracja nicków jest tymczasowo wyłączona."
@@ -8851,13 +8830,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Możesz mieć tylko %d wpisy(ów) na liście dostępu."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Wiadomość powitalna osoby %s została usunięta."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8869,7 +8843,7 @@ msgstr "Możesz mieć tylko %d wpisów na kanałowej liście dostępu."
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Możesz mieć jedynie %d wpisów w liście AKICK."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Błąd, możesz mieć tylko %d wpisów na liście zakazanych słów."
@@ -9158,7 +9132,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9236,7 +9210,7 @@ msgstr ""
"Ta opcja powinna być używana tylko wtedy, kiedy\n"
"jest taka potrzeba. Należy ją później wyłączyć."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9258,7 +9232,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Składnia: INVITE kanał\n"
@@ -9277,7 +9251,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Składnia: UNBAN kanał [nick]\n"
@@ -9328,7 +9302,7 @@ msgstr " SHUTDOWN Wyłącza serwisy z zapisaniem baz"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9339,7 +9313,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9348,7 +9322,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9365,10 +9339,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9376,14 +9350,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9398,7 +9372,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Składnia: HOP kanał ADD nick\n"
@@ -9442,36 +9416,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "Opcja IMMED nie jest jest dostępna w tej sieci."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9519,7 +9493,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9530,18 +9504,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9549,7 +9523,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9562,7 +9536,6 @@ msgstr ""
"Twoja prywatność będzie uszanowana - nie będzie podawany osobom trzecim,"
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9580,7 +9553,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9590,12 +9563,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Wiadomość powitalna osoby %s została usunięta."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "Lista AKILL została wyczyszczona."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "Lista AKILL została wyczyszczona."
@@ -9614,7 +9587,7 @@ msgstr "Adres e-mail osoby %s będzie ukrywany w informacjach %s."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "Adres e-mail osoby %s będzie pokazywany w informacjach %s."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9646,11 +9619,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Wiadomość powitalna osoby %s została usunięta."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9712,12 +9685,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "Limit wiadomości dla %s nie może być zmieniany."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Wiadomość powitalna osoby %s została usunięta."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9732,10 +9700,6 @@ msgstr "Defcon jest teraz na poziomie: %d"
msgid "The nick %s is now being changed to %s."
msgstr "Nick %s zostaje zmieniony na %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9758,12 +9722,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"Status dostępu do serwisów osoby %s będzie pokazywany w informacjach %s."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Zarządza listą wyjątków dla limitów sesji"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9835,7 +9799,7 @@ msgstr "Nie ma losowych wiadomości."
msgid "There is no such configuration block %s."
msgstr " RELOAD Åaduje na nowo plik konfiguracyjny"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Nie ma wiadomości dla operatorów."
@@ -9863,7 +9827,7 @@ msgstr "Ten kanał nie może być używany."
msgid "This channel may not be used."
msgstr "Ten kanał nie może być używany."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9899,7 +9863,7 @@ msgstr ""
"To polecenie pozwala ustawić vhost bieżącego nicka\n"
"dla wszystkich nicków w grupie."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9912,7 +9876,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -9945,8 +9909,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10049,7 +10013,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10063,7 +10027,7 @@ msgstr ""
"\n"
"To polecenie ładuje wskazany moduł z katalogu modułów."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10115,7 +10079,7 @@ msgstr ""
"\n"
"To polecenie ładuje wskazany moduł z katalogu modułów."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10131,12 +10095,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Ten nick jest obecnie zawieszony, powód: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "Ten nick jest obecnie zawieszony, powód: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10197,7 +10161,7 @@ msgstr ""
msgid "Topic"
msgstr "TOPICLOCK"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "TOPICLOCK"
@@ -10212,7 +10176,7 @@ msgstr "Blokada tematu na kanale %s została włączona."
msgid "Topic lock option for %s is now on."
msgstr "Blokada tematu na kanale %s została włączona."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "KEEPTOPIC"
@@ -10227,7 +10191,7 @@ msgstr "Temat kanału %s będzie teraz utrzymywany."
msgid "Topic retention option for %s is now on."
msgstr "Temat kanału %s będzie teraz utrzymywany."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10235,17 +10199,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Wyłącz CAPS LOCKa!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE Włącza lub wyłącza bezpieczeństwo nicka"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE Włącza lub wyłącza bezpieczeństwo nicka"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL Włącza lub wyłącza ochronę nicka"
@@ -10284,7 +10249,7 @@ msgstr ""
"Jednak każdy, kto zna nick może uzyskać o nim\n"
"informacje używając polecenia INFO."
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10315,7 +10280,7 @@ msgstr " SECURE Włącza lub wyłącza bezpieczeństwo nicka"
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE Włącza lub wyłącza bezpieczeństwo nicka"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10348,7 +10313,7 @@ msgstr ""
"należy stosować z rozwagą). Administrator sieci \n"
"może wyłączyć korzystanie z IMMED."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10381,7 +10346,7 @@ msgstr ""
"należy stosować z rozwagą). Administrator sieci \n"
"może wyłączyć korzystanie z IMMED."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10416,7 +10381,7 @@ msgstr ""
"Aby uzyskać więcej informacji o danej opcji wpisz:\n"
"/msg %s HELP SASET opcja"
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10425,7 +10390,7 @@ msgstr ""
"Aby uzyskać więcej informacji o danej opcji wpisz:\n"
"/msg %s HELP SET opcja"
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10440,8 +10405,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Wyładowuje moduł"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Nie można wyładować modułu %s"
@@ -10483,7 +10448,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Kopanie za podkreślenia: %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Nieznana opcja komendy SASET %s."
@@ -10503,7 +10468,7 @@ msgstr "Nieznana opcja %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Nieznana komenda %s. Napisz \"%s%s HELP\" aby uzyskać pomoc."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Nieznany flaga %c zostaje zignorowana."
@@ -10531,8 +10496,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Składnia: DROP kanał\n"
"\n"
@@ -10548,10 +10513,10 @@ msgstr " UNSUSPEND Uwalnia zawieszonego nicka"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10603,31 +10568,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s zmienia Twoje flagi użytkownika."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS Zarządza listą dostępu"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "Ban na kanale %s został zdjęty."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "Vhost dla %s został usunięty."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Limit wiadomości dla %s zmieniono na %d."
@@ -10680,13 +10645,13 @@ msgstr "Vhosty dla grupy %s zostały zmienione na %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [kanał] [lista | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10699,7 +10664,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "Właścicielem kanału %s jest teraz %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10737,7 +10702,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10827,7 +10792,7 @@ msgstr ""
"\n"
"Parametr ALL wyświetla wszystkie dostępne informacje."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10836,7 +10801,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Należysz już do grupy %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Jesteś już zidentyfikowany(a)."
@@ -10901,7 +10866,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10926,13 +10891,22 @@ msgstr ""
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "Nie możesz wysyłać wiadomości z potwierdzeniem odbioru do siebie!"
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Nie możesz usunąć samego siebie!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Nie znaleziono wpisów na liście dostępu kanału %s."
@@ -10942,16 +10916,11 @@ msgstr "Nie znaleziono wpisów na liście dostępu kanału %s."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Nie mogę wylogować %s, bo to administrator serwisów."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "Nie możesz usuwać adresu e-mail w tej sieci."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10962,12 +10931,7 @@ msgstr "Nie możesz ustawić limitu wiadomości dla %s większego niż %d."
msgid "You cannot set your memo limit higher than %d."
msgstr "Nie możesz ustawić swojego limitu wiadomości większego niż %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Nie możesz usuwać adresu e-mail w tej sieci."
@@ -11007,12 +10971,12 @@ msgstr "Aktualnie masz jedną wiadomość."
msgid "You currently have no memos."
msgstr "Aktualnie nie masz wiadomości."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11048,7 +11012,7 @@ msgstr "Zostałeś zaproszony do %s."
msgid "You have been invited to %s."
msgstr "Zostałeś zaproszony do %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "Twój nick został pomyślnie wylogowany."
@@ -11092,32 +11056,27 @@ msgstr ""
"Nie będziesz otrzymywać nowych wiadomości dopóki\n"
"nie usuniesz kilku starych."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "Zostałeś zaproszony do %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Usuwa vhosty wszystkich nicków w grupie"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "Nie możesz usuwać adresu e-mail w tej sieci."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "Nie możesz usuwać adresu e-mail w tej sieci."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "Nie mogę wylogować %s, bo to administrator serwisów."
@@ -11162,26 +11121,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "Aby zarejestrować kanał musisz być jego operatorem."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
msgstr "Aby zarejestrować kanał musisz być jego operatorem."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "Aby zarejestrować kanał musisz być jego operatorem."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "Aby zarejestrować kanał musisz być jego operatorem."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11189,18 +11133,18 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"Musisz być połączony(a) dłużej niż %d sekund(y), aby móc zarejestrować nick."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11213,40 +11157,18 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Będziesz otrzymywać powiadomienie o nowych wiadomościach."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Będziesz powiadomienie informacje o nowych wiadomościach\n"
-"podczas logowania i w momencie ich nadejścia."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Będziesz powiadomienie informacje o nowych wiadomościach\n"
"podczas logowania i w momencie ich nadejścia."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Będziesz powiadomienie informacje o nowych wiadomościach\n"
-"podczas logowania i w momencie ich nadejścia."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr ""
"Będziesz otrzymywać powiadomienie o nowych wiadomościach podczas logowania."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Będziesz otrzymywać powiadomienie o nowych wiadomościach."
@@ -11259,7 +11181,7 @@ msgid "You will no longer be informed via email."
msgstr ""
"Powiadomienie o nowych wiadomościach nie będą wysyłane na adres e-mail."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Nie będziesz otrzymywać informacji o nowych wiadomościach."
@@ -11285,23 +11207,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "Bot %s został usunięty."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "Jesteś już zidentyfikowany(a)."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Jesteś już zidentyfikowany(a)."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "Adres e-mail osoby %s został zmieniony na %s."
@@ -11311,18 +11233,18 @@ msgstr "Adres e-mail osoby %s został zmieniony na %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Wszystkie O:linie %s zostały usunięte."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Wszystkie O:linie %s zostały usunięte."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "Adres e-mail osoby %s został zmieniony na %s."
@@ -11382,7 +11304,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Nick %s został zarejestrowany."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Twój nick został zmieniony na %s."
@@ -11391,43 +11313,42 @@ msgstr "Twój nick został zmieniony na %s."
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Twój kod rejestracyjny został ponownie wysłany na %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Twoje hasło do nicka to %s"
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "Bot %s został usunięty."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Twój vhost %s jest teraz aktywny."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Twój vhost %s@%s jest teraz aktywny."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr ""
"Twój vhost został usunięty i zostało włączone normalne ukrywanie hosta."
@@ -11478,7 +11399,7 @@ msgstr "[Losowa wiadomość - %s] %s"
msgid "[account] password"
msgstr "IDENTIFY hasło"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #kanał [nick]"
@@ -11536,8 +11457,8 @@ msgstr "INFO nick"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK nick"
@@ -11559,7 +11480,7 @@ msgstr "CHANKILL [+czas-trwania] {#kanał} [powód]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11567,22 +11488,22 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto-memo] Wysłana przez Ciebie wiadomość do %s została przeczytana."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto-memo] Wysłana przez Ciebie wiadomość do %s została przeczytana."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "Ostatnia wiadomość do %s została odwołana."
@@ -11687,12 +11608,12 @@ msgstr ""
msgid "seconds"
msgstr "Komendy %s:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Twój vhost %s jest teraz aktywny."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "Bot %s został usunięty."
@@ -11728,26 +11649,7 @@ msgstr "UNBAN kanał [nick]"
msgid "{nick | channel}"
msgstr "CANCEL {nick | kanał}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {nick | kanał} treść"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "WyjÄ…tek dla %s (#%d) przeniesiono na pozycjÄ™ %d."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Nic się nie zmieniło."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Składnia: GETEMAIL uzytkownik@serwer.com\n"
-#~ "\n"
-#~ "Listuje nicki, które mają ustawiony podany adres e-mail.\n"
-#~ "Uwaga: nie można używać symboli wieloznacznych (* lub ?).\n"
-#~ "Każdy przypadek użycia tej komendy jest logowany."
diff --git a/language/anope.pt_PT.po b/language/anope.pt_PT.po
index eb4021d06..b9fef464d 100644
--- a/language/anope.pt_PT.po
+++ b/language/anope.pt_PT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 21:02-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Portuguese\n"
@@ -27,17 +27,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "O registro do seu nick foi cancelado."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "%s adicionado à lista de AKILL."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s adicionado à lista de acesso do %s com o nível %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s adicionado à lista de acesso do %s com o nível %d."
@@ -47,7 +47,7 @@ msgstr "%s adicionado à lista de acesso do %s com o nível %d."
msgid "%s added to %s autokick list."
msgstr "%s adicionado à lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s adicionado na lista de palavrões do %s."
@@ -62,17 +62,17 @@ msgstr "%s adicionado em sua lista de acesso."
msgid "%s added to %s's certificate list."
msgstr "%s adicionado em sua lista de acesso."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s adicionado em sua lista de acesso."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "%s adicionado à lista de AKILL."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s adicionado à lista de AKILL."
@@ -107,7 +107,7 @@ msgstr ""
"/msg %s comando. Para informações mais específicas\n"
"sobre um comando, digite /msg %s HELP comando."
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -123,7 +123,7 @@ msgstr ""
"/msg %s comando. Para mais informações sobre um\n"
"comando específico, digite /msg %s HELP comando."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -138,7 +138,7 @@ msgstr ""
"/msg %s comando. Para mais informações sobre um\n"
"comando específico, digite /msg %s HELP comando."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -157,7 +157,7 @@ msgstr ""
"/msg %s comando. Para mais informações sobre\n"
"um comando específico, digite /msg %s HELP comando."
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s já existe na lista de palavrões do %s."
@@ -178,7 +178,7 @@ msgstr "%s já existe na lista de EXCEPTION."
msgid "%s cannot be taken as times to ban."
msgstr "%s não pode ser colocado como tempo para ban."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s alterou seus modos de usuário."
@@ -188,12 +188,12 @@ msgstr "%s alterou seus modos de usuário."
msgid "%s channel list:"
msgstr "Fim da listagem."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s deletado da lista de AOP do %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s removido da lista de acesso do %s."
@@ -203,7 +203,7 @@ msgstr "%s removido da lista de acesso do %s."
msgid "%s deleted from %s autokick list."
msgstr "%s removido da lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s removido da lista de palavrões do %s."
@@ -228,12 +228,12 @@ msgstr "%s removido da lista de limite de sessões."
msgid "%s deleted from the %s list."
msgstr "%s deletado da lista de AOP do %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s removido da lista de AKILL."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s desabilitado no canal %s."
@@ -306,7 +306,7 @@ msgstr "You are already in %s! "
msgid "%s is already in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s adicionado em sua lista de acesso."
@@ -316,7 +316,7 @@ msgstr "%s adicionado em sua lista de acesso."
msgid "%s is already suspended."
msgstr "You are already in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s não é um bot válido ou um canal registrado."
@@ -346,7 +346,7 @@ msgstr "%s desabilitado no canal %s."
msgid "%s is not in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "%s não encontrado na lista de Ignore."
@@ -378,12 +378,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s adicionado à lista de akick do %s."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "Nick %s não encontrado na lista de AOP do %s."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s não foi encontrado na lista de acesso do %s."
@@ -393,7 +393,7 @@ msgstr "%s não foi encontrado na lista de acesso do %s."
msgid "%s not found on %s autokick list."
msgstr "%s não encontrado na lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s não foi encontrado na lista de palavrões do %s."
@@ -430,17 +430,17 @@ msgstr "%s não encontrado na lista de limite de sessões."
msgid "%s not found on the %s list."
msgstr "Nick %s não encontrado na lista de AOP do %s."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s não encontrado na lista de AKILL."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "%s removido da lista de acesso do %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s removido da sua lista de acesso."
@@ -472,11 +472,11 @@ msgstr ""
"Digite /msg %s HELP SET opção para maiores informações\n"
"sobre uma opção em particular."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -484,12 +484,12 @@ msgstr ""
"BOT CHANGE nickantigo nicknovo [user [host [real]]]\n"
"BOT DEL nick"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <nick>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -504,6 +504,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -564,7 +567,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -582,18 +585,18 @@ msgstr "[Auto-Memo] O memo que você enviou para %s foi lido."
msgid "[target] [password]"
msgstr "GROUP alvo senha"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -636,7 +639,7 @@ msgstr "UNBAN canal [nick]"
msgid "channel nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR canal opção"
@@ -646,7 +649,7 @@ msgstr "CLEAR canal opção"
msgid "channel text"
msgstr "ACT canal texto"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT canal texto"
@@ -661,12 +664,12 @@ msgstr "KICK canal usuário motivo"
msgid "channel what"
msgstr "TOPIC canal [tópico]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE canal modos"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -675,7 +678,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE canal modos"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -684,19 +687,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC canal [tópico]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP canal"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC canal [tópico]"
@@ -711,7 +714,7 @@ msgstr "DROP canal"
msgid "channel DEL num"
msgstr "MODE canal modos"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [canal] {núm | list | ALL}"
@@ -721,7 +724,7 @@ msgstr "DEL [canal] {núm | list | ALL}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | entrada]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [canal] {núm | list | ALL}"
@@ -730,7 +733,7 @@ msgstr "DEL [canal] {núm | list | ALL}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP canal"
@@ -740,41 +743,50 @@ msgstr "DROP canal"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | entrada]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | entrada]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | entrada]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET canal GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE canal modos"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC canal [tópico]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP canal {ADD|DEL|LIST|CLEAR} [nick | entrada]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [canal] {núm | list | ALL}"
@@ -784,7 +796,7 @@ msgstr "DEL [canal] {núm | list | ALL}"
msgid "channel [description]"
msgstr "REGISTER canal descrição"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN canal [nick]"
@@ -794,7 +806,7 @@ msgstr "UNBAN canal [nick]"
msgid "channel [parameters]"
msgstr "CLEAR canal opção"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN canal [nick]"
@@ -809,23 +821,13 @@ msgstr "BAN #channel nick [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #channel nick [reason]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC canal [tópico]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP canal"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET canal XOP {ON | OFF}"
@@ -853,7 +855,7 @@ msgstr "KICK canal opções {ON|OFF} [configurações]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET canal XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -877,27 +879,27 @@ msgstr "SET canal XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE número"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL mensagem"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -907,8 +909,9 @@ msgid "new-password"
msgstr "GROUP alvo senha"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO nick"
@@ -938,18 +941,18 @@ msgstr "SET <nick> <hostmask>."
msgid "nick newnick"
msgstr "SVSNICK nick novonick "
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK nick"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID nick motivo"
@@ -959,7 +962,7 @@ msgstr "FORBID nick motivo"
msgid "nickname email"
msgstr "FORBID nick motivo"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID nick motivo"
@@ -969,12 +972,12 @@ msgstr "FORBID nick motivo"
msgid "nickname message"
msgstr "FORBID nick motivo"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID nick motivo"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST nick [senha]"
@@ -984,7 +987,7 @@ msgstr "GHOST nick [senha]"
msgid "nickname [parameter]"
msgstr "GHOST nick [senha]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST nick [senha]"
@@ -999,15 +1002,15 @@ msgstr "FORBID nick motivo"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET nickname KILL {ON | QUICK | IMMED | OFF}"
@@ -1051,12 +1054,12 @@ msgstr "REGISTER senha email"
msgid "password"
msgstr "GROUP alvo senha"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER senha email"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER senha email"
@@ -1076,7 +1079,7 @@ msgstr "LIST opções [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE servidor [motivo]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE canal modos"
@@ -1086,7 +1089,7 @@ msgstr "MODE canal modos"
msgid "user [reason]"
msgstr "JUPE servidor [motivo]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1103,7 +1106,7 @@ msgstr ""
"outras atitudes mau intencionadas. O abuso do %s\n"
"resultará em, no mínimo, perda do(s) nick(s) abusivo(s). "
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1167,7 +1170,7 @@ msgstr ""
"\n"
"AKILL CLEAR apaga todas as entradas da lista de AKILL."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1228,7 +1231,7 @@ msgstr ""
"\n"
"AKILL CLEAR apaga todas as entradas da lista de AKILL."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1342,7 +1345,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1364,7 +1367,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1376,7 +1379,7 @@ msgstr ""
"sem ser necessário se identificar como dono dele, e podem ver a lista de\n"
"acesso de qualquer nick (/msg %s ACCESS LIST nick)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1390,7 +1393,7 @@ msgstr ""
"também ver as listas de acesso, AKICK, e níveis de qualquer\n"
"canal."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1399,7 +1402,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1457,7 +1470,7 @@ msgstr ""
"de acesso, e /msg %s HELP SET XOP para saber como\n"
"escolher entre a lista de acesso e o sistema de listas xOP."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1481,7 +1494,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1540,7 +1553,7 @@ msgstr ""
"de acesso, e /msg %s HELP SET XOP para saber como\n"
"escolher entre a lista de acesso e o sistema de listas xOP."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1599,7 +1612,7 @@ msgstr ""
"de acesso, e /msg %s HELP SET XOP para saber como\n"
"escolher entre a lista de acesso e o sistema de listas xOP."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1662,9 +1675,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"Sintaxe: SET canal NOBOT {ON|OFF}\n"
"\n"
@@ -1673,7 +1686,7 @@ msgstr ""
"canal, este será automaticamente desassociado quando você\n"
"ativar essa opção."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1693,7 +1706,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1708,7 +1721,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "Comando fornecido: //msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1722,7 +1735,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1734,7 +1747,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr " JUPE Jupa um servidor"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1753,17 +1766,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s não é notificado de novos memos."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
@@ -1788,8 +1801,8 @@ msgstr "%d nicks no grupo."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "Lista de AOP do canal %s está vazia."
@@ -1881,9 +1894,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr " Kick por Caps: %s (mínimo %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "Lista de acesso do canal %s está vazia."
@@ -1893,7 +1906,7 @@ msgstr "Lista de acesso do canal %s está vazia."
msgid "%s added to %s's auto join list."
msgstr "%s adicionado à lista de akick do %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "Bot %s já existe."
@@ -1904,7 +1917,7 @@ msgstr "Bot %s já existe."
msgid "%s autokick list is empty."
msgstr "Lista de akick do %s vazia."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "Lista de palvrões do %s está vazia."
@@ -1914,8 +1927,8 @@ msgstr "Lista de palvrões do %s está vazia."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s não pode ser o successor do canal %s porque ele é o founder."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "Comandos do %s:"
@@ -2015,7 +2028,7 @@ msgstr "%s está online neste momento."
msgid "%s is a network service."
msgstr "%s está online neste momento."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "%s já está coberto pelo AKILL %s."
@@ -2030,7 +2043,7 @@ msgstr "%s adicionado em sua lista de acesso."
msgid "%s is an unconfirmed nickname."
msgstr "Este nick não irá expirar."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2054,7 +2067,7 @@ msgstr "%s está desativada"
msgid "%s is enabled"
msgstr "%s está ativada"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s não é um ban válido."
@@ -2100,7 +2113,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s desabilitado no canal %s."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "Lista de acesso para %s:"
@@ -2110,7 +2123,7 @@ msgstr "Lista de acesso para %s:"
msgid "%s list is empty."
msgstr "Lista de AOP do canal %s está vazia."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s não é notificado de novos memos."
@@ -2167,7 +2180,7 @@ msgstr ""
"%s irá agora notificá-lo de novos memos quando você conectar ou quando "
"desativar o /AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) adicionado à lista de bots."
@@ -2221,12 +2234,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s está ativada"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2293,7 +2306,7 @@ msgstr "%s está online neste momento."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2306,13 +2319,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "Uma mensagem global foi enviada a todos os usuários registrados."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2350,7 +2363,7 @@ msgstr "GROUP alvo senha"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+tempo] {#canal} [motivo]"
@@ -2370,12 +2383,12 @@ msgstr "CHANKILL [+tempo] {#canal} [motivo]"
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID nick motivo"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+tempo] {#canal} [motivo]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+tempo] {#canal} [motivo]"
@@ -2385,15 +2398,15 @@ msgstr "CHANKILL [+tempo] {#canal} [motivo]"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+tempo] {#canal} [motivo]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2407,8 +2420,8 @@ msgstr "AKICK ENFORCE para %s terminado; %d usuários afetados."
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL AKILL todos os usuários de um canal específico"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "A lista de AKILL está vazia."
@@ -2442,17 +2455,17 @@ msgstr "O nível deve ser entre %d e %d inclusive."
msgid "Access level must be non-zero."
msgstr "O nível de acesso deve ser diferente de zero."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "Opções de nível de acesso para o canal %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Níveis de acesso para o %s redefinidos para o padrão."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "Lista de acesso para %s:"
@@ -2466,24 +2479,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE Ativa os recursos de segurança do %s"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2507,7 +2512,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2547,13 +2552,7 @@ msgstr "Uplink server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2574,7 +2573,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Todas as O:lines do servidor %s foram resetadas."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
@@ -2584,16 +2583,11 @@ msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
msgid "All available commands for %s:"
msgstr "Nenhuma ajuda disponível para %s."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Todos os logon news foram removidos."
@@ -2603,12 +2597,12 @@ msgstr "Todos os logon news foram removidos."
msgid "All memos for channel %s have been deleted."
msgstr "Todos os memos para o canal %s foram apagados."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2631,7 +2625,7 @@ msgstr "Todas as O:lines do servidor %s foram removidas."
msgid "All random news items deleted."
msgstr "Todos os itens RandomNews deletados."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
@@ -2643,12 +2637,12 @@ msgstr "Todas as O:lines do servidor %s foram resetadas."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Todos os vhost's no grupo %s foram ajustados para %s@%s"
#: src/access.cpp:41
@@ -2782,7 +2776,7 @@ msgstr ""
"Permite que os IRCops enviem mensagens para todos os usuários\n"
"da Rede. A mensagem será enviada pelo nick %s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2796,7 +2790,7 @@ msgstr ""
"qualquer canal. Os parâmetros são os mesmos do comando\n"
"/MODE padrão."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2808,7 +2802,7 @@ msgstr ""
"qualquer canal. Os parâmetros são os mesmos do comando\n"
"/MODE padrão."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2819,13 +2813,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2892,7 +2886,7 @@ msgstr ""
"\n"
"Ignores will not be enforced on IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2961,7 +2955,7 @@ msgstr ""
"\n"
"AKILL CLEAR apaga todas as entradas da lista de AKILL."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2969,19 +2963,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3030,7 +3022,7 @@ msgstr ""
"o limite de conexões e como especificar limites de conexões\n"
"para certos hosts e grupos de hosts."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3038,12 +3030,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3077,7 +3068,7 @@ msgstr ""
"\n"
"Opções disponíveis:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3095,7 +3086,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3108,7 +3099,7 @@ msgstr ""
"the given user. With MSG set, Services will use messages,\n"
"else they'll use notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3121,7 +3112,7 @@ msgstr ""
"comunicar com você. Com MSG acionado, os Services irão usar\n"
"mensagems, caso contrário, usarão notices. "
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3202,13 +3193,13 @@ msgstr ""
"você terá informações sobre o bot, como o horário de criação\n"
"ou número de canais onde ele está."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Deleta o vHost de outro usuário"
@@ -3218,15 +3209,10 @@ msgstr " DEL Deleta o vHost de outro usuário"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s is a services operator of type %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr " ASSIGN Associa um bot ao canal"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3236,16 +3222,21 @@ msgstr ""
"Você poderá então configurar o bot para o canal de acordo\n"
"com as suas necessidades."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr " ASSIGN Associa um bot ao canal"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr " ASSIGN Associa um bot ao canal"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET Associa uma mensgem de entrada ao seu nick"
@@ -3255,12 +3246,12 @@ msgstr " GREET Associa uma mensgem de entrada ao seu nick"
msgid "Associate a greet message with your nickname"
msgstr " GREET Associa uma mensgem de entrada ao seu nick"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL Associa um endereço de e-mail ao seu nick"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL Associa um endereço de e-mail ao seu nick"
@@ -3270,12 +3261,12 @@ msgstr " EMAIL Associa um endereço de e-mail ao seu nick"
msgid "Associate oper info with a nick or channel"
msgstr " ASSIGN Associa um bot ao canal"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL Associa um endereço de e-mail ao seu nick"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3292,7 +3283,7 @@ msgstr ""
"nick ou o mesmo seje inválido, não será possível recuperar\n"
"a senha perdida."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3321,17 +3312,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "Nenhuma ajuda disponível para %s."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Nenhuma ajuda disponível para %s."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3346,20 +3332,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr " Kick por palavrão: %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "Lista de acesso para %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Lista de palavrões está agora vazia."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "Bot %s já existe."
@@ -3378,7 +3364,7 @@ msgstr "Tipo de ban para o canal %s é agora #%d."
msgid "Bans a given nick or mask on a channel"
msgstr " BAN Bane o nick selecionado em um canal"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3406,7 +3392,7 @@ msgstr "%s não é notificado de novos memos."
msgid "Bolds kicker"
msgstr " Kick por negrito: %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Bot %s já existe."
@@ -3421,12 +3407,12 @@ msgstr "Bot %s já existe."
msgid "Bot %s has been assigned to %s."
msgstr "Bot %s foi associado ao canal %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot %s foi alterado para %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot %s foi removido."
@@ -3456,42 +3442,42 @@ msgstr "Bot não irá kickar OPs no canal %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot não irá kickar voices no canal %s."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Modo NOBOT está agora ATIVADO no canal %s."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "Bot %s foi removido."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot Hosts may only contain %d characters."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "O Host do bot deve conter apenas caracteres válidos a Hosts."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "A Identd do bot deve conter apenas caracteres válidos."
@@ -3509,12 +3495,12 @@ msgstr "Lista de bots:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "O Nick do bot deve conter apenas caracteres válidos a Nicks."
@@ -3607,8 +3593,8 @@ msgstr "O bot não irá mais kickar por flood."
msgid "Bot won't kick for repeats anymore."
msgstr "O bot não irá mais kickar por repetição."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3647,12 +3633,12 @@ msgstr ""
"canal, caso ela ainda não tenha sido lida no momento em que este\n"
"comando for usado."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Bot irá kickar OPs no canal %s."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Não foi possível enviar e-mail agora; tente novamente mais tarde."
@@ -3736,22 +3722,22 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s alterou seus modos de usuário."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr " MSG Altera o método de comunicação dos Services"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s alterou seus modos de usuário."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Modos do usuário %s alterados."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3762,7 +3748,7 @@ msgstr ""
"Altera o display usado como referência ao nome do seu grupo \n"
"nos Services. O novo display DEVE ser um nick do seu grupo."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3784,7 +3770,7 @@ msgstr ""
"Muda o fundador do canal. O novo nick deve estar\n"
"registrado."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3801,7 +3787,7 @@ msgstr ""
"já que Inglês é a linguagem oficial destes Services.\n"
"O número deve ser escolhido da seguinte lista de línguas:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3818,7 +3804,7 @@ msgstr ""
"já que Inglês é a linguagem oficial destes Services.\n"
"O número deve ser escolhido da seguinte lista de línguas:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3826,7 +3812,7 @@ msgstr ""
"\n"
"Muda a senha de seu nick."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3853,7 +3839,7 @@ msgstr ""
"(%d), o canal será dropado, como se nenhum sucessor tivesse\n"
"sido ajustado. O novo nick deverá estar registrado."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP canal"
@@ -3933,12 +3919,12 @@ msgstr "O canal %s irá expirar."
msgid "Channel %s will not expire."
msgstr "O canal %s não irá expirar."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Lista de AOP do canal %s foi limpa."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Lista de acesso do canal %s apagada."
@@ -3948,7 +3934,7 @@ msgstr "Lista de acesso do canal %s apagada."
msgid "Channel %s akick list has been cleared."
msgstr "Lista de akick do canal %s foi limpa."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "Canal %s está agora liberado."
@@ -3975,8 +3961,8 @@ msgstr ""
"Canais nos quais %s tem acesso:\n"
" Núm Canal Nível Descrição "
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s não foi encontrado na lista de acesso do %s."
@@ -4042,7 +4028,7 @@ msgstr " CHECK Verifica se o último memo enviado para um nick foi lido"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Sintaxe: CHECK nick\n"
"\n"
@@ -4142,7 +4128,7 @@ msgstr " KICK Configura os kickers"
msgid "Configures reverses kicker"
msgstr " KICK Configura os kickers"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr " SET Configura as opções do bot"
@@ -4157,7 +4143,7 @@ msgstr " KICK Configura os kickers"
msgid "Confirm a passcode"
msgstr " CONFIRM Confirma um código de autorização do NickServ"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES Limpa os modos de um canal"
@@ -4167,50 +4153,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr " Criado: %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr " Criado: %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Lista de AKILL atual:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Lista de AKILL atual:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Atual lista de Limite de sessões:"
@@ -4264,13 +4250,13 @@ msgstr "FORBID nick motivo"
msgid "DEL [nickname] mask"
msgstr "MODE canal modos"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [canal] {núm | list | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [canal] {núm | list | ALL}"
@@ -4289,19 +4275,19 @@ msgstr "OPERNEWS DEL {núm | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} servidor"
@@ -4315,7 +4301,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4445,17 +4431,22 @@ msgstr " OPERNEWS Define mensagens a serem mostradas a quem pega Oper"
msgid "Delete a memo or memos"
msgstr " DEL Apaga a(s) mensagem(ns)"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Deleta o vHost de todos os nicks de um grupo"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Deleta o vHost de outro usuário"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Deletadas %d entradas da lista de AOP do %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Removidas %d entradas da lista de acesso do %s."
@@ -4465,7 +4456,7 @@ msgstr "Removidas %d entradas da lista de acesso do %s."
msgid "Deleted %d entries from %s autokick list."
msgstr "Removidas %d entradas da lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Removidas %d entradas da lista de palavrões do %s."
@@ -4485,7 +4476,7 @@ msgstr "Deletadas %d entradas da lista de AOP do %s."
msgid "Deleted %d entries from the AKILL list."
msgstr "Removidas %d entradas da lista de AKILL."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "Removida 1 entrada da lista de acesso do %s."
@@ -4495,7 +4486,7 @@ msgstr "Removida 1 entrada da lista de acesso do %s."
msgid "Deleted 1 entry from %s autokick list."
msgstr "Removida 1 entrada da lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Removida 1 entrada da lista de palavrões do %s."
@@ -4518,7 +4509,7 @@ msgstr "Removida 1 entrada da lista de AKILL."
msgid "Deleted info from %s."
msgstr "Removida 1 entrada da lista de AKILL."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Deletada 1 entrada da lista de AOP do %s."
@@ -4566,11 +4557,6 @@ msgstr ""
"Sintaxe: DEL <nick>\n"
"Deleta o vhost associado ao nick dado."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Deleta o vHost de todos os nicks de um grupo"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4581,13 +4567,13 @@ msgstr ""
"Deleta o vhost para todos os nicks no mesmo grupo do\n"
"nick fornecido."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "Descrição do canal %s alterada para %s."
@@ -4602,7 +4588,7 @@ msgstr "Descrição do canal %s alterada para %s."
msgid "Description of %s unset."
msgstr "Descrição do canal %s alterada para %s."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "%s está ativada"
@@ -4627,7 +4613,7 @@ msgstr ""
"\n"
"Um motivo pode ser necessário em algumas redes."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Exibidos todos os registros (Contador: %d)"
@@ -4747,12 +4733,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail address for %s changed to %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail address for %s unset."
@@ -4780,7 +4766,7 @@ msgstr ""
"to them. (However, no more than %s messages will be\n"
"sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"LOGONNEWS may only be used by Services Operators."
@@ -4802,7 +4788,7 @@ msgstr ""
"be sent to them. (However, no more than %s messages will\n"
"be sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"OPERNEWS may only be used by Services Operators."
@@ -4830,7 +4816,7 @@ msgstr " E-mail: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "O nick %s usa o E-mail %s."
#: modules/fantasy.cpp:19
@@ -4841,11 +4827,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "%s está ativada"
@@ -4878,14 +4864,14 @@ msgstr ""
"mesmo depois que os usuários deixarem o canal, e será\n"
"restaurado na próxima vez que o canal for reutilizado."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4984,8 +4970,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Sintaxe: %s canal SECUREOPS {ON|OFF}\n"
"\n"
@@ -5029,7 +5015,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5054,22 +5040,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Fim da listagem."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "Fim da lista de acesso."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Fim da listagem - %d/%d resultados mostrados."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Fim da lista de acesso."
@@ -5078,7 +5064,7 @@ msgstr "Fim da lista de acesso."
msgid "End of autokick list"
msgstr "Fim da lista de acesso."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Fim da listagem."
@@ -5111,7 +5097,7 @@ msgstr "Fim da listagem."
msgid "End of list - %d channels shown."
msgstr "Fim da listagem - %d/%d resultados mostrados."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Fim da listagem - %d/%d resultados mostrados."
@@ -5146,8 +5132,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Português"
@@ -5204,44 +5190,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "Sessão para %s (#%d) alterada para a posição %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exceção para %s foi atualizada para %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr " Expira em: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Exceção para %s foi atualizada para %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Tempo de expiração para %s alterado."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantasia"
@@ -5270,16 +5261,16 @@ msgstr "A máscara %s já se encontra em sua lista de acesso."
msgid "Fingerprint %s is already in use."
msgstr "You are already in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Nível de acesso para %s no %s alterado para %d."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "Lista de acesso para %s:"
@@ -5367,7 +5358,7 @@ msgstr "Founder do canal %s alterado para %s."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "Comando GETPASS não disponível: modo de encriptação ativado."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Seu nick foi derrubado e pode ser usado."
@@ -5376,14 +5367,14 @@ msgstr "Seu nick foi derrubado e pode ser usado."
msgid "Give Operflags to a certain user"
msgstr " OLINE Dá flags de Operador a um determinado usuário"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Concede-lhe status de Owner no canal"
@@ -5459,24 +5450,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Por favor não use reversos no canal!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "Bot %s já existe."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "Bot %s já existe."
@@ -5486,8 +5473,8 @@ msgstr "Bot %s já existe."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Identifica seu nick com sua senha"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Se você não mudar seu nick em 20 segundos, eu irei mudá-lo."
@@ -5500,12 +5487,12 @@ msgstr "Lista de Ignore foi apagada."
msgid "Ignore list is empty."
msgstr "Lista de Ignore dos Services vazia."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "Lista de bots:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Proteção de Voices"
@@ -5562,7 +5549,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5579,7 +5566,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Número inválido. Deve ser um número inteiro maior que 1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5599,17 +5586,17 @@ msgstr " Italics kicker : %s"
msgid "Join a group"
msgstr " GROUP Se junta a um grupo"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Modo mensagem"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Opção Peace para %s está agora ATIVADA."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Opção Peace para %s está agora ATIVADA."
@@ -5628,7 +5615,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr " KICK Kicka um usuário de um canal"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5638,13 +5625,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Kicka (expulsa) um nick de um canal"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Sintaxe: KICK #canal nick [motivo]\n"
"\n"
@@ -5669,19 +5656,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [canal] [list | NEW]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [canal] [list | NEW]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK nick"
@@ -5690,15 +5677,10 @@ msgstr "CHECK nick"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [texto|núm]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Linguagem alterada para Português."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "Successor do canal %s alterado para %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5709,7 +5691,7 @@ msgstr "Último memo enviado para %s foi cancelado."
msgid "Last quit message"
msgstr "Última mensagem de saída: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr " Último horário visto: %s"
@@ -5719,11 +5701,11 @@ msgstr " Último horário visto: %s"
msgid "Last seen address"
msgstr " Último endereço visto: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr " Último horário visto: %s"
@@ -5733,27 +5715,27 @@ msgstr " Último horário visto: %s"
msgid "Last usermask"
msgstr " Último horário visto: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Nível para %s no canal %s alterado para %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "O nível deve ser entre %d e %d inclusive."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5770,7 +5752,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr " ALIST Lista todos os canais nos quais você tem acesso"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5780,7 +5762,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST Lista os módulos carregados"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "Lista de nicks no grupo %s:"
@@ -6032,18 +6014,18 @@ msgstr " MODLIST Lista os módulos carregados"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Mostra informações sobre algum canal registrado"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Sintaxe: INFO canal\n"
"\n"
@@ -6130,7 +6112,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6169,12 +6155,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK Faz a manutenção da Lista de Autokick"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr " BOT Mantém a lista de bots da Rede"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6182,7 +6168,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6200,7 +6186,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6212,7 +6198,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6268,7 +6254,7 @@ msgstr ""
"\n"
"O comando BADWORDS CLEAR limpa todas entradas da lista."
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr " BADWORDS Configura os palavrões"
@@ -6283,7 +6269,7 @@ msgstr ""
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Sintaxe: ACT canal texto\n"
"\n"
@@ -6292,13 +6278,13 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr ""
" SAY Faz com que o bot diga determinado texto no canal dado"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr ""
" SAY Faz com que o bot diga determinado texto no canal dado"
@@ -6331,7 +6317,7 @@ msgstr ""
"de entrada que aparecerá sempre quando você entrar em um canal\n"
"que tenha a opção GREET habilitada, e também tenha acesso a isto."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "Você não pode remover o e-mail nesta Rede."
@@ -6351,12 +6337,12 @@ msgstr " IGNORE Modifica a lista de ignorados dos Services"
msgid "Manage your auto join list"
msgstr " AKICK Faz a manutenção da Lista de Autokick"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL Manipula a lista de AKILL"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL Manipula a lista de AKILL"
@@ -6366,20 +6352,20 @@ msgstr " AKILL Manipula a lista de AKILL"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Manipula o sistema DefCon"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Modifica o tópico de um canal"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6392,8 +6378,8 @@ msgstr "A máscara %s já se encontra em sua lista de acesso."
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "A máscara %s já se encontra em sua lista de acesso."
@@ -6425,7 +6411,7 @@ msgstr " Trava de modo: %s"
msgid "Memo %d has been deleted."
msgstr "Memo %d foi apagado."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Lista de Ignore dos Services vazia."
@@ -6445,7 +6431,7 @@ msgstr "Limite de memos para %s é agora de %d."
msgid "Memo limit for %s set to 0."
msgstr "Limite de memos para %s é agora de 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Memo enviado para %s."
@@ -6460,7 +6446,7 @@ msgstr " Trava de modo: %s"
msgid "Message"
msgstr "GLOBAL mensagem"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Modo mensagem"
@@ -6468,26 +6454,26 @@ msgstr "Modo mensagem"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "%s não encontrado na lista de Ignore."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr " Trava de modo: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr " Trava de modo: %s"
@@ -6496,11 +6482,6 @@ msgstr " Trava de modo: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6550,7 +6531,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6561,7 +6542,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Modifica a lista de ignorados dos Services"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP Modifica a lista de AOP (AutoOP) de um canal"
@@ -6571,7 +6552,7 @@ msgstr " AOP Modifica a lista de AOP (AutoOP) de um canal"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS Modifica a lista de endereços autorizados"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS Modifica a lista de usuários privilegiados"
@@ -6581,7 +6562,7 @@ msgstr " ACCESS Modifica a lista de usuários privilegiados"
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Modifica a lista de ignorados dos Services"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Modifica a lista de limite de sessões"
@@ -6630,14 +6611,14 @@ msgstr "Módulo: %s Versão: %s Autor: %s Carregado: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Módulo: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6650,19 +6631,19 @@ msgstr "Lista de acesso para %s:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "O nick %s foi desregistrado."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "O nick %s já está registrado!"
@@ -6677,7 +6658,6 @@ msgstr "O nick %s já está registrado!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s é um nick ilegal e não pode ser usado."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6693,7 +6673,7 @@ msgstr "Nick %s está atualmente em uso."
msgid "Nick %s is forbidden."
msgstr "Nick %s não está em uso no momento."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s is a services operator of type %s."
@@ -6718,12 +6698,12 @@ msgstr "Nick %s registrado."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s foi truncado para %d caracteres."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s will expire."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s will not expire."
@@ -6788,17 +6768,17 @@ msgstr "O canal %s já está registrado!"
msgid "Nickname %s may not be registered."
msgstr "O canal %s não pode ser registrado."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "O nick %s foi registrado em sua conta: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Nick %s registrado."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6807,7 +6787,7 @@ msgstr "Auto-op"
msgid "No bot"
msgstr "Sem bot"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "não expira"
@@ -6836,13 +6816,13 @@ msgstr "Nenhum logon news para remover!"
msgid "No matches for %s found."
msgstr "Nenhum email listado para %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "Resultado não encontrado na lista de AOP do %s."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Resultado não encontrado na lista de acesso do %s."
@@ -6852,21 +6832,21 @@ msgstr "Resultado não encontrado na lista de acesso do %s."
msgid "No matching entries on %s autokick list."
msgstr "Nenhum resultado encontrado na lista de akick do %s."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Nenhum resultado correspondente encontrado na lista do %s."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "Nenhum resultado encontrado na lista de limite de sessões."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Resultado não encontrado na lista de AOP do %s."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Nenhum resultado equivalente na lista de AKILL."
@@ -6879,7 +6859,12 @@ msgstr "Nenhum memo foi cancelado."
msgid "No modules currently loaded matching that criteria."
msgstr "Nenhum módulo carregado atualmente."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Impedido o registro de novos nicks"
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6899,12 +6884,7 @@ msgstr "Nenhum item RandomNews para deletar!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Impedido o registro de novos nicks"
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6913,8 +6893,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "Lista de acesso para %s:"
@@ -6924,7 +6904,7 @@ msgstr "Lista de acesso para %s:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Modos do usuário %s alterados."
@@ -6939,7 +6919,7 @@ msgstr "Modo NOBOT está agora ATIVADO no canal %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Modo NOBOT está agora ATIVADO no canal %s."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6948,21 +6928,21 @@ msgstr ""
msgid "None"
msgstr "Nenhuma"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -6970,18 +6950,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [texto|núm]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "A informação antiga é igual a nova."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Está online em: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7005,12 +6982,12 @@ msgstr "OperNews não encontrado #%d!"
msgid "Oper news items:"
msgstr "Oper News itens:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "O nick %s foi desregistrado."
@@ -7025,17 +7002,17 @@ msgstr "As Operflags %s foram adicionadas para %s."
msgid "Operflags %s have been removed from %s."
msgstr "As Operflags %s foram adicionadas para %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7049,12 +7026,12 @@ msgstr "Proteção de OPs"
msgid "Options"
msgstr " Opções: %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} servidor"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7071,12 +7048,12 @@ msgstr "Senha incorreta."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "Successor do canal %s alterado para %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "Senha para %s foi enviada."
@@ -7096,7 +7073,7 @@ msgstr "Senha incorreta."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Paz"
@@ -7110,7 +7087,7 @@ msgstr "Opção Peace para %s está agora ATIVADA."
msgid "Peace option for %s is now on."
msgstr "Opção Peace para %s está agora ATIVADA."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7141,12 +7118,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Por favor aguarde %d segundos e tente novamente."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Por favor aguarde %d segundos antes de usar o comando SEND novamente."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Por favor aguarde %d segundos antes de usar o comando SEND novamente."
@@ -7156,13 +7133,13 @@ msgstr "Por favor aguarde %d segundos antes de usar o comando SEND novamente."
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Por favor espere %d segundos antes de usar o comando GROUP novamente."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
"Por favor espere %d segundos antes de usar o comando REGISTER novamente."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7175,7 +7152,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7205,7 +7182,7 @@ msgstr ""
" PRIVATE Prevent the nickname from appearing in a\n"
" /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE Prevent the nickname from expiring"
@@ -7214,17 +7191,17 @@ msgstr " NOEXPIRE Prevent the nickname from expiring"
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Privado"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Modo Privado do bot %s está agora ATIVADO."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Modo Privado do bot %s está agora ATIVADO."
@@ -7249,36 +7226,36 @@ msgstr "Private option is now ON for %s."
msgid "Private option is now on for %s."
msgstr "Private option is now ON for %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Proteção"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Protection is now ON for %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Protection is now ON for %s, with a reduced delay."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Protection is now ON for %s, with no delay."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Protection is now ON for %s."
@@ -7295,7 +7272,7 @@ msgstr ""
"usa por completo todo o host real ident@host para cada nick;\n"
"em seguida, força o AKILL."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Proteção de Voices"
@@ -7341,20 +7318,20 @@ msgstr " READ Lê a(s) mensagem(ns)"
msgid "Real name"
msgstr " RealName: %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "Successor do canal %s removido."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7364,33 +7341,33 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS Redefine os níveis de acesso"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr " RELEASE Retoma a custódia do seu nick após um RECOVER"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s está ativada"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7402,12 +7379,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Registra um nick"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Registra um nick"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr " Hora de registro: %s"
@@ -7466,7 +7443,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7520,7 +7497,7 @@ msgstr ""
"privilégios em canais. Para maiores informações neste recurso,\n"
"digite /msg %s HELP GROUP."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Desculpe, o registro de canais está temporariamente desativado."
@@ -7530,12 +7507,12 @@ msgstr "Desculpe, o registro de canais está temporariamente desativado."
msgid "Regulate the use of critical commands"
msgstr " PEACE Regula o uso de comandos críticos"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Retorna o status do owner de um determinado nick"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Deleta o vHost de outro usuário"
@@ -7584,46 +7561,46 @@ msgstr ""
" NOOP Remove temporariamente todas as O:lines de um \n"
" servidor remotamente"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr " Trava de modo: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr " OP Atribui status de OP a um nick no canal"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Kicka (expulsa) um nick de um canal"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7639,14 +7616,14 @@ msgstr " Kick por repetição: %s"
msgid "Request a vHost for your nick"
msgstr "Não há endereço de email ajustado para o seu nick."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Recarrega o arquivo de configuração dos Services"
@@ -7656,7 +7633,7 @@ msgstr " RELOAD Recarrega o arquivo de configuração dos Services"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Acesso restrito ao canal"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Acesso restrito"
@@ -7691,7 +7668,7 @@ msgstr " KEEPTOPIC Mantem o tópico quando o canal não está em uso"
msgid "Retrieve the password for a nickname"
msgstr " GETPASS Recupera a senha de um determinado nick"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7707,8 +7684,18 @@ msgstr " GETKEY Retorna a key (do modo +k) do canal fornecido"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Retorna a key (do modo +k) do canal fornecido"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Sintaxe: GETEMAIL usuário@emailhost\n"
+"\n"
+"Retorna os nicks que utilizam o email dado. Observe que\n"
+"você não pode usar coringas para usuário nem para emailhost.\n"
+"Sempre que este comando for usado, uma mensagem incluindo a pessoa\n"
+"que emitiu o comando e o email no qual foi usado serão gravados."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7788,16 +7775,16 @@ msgstr " LOGOUT Reverte o efeito do comando IDENTIFY"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} servidor"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Senha aceita - você está agora reconhecido."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Senha aceita - você está agora reconhecido."
@@ -7820,7 +7807,7 @@ msgstr " RESTART Salva os dados e reinicia os Services"
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Founder Seguro"
@@ -7835,7 +7822,7 @@ msgstr "Opção Secure Founder para %s está agora ATIVADA."
msgid "Secure founder option for %s is now on."
msgstr "Opção Secure Founder para %s está agora ATIVADA."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "OPs Seguros"
@@ -7860,12 +7847,12 @@ msgstr "Opção Secure para %s está agora ATIVADA."
msgid "Secure option for %s is now on."
msgstr "Opção Secure para %s está agora ATIVADA."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Secure option is now ON for %s."
@@ -7875,11 +7862,11 @@ msgstr "Secure option is now ON for %s."
msgid "Secureops enforced on %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Segurança"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7888,7 +7875,7 @@ msgstr ""
"Digite /msg %s HELP SET opção para maiores informações\n"
"sobre uma opção em particular."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7957,7 +7944,7 @@ msgstr ""
"Envia um memo a todos os membros da Staff dos Services\n"
"contendo uma mensagem."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8032,14 +8019,14 @@ msgid "Server %s already exists."
msgstr "Bot %s já existe."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "O nick %s foi desregistrado."
@@ -8049,12 +8036,12 @@ msgstr "O nick %s foi desregistrado."
msgid "Server %s is already in zone %s."
msgstr "You are already in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s está online neste momento."
@@ -8069,12 +8056,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "Não possui mais nenhum bot associado ao canal %s."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8094,19 +8081,18 @@ msgstr "Servers found: %d"
msgid "Service"
msgstr "Servers found: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Seu nick foi derrubado e pode ser usado."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s is a services operator of type %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr ""
@@ -8163,7 +8149,7 @@ msgstr "Os services foram configurados para não enviar e-mail."
msgid "Services ignore list:"
msgstr " IGNORE Modifica a lista de ignorados dos Services"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8177,7 +8163,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Servers found: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8187,7 +8173,7 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8197,12 +8183,12 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services will now autoop %s in channels."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services will now reply to %s with messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services will now reply to %s with notices."
@@ -8221,7 +8207,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Limite de sessões para %s é agora de %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Opção de limite de sessões desabilitada."
@@ -8265,7 +8251,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC Ajusta a descrição do canal"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Mostra o seu grupo nos Services"
@@ -8275,14 +8261,14 @@ msgstr " DISPLAY Mostra o seu grupo nos Services"
msgid "Set the founder of a channel"
msgstr " FOUNDER Ajusta o fundador do canal"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE Ajusta a linguagem dos Services quando\n"
" mensagens são enviadas à você"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Set the nickname password"
@@ -8651,7 +8637,7 @@ msgstr ""
"\n"
"Ajusta várias opções de nick. A opção pode ser:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8668,7 +8654,7 @@ msgstr ""
"Ajustando para ON, evita que o canal seja desregistrado\n"
"por passar do tempo de expiração."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8683,7 +8669,7 @@ msgstr ""
"Set to ON to allow ChanServ to op the given nickname \n"
"automatically when joining channels."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8694,7 +8680,7 @@ msgstr ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8707,7 +8693,7 @@ msgstr ""
"Sets whether you will be opped automatically. Set to ON to \n"
"allow ChanServ to op you automatically when entering channels."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8774,11 +8760,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Opção Signed Kicks para %s está agora ATIVADA."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "Kicks assinados"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s possui muitos memos atualmente e não pode receber mais nenhum."
@@ -8788,45 +8774,39 @@ msgstr "%s possui muitos memos atualmente e não pode receber mais nenhum."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Desculpe, o comando BADWORDS está temporariamente desatvado."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Desculpe, o comando SET está temporariamente desativado."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Desculpe, comando CHANGE temporariamente desativado."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Desculpe, o comando SET está temporariamente desativado."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Desculpe, o comando SET está temporariamente desativado."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Desculpe, a modificação da lista de AOP está temporariamente desabilitada."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Desculpe, o registro de canais está temporariamente desativado."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Desculpe, o comando AKICK está temporariamente desativado."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Desculpe, o comando BADWORDS está temporariamente desatvado."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Desculpe, o comando DROP está temporariamente desativado."
@@ -8857,7 +8837,7 @@ msgstr "Desculpe, o comando DROP está temporariamente desativado."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Desculpe, o comando GROUP está temporariamente desativado."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Desculpe, registros de nick estão temporariamente desativados."
@@ -8877,13 +8857,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Desculpe, você pode ter somente %d entradas em sua lista de acesso."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8896,7 +8871,7 @@ msgstr ""
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Desculpe, você pode ter apenas %d akicks na lista do canal."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Desculpe, você pode ter apenas %d palavrões em sua lista."
@@ -8963,7 +8938,7 @@ msgstr "Successor do canal %s removido."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "Opção SuperAdmin não habilitada no arquivo services.conf"
+msgstr "Opção SuperAdmin não habilitada no arquivo anope.conf"
#: modules/commands/ns_suspend.cpp:60
#, fuzzy
@@ -9185,7 +9160,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9261,7 +9236,7 @@ msgstr ""
"Esta opção não é permanente, e deve ser usada somente quando\n"
"necessária, e desativada quando não for mais necessária."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9283,7 +9258,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Sintaxe: INVITE #canal\n"
@@ -9300,7 +9275,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Sintaxe: UNBAN #canal [nick]\n"
@@ -9352,7 +9327,7 @@ msgstr " SHUTDOWN Termina os Services salvando os dados"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9363,7 +9338,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9372,7 +9347,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9389,10 +9364,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9400,14 +9375,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9422,7 +9397,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Sintaxe: HOP canal ADD nick\n"
@@ -9464,36 +9439,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "O comando IMMED não está disponível nesta Rede."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9541,7 +9516,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9552,18 +9527,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9571,7 +9546,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9585,7 +9560,6 @@ msgstr ""
"para terceiros."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9603,7 +9577,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9613,12 +9587,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "Lista de AKILL apagada."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "Lista de AKILL apagada."
@@ -9637,7 +9611,7 @@ msgstr "The E-mail address of %s will now be hidden from %s INFO displays."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "The E-mail address of %s will now be shown in %s INFO displays."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9668,11 +9642,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9734,12 +9708,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "O limite de memos para %s não pode ser mudado."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9754,10 +9723,6 @@ msgstr "O Nível do Defcon está agora no Nível: %d"
msgid "The nick %s is now being changed to %s."
msgstr "O nick %s está sendo alterado para %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9781,12 +9746,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"The services access status of %s will now be shown in %s INFO displays."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Modifica a lista de limite de sessões"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9858,7 +9823,7 @@ msgstr "Não há RandomNews."
msgid "There is no such configuration block %s."
msgstr " RELOAD Recarrega o arquivo de configuração dos Services"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Não existe nenhum oper news."
@@ -9886,7 +9851,7 @@ msgstr "Este canal não pode ser usado."
msgid "This channel may not be used."
msgstr "Este canal não pode ser usado."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9922,7 +9887,7 @@ msgstr ""
"Este comando permite aos usuários ajustar o vhost do seu\n"
"nick ATUAL para ser o vhost de todos os nicks no mesmo grupo."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9935,7 +9900,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -9970,8 +9935,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10069,7 +10034,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10084,7 +10049,7 @@ msgstr ""
"Este comando carrega o módulo chamado NomeDoArquivo\n"
"do diretório de módulos."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10138,7 +10103,7 @@ msgstr ""
"Este comando carrega o módulo chamado NomeDoArquivo\n"
"do diretório de módulos."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10154,12 +10119,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Este nick está atualmente suspenso, motivo: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "Este nick está atualmente suspenso, motivo: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10220,7 +10185,7 @@ msgstr ""
msgid "Topic"
msgstr "Trava de tópico"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Trava de tópico"
@@ -10235,7 +10200,7 @@ msgstr "Trava de tópico para %s está agora ATIVADA."
msgid "Topic lock option for %s is now on."
msgstr "Trava de tópico para %s está agora ATIVADA."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Retenção de tópico"
@@ -10250,7 +10215,7 @@ msgstr "Retenção de tópico para %s está agora ATIVADA."
msgid "Topic retention option for %s is now on."
msgstr "Retenção de tópico para %s está agora ATIVADA."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10258,17 +10223,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Desligue o CAPS LOCK!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE Ativa/Desativa os recursos de segurança para o seu nick"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE Ativa/Desativa os recursos de segurança para o seu nick"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL Ativa/Desativa a proteção de kill para o seu nick"
@@ -10307,7 +10273,7 @@ msgstr ""
"o comando %s's LIST. (Entretando, alguém que sabe do seu\n"
"nick ainda pode obter informações usando o comando INFO)."
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10338,7 +10304,7 @@ msgstr " SECURE Ativa/Desativa os recursos de segurança para o seu nick"
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE Ativa/Desativa os recursos de segurança para o seu nick"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10369,7 +10335,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10400,7 +10366,7 @@ msgstr ""
"não usar essa opção, a não ser que seja necessário. Pode\n"
"acontecer do Administrador da Rede desabilitar essa opção."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10437,7 +10403,7 @@ msgstr ""
"on a specific option. The options will be set on the given\n"
"nickname. "
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10446,7 +10412,7 @@ msgstr ""
"Digite /msg %s HELP SET opção para maiores informações\n"
"sobre uma opção em particular."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10462,8 +10428,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Descarrega um módulo"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Impossível remover o módulo %s"
@@ -10507,7 +10473,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr " Kick por sublinhado: %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Unknown SASET option %s."
@@ -10527,7 +10493,7 @@ msgstr "Opção desconhecida: %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Comando desconhecido %s. Digite %s%s HELP para ajuda."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Modo %c desconhecido e ignorado."
@@ -10555,8 +10521,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Sintaxe: DROP canal\n"
"\n"
@@ -10572,10 +10538,10 @@ msgstr " UNSUSPEND Libera o nick fornecido"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10625,31 +10591,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s alterou seus modos de usuário."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS Modifica a lista de usuários privilegiados"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "Você não está mais banido do %s."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "vhost para %s removido."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Limite de memos para %s é agora de %d."
@@ -10702,13 +10668,13 @@ msgstr "vhost do grupo %s ajustado para %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [canal] [list | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10721,7 +10687,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "Founder do canal %s alterado para %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10759,7 +10725,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10852,7 +10818,7 @@ msgstr ""
"A opção RESET reinicia a contagem do máximo de usuários\n"
"para o número de usuários atualmente conectados na rede."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10861,7 +10827,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Você já é um membro do grupo %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Você já está identificado."
@@ -10926,7 +10892,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10952,13 +10918,22 @@ msgid "You can not request a receipt when sending a memo to yourself."
msgstr ""
"Você não pode pedir uma notificação ao enviar uma mensagem a si próprio."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Você não pode usar o comando GHOST em si mesmo!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Resultado não encontrado na lista de acesso do %s."
@@ -10969,16 +10944,11 @@ msgid "You can't logout %s, they are a Services Operator."
msgstr ""
"Impossível fazer logout em %s porque ele é um Administrador dos Services."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "Você não pode remover o e-mail nesta Rede."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10989,12 +10959,7 @@ msgstr "Você não pode colocar o limite de memos para %s maior que %d."
msgid "You cannot set your memo limit higher than %d."
msgstr "Você não pode colocar seu limite de memos maior que %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "Você não pode remover o e-mail nesta Rede."
@@ -11034,12 +10999,12 @@ msgstr "Você possui atualmente 1 memo."
msgid "You currently have no memos."
msgstr "Você não possui nenhum memo atualmente."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11075,7 +11040,7 @@ msgstr "You have been invited to %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "Seu nick foi desconectado."
@@ -11118,32 +11083,27 @@ msgstr ""
"Atenção: Você atingiu seu número máximo de memos (%d). Não será possível "
"receber novos memos enquanto você não apagar alguns."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Deleta o vHost de todos os nicks de um grupo"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "Você não pode remover o e-mail nesta Rede."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "Você não pode remover o e-mail nesta Rede."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr ""
@@ -11193,26 +11153,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "Você deve ser no mínimo um operador para registrar o canal."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
msgstr "Você deve ser no mínimo um operador para registrar o canal."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "Você deve ser no mínimo um operador para registrar o canal."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "Você deve ser no mínimo um operador para registrar o canal."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11220,18 +11165,18 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"Você deve estar conectado há mais de %d segundos para registrar seu nick."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11245,39 +11190,17 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Você será notificado de novos memos quando eles forem enviados."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Você será notificado de novos memos quando conectar e quando eles forem "
-"enviados."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Você será notificado de novos memos quando conectar e quando eles forem "
"enviados."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Você será notificado de novos memos quando conectar e quando eles forem "
-"enviados."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Você será notificado de novos memos quando conectar."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Você será notificado de novos memos quando eles forem enviados."
@@ -11289,7 +11212,7 @@ msgstr "Você não poderá mais receber memos."
msgid "You will no longer be informed via email."
msgstr "Você não será mais notificado por email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Você será notificado de novos memos."
@@ -11315,23 +11238,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "Bot %s foi removido."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "Você já está identificado."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Você já está identificado."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "E-mail address for %s changed to %s."
@@ -11341,18 +11264,18 @@ msgstr "E-mail address for %s changed to %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Todas as O:lines do servidor %s foram removidas."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Todas as O:lines do servidor %s foram removidas."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "E-mail address for %s changed to %s."
@@ -11412,7 +11335,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Nick %s registrado."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Seu nick está sendo mudado para %s."
@@ -11421,43 +11344,42 @@ msgstr "Seu nick está sendo mudado para %s."
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Seu passcode foi re-enviado para %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Sua senha é %s - guarde ela para uso posterior."
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "Bot %s foi removido."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Seu vhost %s está agora ativado."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Seu vhost %s@%s está agora ativado."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -11507,7 +11429,7 @@ msgstr "[Random News - %s] %s"
msgid "[account] password"
msgstr "IDENTIFY senha"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #channel [nick]"
@@ -11565,8 +11487,8 @@ msgstr "INFO nick"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK nick"
@@ -11588,7 +11510,7 @@ msgstr "CHANKILL [+tempo] {#canal} [motivo]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11596,22 +11518,22 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[Auto-Memo] O memo que você enviou para %s foi lido."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[Auto-Memo] O memo que você enviou para %s foi lido."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "Último memo enviado para %s foi cancelado."
@@ -11716,12 +11638,12 @@ msgstr ""
msgid "seconds"
msgstr "Comandos do %s:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Seu vhost %s está agora ativado."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "Bot %s foi removido."
@@ -11757,27 +11679,7 @@ msgstr "UNBAN canal [nick]"
msgid "{nick | channel}"
msgstr "CANCEL {nick | canal}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {nick | canal} texto"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "Sessão para %s (#%d) alterada para a posição %d."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "A informação antiga é igual a nova."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Sintaxe: GETEMAIL usuário@emailhost\n"
-#~ "\n"
-#~ "Retorna os nicks que utilizam o email dado. Observe que\n"
-#~ "você não pode usar coringas para usuário nem para emailhost.\n"
-#~ "Sempre que este comando for usado, uma mensagem incluindo a pessoa\n"
-#~ "que emitiu o comando e o email no qual foi usado serão gravados."
diff --git a/language/anope.ru_RU.po b/language/anope.ru_RU.po
index 42e8d2638..0b3d4ddb5 100644
--- a/language/anope.ru_RU.po
+++ b/language/anope.ru_RU.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 21:10-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Russian\n"
@@ -28,17 +28,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "Ваш ник уÑпешно удален из базы данных ÑервиÑов."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок AKILL'ов."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s добавлен в ÑпиÑок доÑтупа канала %s Ñ ÑƒÑ€Ð¾Ð²Ð½ÐµÐ¼ доÑтупа %d."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s добавлен в ÑпиÑок доÑтупа канала %s Ñ ÑƒÑ€Ð¾Ð²Ð½ÐµÐ¼ доÑтупа %d."
@@ -48,7 +48,7 @@ msgstr "%s добавлен в ÑпиÑок доÑтупа канала %s Ñ
msgid "%s added to %s autokick list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок автокиков канала %s."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок плохих Ñлов канала %s."
@@ -63,17 +63,17 @@ msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑÐ
msgid "%s added to %s's certificate list."
msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑпиÑок доÑтупа."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑпиÑок доÑтупа."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок AKILL'ов."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок AKILL'ов."
@@ -109,7 +109,7 @@ msgstr ""
"информации по конкретной команде, напишите\n"
"/msg %s HELP команда."
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -127,7 +127,7 @@ msgstr ""
"Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации по какой-либо команде иÑпользуйте:\n"
"/msg %s HELP команда."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -144,7 +144,7 @@ msgstr ""
"Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации по какой-либо команде иÑпользуйте:\n"
"/msg %s HELP команда."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -166,7 +166,7 @@ msgstr ""
"/msg %s HELP команда\n"
" "
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "ЗапиÑÑŒ вида %s уже ÑодержитÑÑ Ð² ÑпиÑке плохих Ñлов канала %s."
@@ -187,7 +187,7 @@ msgstr "ЗапиÑÑŒ вида %s уже приÑутÑтвует в ÑпиÑк
msgid "%s cannot be taken as times to ban."
msgstr "Значение вида %s не может быть иÑпользовано как кол-во киков до бана."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s принудительно изменил ваши пользовательÑкие режимы."
@@ -197,12 +197,12 @@ msgstr "%s принудительно изменил ваши пользова
msgid "%s channel list:"
msgstr "Конец ÑпиÑка каналов."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s уÑпешно удален из AOP'ов канала %s."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "Ðик %s уÑпешно удален из ÑпиÑка доÑтупа канала %s."
@@ -212,7 +212,7 @@ msgstr "Ðик %s уÑпешно удален из ÑпиÑка доÑтупа
msgid "%s deleted from %s autokick list."
msgstr "ЗапиÑÑŒ вида %s удалена из ÑпиÑка автокиков канала %s."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно удалена из ÑпиÑка плохих Ñлов канала %s."
@@ -237,12 +237,12 @@ msgstr "ЗапиÑÑŒ вида %s уÑпешно удалена из ÑпиÑк
msgid "%s deleted from the %s list."
msgstr "%s уÑпешно удален из AOP'ов канала %s."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно удалена из ÑпиÑка AKILL'ов."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "Уровень доÑтупа к %s на канале %s отключен."
@@ -318,7 +318,7 @@ msgstr "You are already in %s! "
msgid "%s is already in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑпиÑок доÑтупа."
@@ -328,7 +328,7 @@ msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑÐ
msgid "%s is already suspended."
msgstr "You are already in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr ""
@@ -360,7 +360,7 @@ msgstr "Уровень доÑтупа к %s на канале %s отключÐ
msgid "%s is not in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "Ðик %s в ÑпиÑке игнорируемых не обнаружен."
@@ -392,12 +392,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок автокиков канала %s."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "Ðик %s в ÑпиÑке AOP'ов канала %s не обнаружен."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "Ðик %s в ÑпиÑке доÑтупа канала %s не обнаружен."
@@ -407,7 +407,7 @@ msgstr "Ðик %s в ÑпиÑке доÑтупа канала %s не обна
msgid "%s not found on %s autokick list."
msgstr "ЗапиÑÑŒ вида %s в ÑпиÑке автокиков канала %s не обнаружена."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "ЗапиÑÑŒ вида %s в ÑпиÑке плохих Ñлов канала %s не обнаружена."
@@ -444,17 +444,17 @@ msgstr "ЗапиÑÑŒ вида %s в ÑпиÑке иÑключений из лÐ
msgid "%s not found on the %s list."
msgstr "Ðик %s в ÑпиÑке AOP'ов канала %s не обнаружен."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "ЗапиÑÑŒ вида %s в ÑпиÑке AKILL'ов не обнаружена."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "Ðик %s уÑпешно удален из ÑпиÑка доÑтупа канала %s."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "МаÑка вида %s уÑпешно удалена из вашего ÑпиÑка доÑтупа."
@@ -487,11 +487,11 @@ msgstr ""
"Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации о какой-либо конкретной опции, Ñм.\n"
"Ñправку по /msg %s HELP опциÑ"
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -499,12 +499,12 @@ msgstr ""
"BOT CHANGE Ñтарый_ник новый_ник [идент [хоÑÑ‚ [реальное_имÑ]]]\n"
"BOT DEL ник"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <ник>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -519,6 +519,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -587,7 +590,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -606,18 +609,18 @@ msgstr ""
msgid "[target] [password]"
msgstr "GROUP главный_ник пароль"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET ник AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -660,7 +663,7 @@ msgstr "UNBAN #канал [nick]"
msgid "channel nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR #канал что_именно"
@@ -670,7 +673,7 @@ msgstr "CLEAR #канал что_именно"
msgid "channel text"
msgstr "ACT #канал текÑÑ‚"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT #канал текÑÑ‚"
@@ -685,12 +688,12 @@ msgstr "KICK #канал ник причина"
msgid "channel what"
msgstr "TOPIC #канал [текÑÑ‚_топика]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE #канал режимы"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -699,7 +702,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE #канал режимы"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -708,19 +711,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC #канал [текÑÑ‚_топика]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP #канал"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC #канал [текÑÑ‚_топика]"
@@ -735,7 +738,7 @@ msgstr "DROP #канал"
msgid "channel DEL num"
msgstr "MODE #канал режимы"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_запиÑей | ALL}"
@@ -745,7 +748,7 @@ msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_зÐ
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP #канал {ADD|DEL|LIST|CLEAR} [ник | номер запиÑ]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_запиÑей | ALL}"
@@ -754,7 +757,7 @@ msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_зÐ
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP #канал"
@@ -764,41 +767,50 @@ msgstr "DROP #канал"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP #канал {ADD|DEL|LIST|CLEAR} [ник | номер запиÑ]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP #канал {ADD|DEL|LIST|CLEAR} [ник | номер запиÑ]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP #канал {ADD|DEL|LIST|CLEAR} [ник | номер запиÑ]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET #канал GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE #канал режимы"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC #канал [текÑÑ‚_топика]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP #канал {ADD|DEL|LIST|CLEAR} [ник | номер запиÑ]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_запиÑей | ALL}"
@@ -808,7 +820,7 @@ msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_зÐ
msgid "channel [description]"
msgstr "REGISTER #канал опиÑание"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN #канал [nick]"
@@ -818,7 +830,7 @@ msgstr "UNBAN #канал [nick]"
msgid "channel [parameters]"
msgstr "CLEAR #канал что_именно"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN #канал [nick]"
@@ -833,23 +845,13 @@ msgstr "BAN #channel nick [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #channel nick [reason]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC #канал [текÑÑ‚_топика]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP #канал"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET #канал XOP {ON | OFF}"
@@ -877,7 +879,7 @@ msgstr "KICK #канал опциÑ {ON|OFF} [параметры]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET #канал XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -901,27 +903,27 @@ msgstr "SET #канал XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE номер"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL Ñообщение"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -931,8 +933,9 @@ msgid "new-password"
msgstr "GROUP главный_ник пароль"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO ник"
@@ -962,18 +965,18 @@ msgstr "SET <ник> <хоÑтмаÑка>."
msgid "nick newnick"
msgstr "SVSNICK ник новый_ник "
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK ник"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID ник причина"
@@ -983,7 +986,7 @@ msgstr "FORBID ник причина"
msgid "nickname email"
msgstr "FORBID ник причина"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID ник причина"
@@ -993,12 +996,12 @@ msgstr "FORBID ник причина"
msgid "nickname message"
msgstr "FORBID ник причина"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID ник причина"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST ник [пароль]"
@@ -1008,7 +1011,7 @@ msgstr "GHOST ник [пароль]"
msgid "nickname [parameter]"
msgstr "GHOST ник [пароль]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST ник [пароль]"
@@ -1023,15 +1026,15 @@ msgstr "FORBID ник причина"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET ник AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET ник KILL {ON | QUICK | IMMED | OFF}"
@@ -1075,12 +1078,12 @@ msgstr "REGISTER пароль email"
msgid "password"
msgstr "GROUP главный_ник пароль"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER пароль email"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER пароль email"
@@ -1100,7 +1103,7 @@ msgstr "LIST маÑка [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE имÑ_Ñервера [причина]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE #канал режимы"
@@ -1110,7 +1113,7 @@ msgstr "MODE #канал режимы"
msgid "user [reason]"
msgstr "JUPE имÑ_Ñервера [причина]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1129,7 +1132,7 @@ msgstr ""
"ников и другие злонамеренные дейÑÑ‚Ð²Ð¸Ñ - приведут, как минимум, к\n"
"уничтожению Ñтих Ñамых ников."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1196,7 +1199,7 @@ msgstr ""
"\n"
"AKILL CLEAR позволÑет полноÑтью очиÑтить ÑпиÑок AKILL'ов."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1260,7 +1263,7 @@ msgstr ""
"\n"
"AKILL CLEAR позволÑет полноÑтью очиÑтить ÑпиÑок AKILL'ов."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1397,7 +1400,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1419,7 +1422,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1432,7 +1435,7 @@ msgstr ""
"к нему, а так же, могут Ñмотреть ÑпиÑок доÑтупа любого ника\n"
"(более подробно Ñм. /msg %s ACCESS LIST ник)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1445,7 +1448,7 @@ msgstr ""
"к нему в качеÑтве владельца, могут проÑматривать ÑпиÑки доÑтупа\n"
"каналов, а так же, ÑпиÑки акиков и уÑтановки уровней доÑтупа каналов."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1454,7 +1457,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1516,7 +1529,7 @@ msgstr ""
"команды ACCESS и ÑиÑтемы привилегий xOP Ñм. Ñправочную информацию\n"
"по /msg %s HELP ACCESS и /msg %s HELP SET XOP."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1540,7 +1553,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1603,7 +1616,7 @@ msgstr ""
"команды ACCESS и ÑиÑтемы привилегий xOP Ñм. Ñправочную информацию\n"
"по /msg %s HELP ACCESS и /msg %s HELP SET XOP."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1666,7 +1679,7 @@ msgstr ""
"команды ACCESS и ÑиÑтемы привилегий xOP Ñм. Ñправочную информацию\n"
"по /msg %s HELP ACCESS и /msg %s HELP SET XOP."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1733,9 +1746,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"СинтакÑиÑ: SET #канал NOBOT {ON|OFF}\n"
"\n"
@@ -1745,7 +1758,7 @@ msgstr ""
"ЕÑли бот уже уÑтановлен на канале, он будет автоматичеÑки удален Ñ\n"
"него Ñразу же поÑле Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ опции."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1766,7 +1779,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1781,7 +1794,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "ПредоÑтавлÑÐµÐ¼Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: /msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1795,7 +1808,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1808,7 +1821,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr " JUPE \"Джуп\" указанного Ñервера Ñети"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1827,17 +1840,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s не уведомлÑетÑÑ Ð¾ новых ÑобщениÑÑ…."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
@@ -1862,8 +1875,8 @@ msgstr "КоличеÑтво ников в группе: %d"
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "СпиÑок AOP'ов канала %s пуÑÑ‚."
@@ -1955,9 +1968,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr "Цензор CapsLOCK......: %s (минимум %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "СпиÑок доÑтупа канала %s пуÑÑ‚."
@@ -1967,7 +1980,7 @@ msgstr "СпиÑок доÑтупа канала %s пуÑÑ‚."
msgid "%s added to %s's auto join list."
msgstr "ЗапиÑÑŒ вида %s уÑпешно добавлена в ÑпиÑок автокиков канала %s."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
@@ -1978,7 +1991,7 @@ msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
msgid "%s autokick list is empty."
msgstr "СпиÑок автокиков канала %s пуÑÑ‚."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "СпиÑок плохих Ñлов канала %s пуÑÑ‚."
@@ -1988,8 +2001,8 @@ msgstr "СпиÑок плохих Ñлов канала %s пуÑÑ‚."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s не может быть наÑледником канала %s так как он его владелец."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "СпиÑок команд %s:"
@@ -2089,7 +2102,7 @@ msgstr "%s ÑÐµÐ¹Ñ‡Ð°Ñ Ð² Ñети."
msgid "%s is a network service."
msgstr "%s ÑÐµÐ¹Ñ‡Ð°Ñ Ð² Ñети."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr ""
@@ -2105,7 +2118,7 @@ msgstr "МаÑка вида %s уÑпешно добавлена в ваш ÑÐ
msgid "%s is an unconfirmed nickname."
msgstr "Дополнительно: региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñтого ника никогда не иÑтечет."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2129,7 +2142,7 @@ msgstr "Режим %s: отключен."
msgid "%s is enabled"
msgstr "Режим %s: включен."
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "ЧиÑло %s не ÑвлÑетÑÑ Ð²Ð°Ð»Ð¸Ð´Ð½Ñ‹Ð¼ номером шаблона банмаÑки."
@@ -2176,7 +2189,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "Уровень доÑтупа к %s на канале %s отключен."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
@@ -2186,7 +2199,7 @@ msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
msgid "%s list is empty."
msgstr "СпиÑок AOP'ов канала %s пуÑÑ‚."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s не уведомлÑетÑÑ Ð¾ новых ÑобщениÑÑ…."
@@ -2244,7 +2257,7 @@ msgstr ""
"С Ñтого момента, %s будет уведомлÑть Ð²Ð°Ñ Ð¾ новых ÑообщениÑÑ… Ñразу поÑле "
"идентификации к нику или по возвращению из режима /AWAY."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) добавлен в ÑпиÑок ботов."
@@ -2298,12 +2311,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "Режим %s: включен."
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2370,7 +2383,7 @@ msgstr "%s ÑÐµÐ¹Ñ‡Ð°Ñ Ð² Ñети."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2384,13 +2397,13 @@ msgid "A massmemo has been sent to all registered users."
msgstr ""
"МаÑÑовое Ñообщение уÑпешно отправлено вÑем зарегиÑтрированным пользователÑм."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2429,7 +2442,7 @@ msgstr "GROUP главный_ник пароль"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причина]"
@@ -2449,12 +2462,12 @@ msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причин
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID ник причина"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причина]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причина]"
@@ -2464,15 +2477,15 @@ msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причин
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причина]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2486,8 +2499,8 @@ msgstr "AKICK ENFORCE на канале %s завершен, пользоваÑ
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL \"Прибить\" вÑех пользователей на указанном канале"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "СпиÑок AKILL'ов пуÑÑ‚."
@@ -2521,17 +2534,17 @@ msgstr "Уровень должен быть чиÑлом между %d и %d в
msgid "Access level must be non-zero."
msgstr "Уровень доÑтупа должен быть отличен от нулÑ."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "УÑтановки ÑпиÑка доÑтупа Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "Уровни доÑтупа Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s Ñброшены на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾-умолчанию."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
@@ -2545,24 +2558,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE дополнительные возможноÑти %s'а по безопаÑноÑти"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2588,7 +2593,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2628,13 +2633,7 @@ msgstr "Uplink-Ñервер: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2655,7 +2654,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Ð’Ñе OLINE-запиÑи на Ñервере %s воÑÑтановлены."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
@@ -2665,16 +2664,11 @@ msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы
msgid "All available commands for %s:"
msgstr "Ð¡Ð¿Ñ€Ð°Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾ %s отÑутÑтвует."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "СпиÑок новоÑтей полноÑтью очищен."
@@ -2684,12 +2678,12 @@ msgstr "СпиÑок новоÑтей полноÑтью очищен."
msgid "All memos for channel %s have been deleted."
msgstr "Ð’Ñе ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s были удалены."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2712,7 +2706,7 @@ msgstr "Ð’Ñе OLINE-запиÑи на Ñервере %s были удален
msgid "All random news items deleted."
msgstr "СпиÑок Ñлучайных новоÑтей полноÑтью очищен."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
@@ -2724,12 +2718,12 @@ msgstr "Ð’Ñе OLINE-запиÑи на Ñервере %s воÑÑтановлÐ
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "Ð’Ñе виртуальные хоÑты Ð´Ð»Ñ Ð½Ð¸ÐºÐ¾Ð² группы %s уÑтановлены на %s@%s"
#: src/access.cpp:41
@@ -2864,7 +2858,7 @@ msgstr ""
"вÑем пользователÑм Ñети. Ð’ качеÑтве ника Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ Ð±ÑƒÐ´ÐµÑ‚ указан\n"
"%s."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2879,7 +2873,7 @@ msgstr ""
"том же формате, в котором указываете при ручной уÑтановке, Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ\n"
"команды /MODE."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2892,7 +2886,7 @@ msgstr ""
"том же формате, в котором указываете при ручной уÑтановке, Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ\n"
"команды /MODE."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2903,13 +2897,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2980,7 +2974,7 @@ msgstr ""
"Пользователи Ñо ÑтатуÑом IRC-оператора игнорироватьÑÑ ÑервиÑами не\n"
"будут, даже еÑли они приÑутÑтвуют в ÑпиÑке игнора."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -3052,7 +3046,7 @@ msgstr ""
"\n"
"AKILL CLEAR позволÑет полноÑтью очиÑтить ÑпиÑок AKILL'ов."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -3060,19 +3054,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3121,7 +3113,7 @@ msgstr ""
"ÑеÑÑий и как уÑтановить отдельный лимит ÑеÑÑий Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ð¾Ð³Ð¾\n"
"хоÑта или группы хоÑтов."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3129,12 +3121,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3167,7 +3158,7 @@ msgstr ""
"ПозволÑет владельцу канала менÑть различные наÑтройки канала.\n"
"ДоÑтупные опции:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3185,7 +3176,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3201,7 +3192,7 @@ msgstr ""
"уведомлений (notice, нотиÑÑ‹).\n"
"Примечание: наÑтройка данной опции может быть заблокирована."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3216,7 +3207,7 @@ msgstr ""
"заÑтавит ÑервиÑÑ‹ иÑпользовать режим уведомлений (notice, нотиÑÑ‹).\n"
"Примечание: наÑтройка данной опции может быть заблокирована."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3305,13 +3296,13 @@ msgstr ""
"опции).\n"
"Примечание: данные будут поÑланы от лица %s"
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Удаление виртуального хоÑта"
@@ -3321,15 +3312,10 @@ msgstr " DEL Удаление виртуального хоÑта"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s is a services operator of type %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr "ASSIGN УÑтановка бота на указанный канал"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3339,16 +3325,21 @@ msgstr ""
"же поÑле уÑтановки, вы Ñможете Ñконфигурировать опции бота по Ñвоему\n"
"уÑмотрению."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr "ASSIGN УÑтановка бота на указанный канал"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "ASSIGN УÑтановка бота на указанный канал"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET уÑтановка приветÑтвенного ÑообщениÑ"
@@ -3358,12 +3349,12 @@ msgstr " GREET уÑтановка приветÑтвенного ÑооÐ
msgid "Associate a greet message with your nickname"
msgstr " GREET уÑтановка приветÑтвенного ÑообщениÑ"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL уÑтановка email-адреÑа на ник"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL уÑтановка email-адреÑа на ник"
@@ -3373,12 +3364,12 @@ msgstr " EMAIL уÑтановка email-адреÑа на ник"
msgid "Associate oper info with a nick or channel"
msgstr "ASSIGN УÑтановка бота на указанный канал"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL уÑтановка email-адреÑа на ник"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3390,7 +3381,7 @@ msgstr ""
"ÐÑÑоциирует email-Ð°Ð´Ñ€ÐµÑ Ñ Ð²Ð°ÑˆÐ¸Ð¼ ником. Данный email будет показан\n"
"в информации о вашем нике, предоÑтавлÑемой по команде INFO."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "ÐвтоÑтатуÑ"
@@ -3419,17 +3410,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "Ð¡Ð¿Ñ€Ð°Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾ %s отÑутÑтвует."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "Ð¡Ð¿Ñ€Ð°Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾ %s отÑутÑтвует."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3444,20 +3430,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr "Цензор плохих Ñлов...: %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "СпиÑок \"плохих\" Ñлов полноÑтью очищен."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
@@ -3476,7 +3462,7 @@ msgstr "Шаблон банмаÑки на канале %s изменен на #
msgid "Bans a given nick or mask on a channel"
msgstr " BAN УÑтановка бана на канале"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3504,7 +3490,7 @@ msgstr "%s не уведомлÑетÑÑ Ð¾ новых ÑобщениÑÑ…."
msgid "Bolds kicker"
msgstr "Цензор жирных букв...: %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
@@ -3519,12 +3505,12 @@ msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
msgid "Bot %s has been assigned to %s."
msgstr "Бот %s уÑпешно назначен на канал %s."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Данные о боте %s были изменены на %s!%s@%s (%s)"
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "Бот под ником %s уÑпешно удален."
@@ -3555,42 +3541,42 @@ msgstr ""
msgid "Bot won't kick voices on channel %s."
msgstr "Теперь, войÑÑ‹ канала %s будут иÑключены из уÑловий кика за нарушениÑ."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Режим без-бота Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "Бот под ником %s уÑпешно удален."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "ХоÑÑ‚ бота не должен превышать %d Ñимволов."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Указанный Ð´Ð»Ñ Ð±Ð¾Ñ‚Ð° хоÑÑ‚ Ñодержит недопуÑтимые Ñимволы."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Идент бота не должен превышать %d Ñимволов."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Указанный Ð´Ð»Ñ Ð±Ð¾Ñ‚Ð° идент Ñодержит недопуÑтимые Ñимволы."
@@ -3608,12 +3594,12 @@ msgstr "СпиÑок ботов:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Идент бота не должен превышать %d Ñимволов."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Указанный Ð´Ð»Ñ Ð±Ð¾Ñ‚Ð° ник Ñодержит недопуÑтимые Ñимволы."
@@ -3708,8 +3694,8 @@ msgstr "Режим кика за флуд отключен."
msgid "Bot won't kick for repeats anymore."
msgstr "Режим кика за чрезмерные повторы отключен."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3747,12 +3733,12 @@ msgstr ""
"ОтменÑет поÑледнее Ñообщение, отправленное вами указанному нику\n"
"или каналу, тем Ñамым предохранÑÑ ÐµÐ³Ð¾ от Ð¿Ñ€Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð°Ð´Ñ€ÐµÑатом."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "С Ñтого момента, бот будет кикать операторов канала %s за нарушениÑ."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Ðа данный момент отправка email невозможна, попробуйте позже."
@@ -3789,7 +3775,7 @@ msgid ""
msgstr ""
"СинтакÑиÑ: RELOAD\n"
"\n"
-"ЗаÑтавлÑет ÑервиÑÑ‹ перечитать конфигурационный файл services.conf.\n"
+"ЗаÑтавлÑет ÑервиÑÑ‹ перечитать конфигурационный файл anope.conf.\n"
"Примечание: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… новых/измененных директив конфига\n"
"требует полного перезапуÑка ÑервиÑов (например: изменение ников\n"
"ÑервиÑов, Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð»Ð¸Ð¼Ð¸Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑеÑÑий, и Ñ‚.д.)"
@@ -3836,22 +3822,22 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s принудительно изменил ваши пользовательÑкие режимы."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr " MSG выбор метода Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÑервиÑов Ñ Ð²Ð°Ð¼Ð¸"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s принудительно изменил ваши пользовательÑкие режимы."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Режимы Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s изменены."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3863,7 +3849,7 @@ msgstr ""
"отображатьÑÑ Ð² ÑпиÑке доÑтупа каналов, где вы пропиÑаны.\n"
"Примечание: новый главный ник должен ÑоÑтоÑть в вашей группе ников."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3886,7 +3872,7 @@ msgstr ""
"ПозволÑет передать права на владение каналом другому пользователю.\n"
"Ðик нового владельца канала должен быть зарегиÑтрированным."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3902,7 +3888,7 @@ msgstr ""
"Ð’ качеÑтве номера, вы должны указать конкретный номер Ñзыка из\n"
"ÑпиÑка поддерживаемых Ñзыков:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3918,7 +3904,7 @@ msgstr ""
"Ð’ качеÑтве номера, вы должны указать конкретный номер Ñзыка из\n"
"ÑпиÑка поддерживаемых Ñзыков:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3927,7 +3913,7 @@ msgstr ""
"ПозволÑет изменить пароль ника, иÑпользуемый Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ к\n"
"нему в качеÑтве полноправного владельца."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3956,7 +3942,7 @@ msgstr ""
"каналом и тот будет удален. Ко вÑему прочему, ник наÑледника канала\n"
"должен быть зарегиÑтрированным ником."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP #канал"
@@ -4037,12 +4023,12 @@ msgstr "Режим иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ времени Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s
msgid "Channel %s will not expire."
msgstr "С Ñтого момента, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s никогда не иÑтечет."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "СпиÑок AOP'ов канала %s был полноÑтью очищен."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "СпиÑок доÑтупа канала %s был полноÑтью очищен."
@@ -4052,7 +4038,7 @@ msgstr "СпиÑок доÑтупа канала %s был полноÑтью о
msgid "Channel %s akick list has been cleared."
msgstr "СпиÑок AKICK'ов на канале %s был полноÑтью очищен."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "Канал %s уÑпешно воÑÑтановлен из режима ÑаÑпенда."
@@ -4079,8 +4065,8 @@ msgstr ""
"Каналы, на которых у %s еÑть уровни доÑтупа:\n"
"Ðомер Канал Уровень ОпиÑание"
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "Ðик %s в ÑпиÑке доÑтупа канала %s не обнаружен."
@@ -4148,7 +4134,7 @@ msgstr ""
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"СинтакÑиÑ: CHECK ник\n"
"\n"
@@ -4249,7 +4235,7 @@ msgstr "KICK ÐаÑтройка уÑловий KICK'а"
msgid "Configures reverses kicker"
msgstr "KICK ÐаÑтройка уÑловий KICK'а"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "SET ÐаÑтройка различных опций бота"
@@ -4264,7 +4250,7 @@ msgstr "KICK ÐаÑтройка уÑловий KICK'а"
msgid "Confirm a passcode"
msgstr " CONFIRM Подтверждение региÑтрации кодом аутенфикации"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES ОчиÑтка вÑех режимов указанного канала"
@@ -4274,50 +4260,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr "Создан..........: %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr "Создан..........: %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Текущий ÑпиÑок AKILL'ов:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Текущий ÑпиÑок AKILL'ов:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Текущий ÑпиÑок иÑключений из лимита ÑеÑÑий:"
@@ -4371,13 +4357,13 @@ msgstr "FORBID ник причина"
msgid "DEL [nickname] mask"
msgstr "MODE #канал режимы"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_запиÑей | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [#канал] {номер_ÑообщениÑ | ÑпиÑок_запиÑей | ALL}"
@@ -4396,19 +4382,19 @@ msgstr "СинтакÑиÑ: OPERNEWS DEL {номер | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} Ñервер"
@@ -4422,7 +4408,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4552,17 +4538,22 @@ msgstr " OPERNEWS Управление ÑпиÑком опер-новоÑÑ
msgid "Delete a memo or memos"
msgstr " DEL Удаление мемо-Ñообщений"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Удаление вирт. хоÑта у вÑех ников указанной группы"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Удаление виртуального хоÑта"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Удалено %d запиÑей из ÑпиÑка AOP'ов канала %s."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Удалено %d запиÑей из ÑпиÑка доÑтупа канала %s."
@@ -4572,7 +4563,7 @@ msgstr "Удалено %d запиÑей из ÑпиÑка доÑтупа кан
msgid "Deleted %d entries from %s autokick list."
msgstr "Удалено %d запиÑей из ÑпиÑка актокиков канала %s."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Удалено %d запиÑей из ÑпиÑка плохих Ñлов канала %s."
@@ -4592,7 +4583,7 @@ msgstr "Удалено %d запиÑей из ÑпиÑка AOP'ов канала
msgid "Deleted %d entries from the AKILL list."
msgstr "Удалено %d запиÑей из ÑпиÑка AKILL'ов."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "Удалена 1 запиÑÑŒ из ÑпиÑка доÑтупа канала %s."
@@ -4602,7 +4593,7 @@ msgstr "Удалена 1 запиÑÑŒ из ÑпиÑка доÑтупа канаÐ
msgid "Deleted 1 entry from %s autokick list."
msgstr "Удалена 1 запиÑÑŒ из ÑпиÑка автокиков канала %s."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "Удалена 1 запиÑÑŒ из ÑпиÑка плохих Ñлов канала %s."
@@ -4625,7 +4616,7 @@ msgstr "Удалена 1 запиÑÑŒ из Ñпика AKILL'ов."
msgid "Deleted info from %s."
msgstr "Удалена 1 запиÑÑŒ из Ñпика AKILL'ов."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "Удалена 1 запиÑÑŒ из ÑпиÑка AOP'ов канала %s."
@@ -4675,11 +4666,6 @@ msgstr ""
"\n"
"УдалÑет виртуальный хоÑÑ‚ назначенный указанному нику."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Удаление вирт. хоÑта у вÑех ников указанной группы"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4690,13 +4676,13 @@ msgstr ""
"\n"
"УдалÑет виртуальные хоÑты у вÑех ников указанной группы."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "ОпиÑание канала %s изменено на %s."
@@ -4711,7 +4697,7 @@ msgstr "ОпиÑание канала %s изменено на %s."
msgid "Description of %s unset."
msgstr "ОпиÑание канала %s изменено на %s."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "Режим %s: включен."
@@ -4741,7 +4727,7 @@ msgstr ""
"Примечание: в завиÑимоÑти от наÑтроек ÑервиÑов, причина может\n"
"быть параметром как опциональным, так и необходимым."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Конец ÑпиÑка хоÑтов, запиÑей наÑчитано: %d"
@@ -4862,12 +4848,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ %s изменен на %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ %s удален."
@@ -4895,7 +4881,7 @@ msgstr ""
"Стоит заметить, что во избежание флуда пользователь получит только\n"
"%d новоÑть(и), так что еÑли у Ð²Ð°Ñ Ð² ÑпиÑке их больше - показаны\n"
"будут только поÑледние из них. Значение NewsCount, отвечающее за\n"
-"одновременно поÑылаемое кол-во новоÑтей, указываетÑÑ Ð² services.conf\n"
+"одновременно поÑылаемое кол-во новоÑтей, указываетÑÑ Ð² anope.conf\n"
"\n"
"Команда LOGONNEWS ADD позволÑет добавить новоÑть в ÑпиÑок.\n"
"\n"
@@ -4924,7 +4910,7 @@ msgstr ""
"Стоит заметить, что во избежание флуда пользователь получит только\n"
"%d новоÑть(и), так что еÑли у Ð²Ð°Ñ Ð² ÑпиÑке их больше - показаны\n"
"будут только поÑледние из них. Значение NewsCount, отвечающее за\n"
-"одновременно поÑылаемое кол-во новоÑтей, указываетÑÑ Ð² services.conf\n"
+"одновременно поÑылаемое кол-во новоÑтей, указываетÑÑ Ð² anope.conf\n"
"\n"
"Команда OPERNEWS ADD позволÑет добавить новоÑть в ÑпиÑок.\n"
"\n"
@@ -4965,7 +4951,7 @@ msgstr "Email-адреÑ.............: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Ðайдено ÑоответÑтвие Ð´Ð»Ñ Ð½Ð¸ÐºÐ° %s: %s."
#: modules/fantasy.cpp:19
@@ -4976,11 +4962,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "Режим %s: включен."
@@ -5016,14 +5002,14 @@ msgstr ""
"же, как только канал Ñнова Ñтанет активным (то еÑть, на него опÑть\n"
"кто-либо зайдет)."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -5129,8 +5115,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"СинтакÑиÑ: %s #канал SECUREOPS {ON | OFF}\n"
"\n"
@@ -5177,7 +5163,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5202,22 +5188,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Конец ÑпиÑка пользователей."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "Конец ÑпиÑка доÑтупа."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Конец ÑпиÑка - %d/%d запиÑей показано."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "Конец ÑпиÑка доÑтупа."
@@ -5226,7 +5212,7 @@ msgstr "Конец ÑпиÑка доÑтупа."
msgid "End of autokick list"
msgstr "Конец ÑпиÑка доÑтупа."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Конец ÑпиÑка пользователей."
@@ -5259,7 +5245,7 @@ msgstr "Конец ÑпиÑка пользователей."
msgid "End of list - %d channels shown."
msgstr "Конец ÑпиÑка - %d/%d запиÑей показано."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Конец ÑпиÑка - %d/%d запиÑей показано."
@@ -5294,8 +5280,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "РуÑÑкий"
@@ -5352,44 +5338,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "ИÑключение Ð´Ð»Ñ %s (#%d) перемещено в позицию %d."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Лимит ÑеÑÑий Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи вида %s был изменен на %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¸Ñтекает....: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Лимит ÑеÑÑий Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи вида %s был изменен на %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "Срок иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñи %s уÑпешно изменен."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "FANTASY-режим"
@@ -5418,16 +5409,16 @@ msgstr "МаÑка вида %s уже приÑутÑтвует в вашем Ñ
msgid "Fingerprint %s is already in use."
msgstr "You are already in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "Уровень доÑтупа Ð´Ð»Ñ %s на канале %s изменен на %d."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
@@ -5515,7 +5506,7 @@ msgstr "Ð’Ñе права на владение каналом %s уÑпешно
msgid "GETPASS command unavailable because encryption is in use."
msgstr "Команда GETPASS недоÑтупна, так как включено шифрование паролей."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "СеÑÑÐ¸Ñ Ñ Ð²Ð°ÑˆÐ¸Ð¼ завиÑшим ником уÑпешно закрыта."
@@ -5524,14 +5515,14 @@ msgstr "СеÑÑÐ¸Ñ Ñ Ð²Ð°ÑˆÐ¸Ð¼ завиÑшим ником уÑпешно з
msgid "Give Operflags to a certain user"
msgstr " OLINE УÑтановка оперфлагов указанному пользователю Ñети"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑтатуÑа владельца на канале"
@@ -5607,24 +5598,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "ИÑпользование инверÑии у Ð½Ð°Ñ Ñ‚ÑƒÑ‚ не приветÑтвуетÑÑ!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
@@ -5634,8 +5621,8 @@ msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ðº нику в качеÑтве владельца"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr ""
@@ -5650,12 +5637,12 @@ msgstr "СпиÑок игнорируемых ников полноÑтью оч
msgid "Ignore list is empty."
msgstr "СпиÑок игнорируемых ников пуÑÑ‚."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "СпиÑок ботов:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Ðе кикать войÑов"
@@ -5712,7 +5699,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5731,7 +5718,7 @@ msgstr ""
"Ðекорректное значение Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð³Ð° ÑеÑÑий. Ð’ качеÑтве параметра должно быть "
"целое чиÑло >1."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5752,17 +5739,17 @@ msgstr "Italics kicker : %s"
msgid "Join a group"
msgstr " GROUP Объединение ников в группы"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Режим приватных Ñообщений"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Режим ÑпокойÑтвиÑ Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Режим ÑпокойÑтвиÑ Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
@@ -5781,7 +5768,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr " KICK Кикнуть Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ ÐºÐ°Ð½Ð°Ð»Ð° поÑредÑтвом ÑервиÑов"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5791,13 +5778,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Выкидывает указанного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"СинтакÑиÑ: KICK #канал ник [причина]\n"
"\n"
@@ -5823,19 +5810,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [#канал] [ÑпиÑок_запиÑей | NEW]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [#канал] [ÑпиÑок_запиÑей | NEW]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK ник"
@@ -5844,15 +5831,10 @@ msgstr "CHECK ник"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [текÑÑ‚|номер]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Язык ÑервиÑов изменен на РуÑÑкий."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "ÐаÑледником канала %s назначен пользователь %s."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5863,7 +5845,7 @@ msgstr "ПоÑледнее ваше Ñообщение адреÑату %s уÑ
msgid "Last quit message"
msgstr "ПоÑледнее quit-Ñообщение: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr "ПоÑледний раз замечен...: %s"
@@ -5873,11 +5855,11 @@ msgstr "ПоÑледний раз замечен...: %s"
msgid "Last seen address"
msgstr "ПоÑледнÑÑ Ð¼Ð°Ñка.........: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr "ПоÑледний раз замечен...: %s"
@@ -5887,27 +5869,27 @@ msgstr "ПоÑледний раз замечен...: %s"
msgid "Last usermask"
msgstr "ПоÑледний раз замечен...: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "Уровень доÑтупа к %s на канале %s изменен на %d."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Уровень должен быть чиÑлом между %d и %d включительно."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5922,7 +5904,7 @@ msgstr " LIST СпиÑок вÑех зарегиÑтрированныÑ
msgid "List channels you have access on"
msgstr " ALIST Вывод ÑпиÑка каналов, на которых у Ð²Ð°Ñ ÐµÑть доÑтуп"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5932,7 +5914,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST СпиÑок загруженных модулей"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "СпиÑок ников в группе %s:"
@@ -6190,18 +6172,18 @@ msgstr " MODLIST СпиÑок загруженных модулей"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ об указанном канале"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"СинтакÑиÑ: INFO #канал\n"
"\n"
@@ -6286,7 +6268,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6325,12 +6311,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK Управление ÑпиÑком автокиков канала"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr "BOT Управление ÑервиÑными ботами"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6338,7 +6324,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6356,7 +6342,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6368,7 +6354,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6428,7 +6414,7 @@ msgstr ""
"Ð’ качеÑтве дополнительного параметра, вы можете указать Ñимвольную\n"
"маÑку, что позволит вам получить ÑпиÑок Ñ ÐºÐ¾Ð½ÐºÑ€Ðµ"
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr "BADWORDS Управление ÑпиÑком \"плохих\" Ñлов"
@@ -6442,7 +6428,7 @@ msgstr "ACT Выполнить дейÑтвие от лица бÐ
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"СинтакÑиÑ: ACT #канал текÑÑ‚\n"
"\n"
@@ -6452,12 +6438,12 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr "SAY ПоÑлать на указанный канал текÑÑ‚ от лица бота"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr "SAY ПоÑлать на указанный канал текÑÑ‚ от лица бота"
#: modules/commands/greet.cpp:157
@@ -6490,7 +6476,7 @@ msgstr ""
"что Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÑ‚ÑтвиÑ, на канале должна быть активирована\n"
"Ð¾Ð¿Ñ†Ð¸Ñ GREET и вы должны иметь ÑоответÑтвующий уровень доÑтупа."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "ВозможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ email-адреÑа в вашей IRC-Ñети недоÑтупна."
@@ -6510,12 +6496,12 @@ msgstr " IGNORE Управление игнор-ÑпиÑком ÑервÐ
msgid "Manage your auto join list"
msgstr " AKICK Управление ÑпиÑком автокиков канала"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL Управление ÑпиÑком AKILL'ов"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL Управление ÑпиÑком AKILL'ов"
@@ -6525,20 +6511,20 @@ msgstr " AKILL Управление ÑпиÑком AKILL'ов"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Управление ÑиÑтемой DefCon (защитных контрмер)"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC УÑтановка топика на канале поÑредÑтвом ÑервиÑов"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6551,8 +6537,8 @@ msgstr "МаÑка вида %s уже приÑутÑтвует в вашем Ñ
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "МаÑка вида %s уже приÑутÑтвует в вашем ÑпиÑке доÑтупа."
@@ -6582,7 +6568,7 @@ msgstr "Блокировка режимов........: %s"
msgid "Memo %d has been deleted."
msgstr "Сообщение под номером %d было удалено."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "СпиÑок игнорируемых ников пуÑÑ‚."
@@ -6602,7 +6588,7 @@ msgstr "Лимит Ñобщений Ð´Ð»Ñ %s уÑтановлен на %d."
msgid "Memo limit for %s set to 0."
msgstr "Лимит Ñообщений Ð´Ð»Ñ %s уÑтановлен на 0."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "Мемо-Ñообщение Ð´Ð»Ñ %s уÑпешно отправлено."
@@ -6617,7 +6603,7 @@ msgstr "Блокировка режимов........: %s"
msgid "Message"
msgstr "GLOBAL Ñообщение"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Режим приватных Ñообщений"
@@ -6625,26 +6611,26 @@ msgstr "Режим приватных Ñообщений"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Ðик %s в ÑпиÑке игнорируемых не обнаружен."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr "Блокировка режимов........: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr "Блокировка режимов........: %s"
@@ -6653,11 +6639,6 @@ msgstr "Блокировка режимов........: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6706,7 +6687,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6717,7 +6698,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Управление игнор-ÑпиÑком ÑервиÑов"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP Управление ÑпиÑком AOP'ов канала"
@@ -6727,7 +6708,7 @@ msgstr " AOP Управление ÑпиÑком AOP'ов канала
msgid "Modify the list of authorized addresses"
msgstr " ACCESS Управление ACCESS-ÑпиÑком ника (ÑпиÑком хоÑтмаÑок)"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS Управление ACCESS-ÑпиÑком привилегий канала"
@@ -6737,7 +6718,7 @@ msgstr " ACCESS Управление ACCESS-ÑпиÑком привиле
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Управление игнор-ÑпиÑком ÑервиÑов"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Управление ÑпиÑком иÑключений из лимита ÑеÑÑий"
@@ -6786,14 +6767,14 @@ msgstr "Модуль: %s ВерÑиÑ: %s Ðвтор: %s Загружен:
msgid "Module: %s [%s] [%s]"
msgstr "Модуль: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6806,19 +6787,19 @@ msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO ник"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "Ðик %s уÑпешно удален из базы данных ÑервиÑов."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "Ðик %s уже зарегиÑтрирован!"
@@ -6833,7 +6814,6 @@ msgstr "Ðик %s уже зарегиÑтрирован!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Указанный ник %s Ñодержит недопуÑтимые Ñимволы."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6849,7 +6829,7 @@ msgstr "Ðик %s на данный момент иÑпользуетÑÑ ÐºÐµ
msgid "Nick %s is forbidden."
msgstr "Ðа данный момент, ник %s ÑервиÑами не удерживаетÑÑ."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s is a services operator of type %s."
@@ -6874,12 +6854,12 @@ msgstr "Ðик %s уÑпешно зарегиÑтрирован."
msgid "Nick %s was truncated to %d characters."
msgstr "Ðик %s был уÑечен до %d Ñимволов."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "C Ñтого момента ник %s Ñнова в режиме иÑтечениÑ."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "С Ñтого момента региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¸ÐºÐ° %s никогда не иÑтечет."
@@ -6944,18 +6924,18 @@ msgstr "Канал %s уже зарегиÑтрирован!"
msgid "Nickname %s may not be registered."
msgstr "Канал %s не может быть зарегиÑтрирован."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr ""
"Ðик %s уÑпешно зарегиÑтрирован, в ACCESS-ÑпиÑок добавлена хоÑтмаÑка: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Ðик %s уÑпешно зарегиÑтрирован."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "ÐвтоÑтатуÑ"
@@ -6964,7 +6944,7 @@ msgstr "ÐвтоÑтатуÑ"
msgid "No bot"
msgstr "Без ботов"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "никогда не иÑтечет"
@@ -6993,13 +6973,13 @@ msgstr "СпиÑок новоÑтей пуÑÑ‚, удалÑть нечего."
msgid "No matches for %s found."
msgstr "Ðики Ñ email-адреÑом %s не обнаружены."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "Совпадающих запиÑей в ÑпиÑке AOP'ов канала %s не обнаружено."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Совпадающих запиÑей в ÑпиÑке доÑтупа канала %s не обнаружено."
@@ -7009,22 +6989,22 @@ msgstr "Совпадающих запиÑей в ÑпиÑке доÑтупа кÐ
msgid "No matching entries on %s autokick list."
msgstr "Совпадающих значений в ÑпиÑке автокиков канала %s не обнаружено."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Ð’ ÑпиÑке плохих Ñлов канала %s Ñовпадающих запиÑей не обнаружено."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr ""
"Совпадающих значений в ÑпиÑке иÑключений из лимита ÑеÑÑий не обнаружено."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "Совпадающих запиÑей в ÑпиÑке AOP'ов канала %s не обнаружено."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Совпадающих запиÑей не обнаружено."
@@ -7037,7 +7017,12 @@ msgstr "Ðет Ñообщений доÑтупных Ð´Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹."
msgid "No modules currently loaded matching that criteria."
msgstr "СпиÑок модулей пуÑÑ‚."
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* Запрет на региÑтрацию ников."
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -7057,12 +7042,7 @@ msgstr "СпиÑок Ñлучайных новоÑтей пуÑÑ‚, удалÑÑ‚Ñ
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* Запрет на региÑтрацию ников."
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -7071,8 +7051,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
@@ -7082,7 +7062,7 @@ msgstr "СпиÑок доÑтупа Ð´Ð»Ñ %s:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Режимы Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s изменены."
@@ -7097,7 +7077,7 @@ msgstr "Режим без-бота Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активировÐ
msgid "No-bot mode is now on on channel %s."
msgstr "Режим без-бота Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -7106,21 +7086,21 @@ msgstr ""
msgid "None"
msgstr "отÑутÑтвуют"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -7128,18 +7108,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [текÑÑ‚|номер]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Ð¡Ñ‚Ð°Ñ€Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ боте не отличаетÑÑ Ð¾Ñ‚ новой."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr "Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð¾Ð½Ð»Ð°Ð¹Ð½, c маÑкой.: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7163,12 +7140,12 @@ msgstr "ÐовоÑть под номером #%d не обнаружена."
msgid "Oper news items:"
msgstr "СпиÑок новоÑтей Ð´Ð»Ñ IRC-операторов:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "Ðик %s уÑпешно удален из базы данных ÑервиÑов."
@@ -7183,17 +7160,17 @@ msgstr "OLINE-флаги %s уÑпешно уÑтановлены Ð´Ð»Ñ ÑеÑ
msgid "Operflags %s have been removed from %s."
msgstr "OLINE-флаги %s уÑпешно уÑтановлены Ð´Ð»Ñ ÑеÑÑий Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s"
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7207,12 +7184,12 @@ msgstr "Ðе кикать операторов"
msgid "Options"
msgstr "Опции...........: %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} Ñервер"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7229,12 +7206,12 @@ msgstr "Вы указали неверный пароль."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "ÐаÑледником канала %s назначен пользователь %s."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "Пароль Ð´Ð»Ñ Ð½Ð¸ÐºÐ° %s был выÑлан на его email-адреÑ."
@@ -7254,7 +7231,7 @@ msgstr "Вы указали неверный пароль."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "СпокойÑтвие"
@@ -7268,7 +7245,7 @@ msgstr "Режим ÑпокойÑтвиÑ Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активи
msgid "Peace option for %s is now on."
msgstr "Режим ÑпокойÑтвиÑ Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7300,13 +7277,13 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "ПожалуйÑта, подождите %d Ñекунд и повторите запроÑ."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr ""
"ПожалуйÑта, подождите %d Ñекунд перед повторным иÑпользованием команды SEND."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr ""
@@ -7317,12 +7294,12 @@ msgstr ""
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "Подождите %d Ñекунд перед повторным иÑпользованием команды GROUP."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr "Подождите %d Ñекунд перед повторным иÑпользованием команды REGISTER."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7335,7 +7312,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7363,7 +7340,7 @@ msgstr " NOEXPIRE Prevent the channel from expiring"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr " PRIVATE Ñкрытие ника в ÑпиÑке ников по /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE уÑтановка на ник Ñ‚.н. режима 'не-иÑтечениÑ'"
@@ -7372,17 +7349,17 @@ msgstr " NOEXPIRE уÑтановка на ник Ñ‚.н. режима 'не-
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "ПриватноÑть"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "Бот под ником %s уÑпешно помечен как приватный."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "Бот под ником %s уÑпешно помечен как приватный."
@@ -7407,36 +7384,36 @@ msgstr "Режим приватноÑти Ð´Ð»Ñ %s активирован."
msgid "Private option is now on for %s."
msgstr "Режим приватноÑти Ð´Ð»Ñ %s активирован."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Защита"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Защита ника %s активирована, лимит времени на ввод паролÑ: 60 Ñекунд."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Защита ника %s активирована,лимит времени на ввод паролÑ: 20 Ñекунд."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Защита ника %s активирована, лимит времени на ввод паролÑ: 0 Ñекунд."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Защита ника %s активирована, лимит времени на ввод паролÑ: 60 Ñекунд."
@@ -7453,7 +7430,7 @@ msgstr ""
"указанной причиной на указанный промежуток времени. Ð’ качеÑтве маÑки\n"
"AKILL'ов будут иÑпользованы маÑки поÑетителей канала вида идент@хоÑÑ‚."
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Ðе кикать войÑов"
@@ -7499,20 +7476,20 @@ msgstr " READ Чтение какого-либо ÑообщениÑ, гру
msgid "Real name"
msgstr "Реальное имÑ....: %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "ÐаÑледник канал %s удален."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7522,34 +7499,34 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS ПереуÑтановка Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑƒÑ€Ð¾Ð²Ð½ÐµÐ¹ доÑтупа канала"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr ""
" RELEASE СнÑтие защиты ÑервиÑов Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ ника поÑле команды RECOVER"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "Режим %s: включен."
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7561,12 +7538,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¸ÐºÐ°"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¸ÐºÐ°"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr "ЗарегиÑтрирован.........: %s"
@@ -7625,7 +7602,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7677,7 +7654,7 @@ msgstr ""
"Ñ Ð¾Ð±Ñ‰ÐµÐ¹ Ð´Ð»Ñ Ð½Ð¸Ñ… информацией, наÑтройками, ÑпиÑком доÑтупа. Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ\n"
"подробной информации Ñм. /msg %s HELP GROUP"
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Извините, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² временно приоÑтановлена."
@@ -7687,13 +7664,13 @@ msgstr "Извините, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² временно
msgid "Regulate the use of critical commands"
msgstr " PEACE активирование режима \"ÑпокойÑтвиÑ\" на канале"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr ""
" STATUS Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑтатуÑа идентификации указанного ника на ÑервиÑах"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Удаление виртуального хоÑта"
@@ -7741,47 +7718,47 @@ msgstr ""
" NOOP Временное удаление вÑех O:line'ов Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾\n"
" Ñервера Ñети"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr "Блокировка режимов........: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr ""
" OP УÑтановка ÑтатуÑа оператора (+o) указанному нику на канале"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Выкидывает указанного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7797,14 +7774,14 @@ msgstr "Цензор повторов......: %s"
msgid "Request a vHost for your nick"
msgstr "Ð”Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ ника не уÑтановлен email-адреÑ."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Перезагрузка конфигурационного файла ÑервиÑов"
@@ -7814,7 +7791,7 @@ msgstr " RELOAD Перезагрузка конфигурационноÐ
msgid "Restrict access to the channel"
msgstr " RESTRICTED ограничение ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´Ð¾Ñтупа на канал до пропиÑанных"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Ограниченный доÑтуп"
@@ -7849,7 +7826,7 @@ msgstr " KEEPTOPIC активирование автоÑохранениÑ
msgid "Retrieve the password for a nickname"
msgstr " GETPASS Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ ника"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7865,8 +7842,18 @@ msgstr " GETKEY Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑƒÑтановленного на канал
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑƒÑтановленного на канале ключа (+k)"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"СинтакÑиÑ: GETEMAIL user@emailhost\n"
+"Выводит ÑпиÑок ников, в наÑтройках у которых Ñтоит указанный email.\n"
+"Примечание: вы не можете иÑпользовать Ñимвольные маÑки ни Ð´Ð»Ñ user,\n"
+"ни Ð´Ð»Ñ emailhost. Каждый раз, при иÑпользовании данной команды,\n"
+"Ñообщение, включающее ник вызвавшего команду и указанный email,\n"
+"будет запиÑано в лог-файл ÑервиÑов."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7948,16 +7935,16 @@ msgstr " LOGOUT Ð”ÐµÐ¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¾Ñ‚ иÑпользуемÐ
msgid "SET server"
msgstr "NOOP {SET|REVOKE} Ñервер"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Пароль принÑÑ‚ - вы признаны как владелец ника."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Пароль принÑÑ‚ - вы признаны как владелец ника."
@@ -7980,7 +7967,7 @@ msgstr " RESTART Сохранить базы данных и переза
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "БезопаÑноÑть владельца"
@@ -7995,7 +7982,7 @@ msgstr "Режим безопаÑноÑти владельца Ð´Ð»Ñ ÐºÐ°Ð½Ð°
msgid "Secure founder option for %s is now on."
msgstr "Режим безопаÑноÑти владельца Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Контроль ÑтатуÑа оператора"
@@ -8020,12 +8007,12 @@ msgstr "Режим безопаÑноÑти Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s актив
msgid "Secure option for %s is now on."
msgstr "Режим безопаÑноÑти Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Режим безопаÑноÑти Ð´Ð»Ñ %s активирован."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Режим безопаÑноÑти Ð´Ð»Ñ %s активирован."
@@ -8035,11 +8022,11 @@ msgstr "Режим безопаÑноÑти Ð´Ð»Ñ %s активирован
msgid "Secureops enforced on %s."
msgstr "Режим безопаÑноÑти Ð´Ð»Ñ %s активирован."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "БезопаÑноÑть"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -8048,7 +8035,7 @@ msgstr ""
"Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации о какой-либо конкретной опции, Ñм.\n"
"Ñправку по /msg %s HELP опциÑ"
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -8119,7 +8106,7 @@ msgstr ""
"ПозволÑет отправить мемо-Ñообщение вÑем операторам/админиÑтраторам\n"
"ÑервиÑов Ñети."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8194,14 +8181,14 @@ msgid "Server %s already exists."
msgstr "Бот Ñ Ð½Ð¸ÐºÐ¾Ð¼ %s уже ÑущеÑтвует."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "Ðик %s уÑпешно удален из базы данных ÑервиÑов."
@@ -8211,12 +8198,12 @@ msgstr "Ðик %s уÑпешно удален из базы данных ÑеÑ
msgid "Server %s is already in zone %s."
msgstr "You are already in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr "%s ÑÐµÐ¹Ñ‡Ð°Ñ Ð² Ñети."
@@ -8231,12 +8218,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "Бот Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s уÑпешно удален."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8256,19 +8243,18 @@ msgstr "Текущее кол-во Ñерверов: %d"
msgid "Service"
msgstr "Текущее кол-во Ñерверов: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Ваш ник оÑвобожден от ÑƒÐ´ÐµÑ€Ð¶Ð°Ð½Ð¸Ñ ÑервиÑами."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s is a services operator of type %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr ""
@@ -8329,7 +8315,7 @@ msgstr ""
msgid "Services ignore list:"
msgstr " IGNORE Управление игнор-ÑпиÑком ÑервиÑов"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8343,7 +8329,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Текущее кол-во Ñерверов: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
@@ -8353,7 +8339,7 @@ msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
@@ -8363,14 +8349,14 @@ msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s отключен"
msgid "Services will now automatically give modes to users in %s."
msgstr "Режим автоÑтатуÑа Ð´Ð»Ñ %s активирован"
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr ""
"Режим приватных Ñообщений Ð´Ð»Ñ %s активирован, теперь ÑервиÑÑ‹ будут отвечать "
"ему в приват."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr ""
@@ -8391,7 +8377,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "Лимит ÑеÑÑий Ð´Ð»Ñ %s уÑтановлен на %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Ограничение ÑеÑÑий отключено, ÑпиÑок иÑключений не требуетÑÑ."
@@ -8435,7 +8421,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC изменение опиÑÐ°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY уÑтановка главного ника группы"
@@ -8445,14 +8431,14 @@ msgstr " DISPLAY уÑтановка главного ника группы
msgid "Set the founder of a channel"
msgstr " FOUNDER Ñмена владельца канала"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE выбор Ñзыка, поÑредÑтвом которого\n"
" ÑервиÑÑ‹ будут Ñ Ð²Ð°Ð¼Ð¸ общатьÑÑ"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD изменение текущего Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ð° ник"
@@ -8855,7 +8841,7 @@ msgstr ""
"Команда SET позволÑет вам наÑтроить различные опции ника.\n"
"СпиÑок опций:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8873,7 +8859,7 @@ msgstr ""
"иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ региÑтрации по времени. СоответÑтвенно деактивирование\n"
"режима вернет вÑе на круги ÑвоÑ."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8889,7 +8875,7 @@ msgstr ""
"владельцу ника ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¸ входе на канал. СоответÑтвенно OFF -\n"
"Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8901,7 +8887,7 @@ msgstr ""
"по времени. Укажите ON, что бы активировать так называемый режим\n"
"'не-иÑтечениÑ'. Параметр OFF Ñнова возвращает ник в режим иÑтечениÑ."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8915,7 +8901,7 @@ msgstr ""
"Укажите ON, еÑли хотите что бы ÑервиÑÑ‹ автоматичеÑки давали вам\n"
"ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¸ входе на канал. СоответÑтвенно OFF - Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8987,11 +8973,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Режим подпиÑанных киков Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "ПодпиÑанные кики"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr ""
@@ -9003,49 +8989,43 @@ msgstr ""
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Извините, изменение базы данных плохих Ñлов временно невозможно."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Извините, но возможноÑть наÑтройки опций бота временно недоÑтупна."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Извините, изменение наÑтроек ботов временно недоÑтупно."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Извините, но возможноÑть наÑтройки опций бота временно недоÑтупна."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Извините, но возможноÑть наÑтройки опций бота временно недоÑтупна."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr ""
"Извините, но возможноÑть модификации ÑпиÑка AOP'ов временно недоÑтупна."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr ""
"Извините, но возможноÑть модификации ÑпиÑка доÑтупа канала временно "
"недоÑтупна."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr ""
"Извините, но возможноÑть модификации ÑпиÑка автокиков канала временно "
"недоÑтупна."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Извините, изменение базы данных плохих Ñлов временно невозможно."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Извините, возможноÑть удаление каналов временно недоÑтупна."
@@ -9076,7 +9056,7 @@ msgstr "Извините, но возможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½Ð¸ÐºÐ¾Ð
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Извините, но возможноÑть группировки ников временно недоÑтупна."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Извините, но региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¸ÐºÐ¾Ð² временно приоÑтановлена."
@@ -9095,13 +9075,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Извините, но количеÑтво запиÑей в ÑпиÑке доÑтупа не может превышать %d"
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "ПриветÑтвие Ð´Ð»Ñ %s удалено."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -9113,7 +9088,7 @@ msgstr "Извините, в ÑпиÑке доÑтупа канала может
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "СпиÑок автокиков канала может Ñодержать не более %d запиÑей."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Размер базы данных плохих Ñлов не может превышать %d запиÑей."
@@ -9408,7 +9383,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9494,7 +9469,7 @@ msgstr ""
"необходимоÑти. Отключите ее Ñразу, как только переÑтанете нуждатьÑÑ\n"
"в ней."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9517,7 +9492,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"СинтакÑиÑ: INVITE #канал\n"
@@ -9535,7 +9510,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"СинтакÑиÑ: UNBAN #канал [nick]\n"
@@ -9589,7 +9564,7 @@ msgstr " SHUTDOWN Завершить работу ÑервиÑов Ñ Ñо
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9600,7 +9575,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9609,7 +9584,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9626,10 +9601,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9637,14 +9612,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9659,7 +9634,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"СинтакÑиÑ: HOP #канал ADD ник\n"
@@ -9705,36 +9680,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "ВозможноÑть уÑтановки режима IMMED в вашей IRC-Ñети недоÑтупна."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9782,7 +9757,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9793,18 +9768,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9812,7 +9787,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9826,7 +9801,6 @@ msgstr ""
"Ðе волнуйтеÑÑŒ, данный email-Ð°Ð´Ñ€ÐµÑ Ð·Ð½Ð°Ñ‚ÑŒ будете лишь вы и ÐдминиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñети."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9844,7 +9818,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9854,12 +9828,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "ПриветÑтвие Ð´Ð»Ñ %s удалено."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "СпиÑок AKILL'ов полноÑтью очищен."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "СпиÑок AKILL'ов полноÑтью очищен."
@@ -9880,7 +9854,7 @@ msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr ""
"Теперь, email-Ð°Ð´Ñ€ÐµÑ Ð½Ð¸ÐºÐ° %s будет показыватьÑÑ Ð² информации по %s INFO."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9913,11 +9887,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "ПриветÑтвие Ð´Ð»Ñ %s удалено."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9988,12 +9962,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "Лимит Ñообщений Ð´Ð»Ñ %s не может быть изменен."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "ПриветÑтвие Ð´Ð»Ñ %s удалено."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -10008,10 +9977,6 @@ msgstr "Уровень DEFCON теперь равен %d"
msgid "The nick %s is now being changed to %s."
msgstr "Ðик Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s был изменен на %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -10037,12 +10002,12 @@ msgstr ""
"Уровень доÑтупа к ÑервиÑам Ð´Ð»Ñ %s теперь будет показыватьÑÑ Ð² информации по "
"%s INFO."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Управление ÑпиÑком иÑключений из лимита ÑеÑÑий"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -10114,7 +10079,7 @@ msgstr "СпиÑок Ñлучайных новоÑтей пуÑÑ‚."
msgid "There is no such configuration block %s."
msgstr " RELOAD Перезагрузка конфигурационного файла ÑервиÑов"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "СпиÑок опер-новоÑтей пуÑÑ‚."
@@ -10142,7 +10107,7 @@ msgstr "ИÑпользование данного канала запрещен
msgid "This channel may not be used."
msgstr "ИÑпользование данного канала запрещено."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -10178,7 +10143,7 @@ msgstr ""
"Эта команда позволÑет пользователÑм уÑтановить виртуальный хоÑÑ‚\n"
"Ñ Ð¸Ñ… ТЕКУЩЕГО ника на вÑе ники группы."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -10191,7 +10156,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -10226,8 +10191,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10334,7 +10299,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10349,7 +10314,7 @@ msgstr ""
"ПозволÑет загрузить какой-либо дополнительный модуль из директории\n"
"Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñми (modules/). "
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10402,7 +10367,7 @@ msgstr ""
"ПозволÑет загрузить какой-либо дополнительный модуль из директории\n"
"Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñми (modules/). "
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10418,12 +10383,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "Дополнительно: Ñтот ник находитÑÑ Ð² режиме ÑаÑпенда по причине: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "Дополнительно: Ñтот ник находитÑÑ Ð² режиме ÑаÑпенда по причине: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10488,7 +10453,7 @@ msgstr ""
msgid "Topic"
msgstr "Блокировка топика"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Блокировка топика"
@@ -10503,7 +10468,7 @@ msgstr "Режим блокировки топика Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s Ð
msgid "Topic lock option for %s is now on."
msgstr "Режим блокировки топика Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Хранение топика"
@@ -10518,7 +10483,7 @@ msgstr "Режим Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð¿Ð¸ÐºÐ° Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s акÑ
msgid "Topic retention option for %s is now on."
msgstr "Режим Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð¿Ð¸ÐºÐ° Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð° %s активирован."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10526,17 +10491,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Выключи CapsLOCK!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE активирование/деактивирование режима безопаÑноÑти"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE активирование/деактивирование режима безопаÑноÑти"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL активирование/деактивирование режима защиты"
@@ -10575,7 +10541,7 @@ msgstr ""
"Примечание: тем не менее, любой, кто знает ваш ник, имеет возможноÑть\n"
"получить информацию о Ð²Ð°Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñƒ INFO."
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10612,7 +10578,7 @@ msgstr " SECURE активирование/деактивирование
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE активирование/деактивирование режима безопаÑноÑти"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10646,7 +10612,7 @@ msgstr ""
"Примечание: возможноÑть уÑтановки метода защиты IMMED может быть\n"
"отключена в вашей IRC-Ñети."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10680,7 +10646,7 @@ msgstr ""
"Примечание: возможноÑть уÑтановки метода защиты IMMED может быть\n"
"отключена в вашей IRC-Ñети."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10717,7 +10683,7 @@ msgstr ""
"воÑпользуйтеÑÑŒ командой /msg %s HELP SASET опциÑ\n"
"Помните, вы должны указать ник, опции которого вы хотите изменить."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10726,7 +10692,7 @@ msgstr ""
"Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации о какой-либо конкретной опции, Ñм.\n"
"Ñправку по /msg %s HELP опциÑ"
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10742,8 +10708,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Выгрузить модуль"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Ðевозможно выгрузить модуль %s"
@@ -10786,7 +10752,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Цензор подчеркиваний.: %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ SASET-Ð¾Ð¿Ñ†Ð¸Ñ %s."
@@ -10806,7 +10772,7 @@ msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° %s. СпиÑок команд доÑтупен по %s%s HELP"
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "ÐеизвеÑтный режим %c - проигнорирован."
@@ -10834,8 +10800,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"СинтакÑиÑ: DROP #канал\n"
"\n"
@@ -10853,10 +10819,10 @@ msgstr " UNSUSPEND СнÑтие режима ÑаÑпенда Ñ Ð½Ð¸ÐºÐ°"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10906,31 +10872,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s принудительно изменил ваши пользовательÑкие режимы."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS Управление ACCESS-ÑпиÑком привилегий канала"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "Вы были разбанены на канале %s."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "Виртуальный хоÑÑ‚ Ð´Ð»Ñ %s удален."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "Лимит Ñобщений Ð´Ð»Ñ %s уÑтановлен на %d."
@@ -10983,13 +10949,13 @@ msgstr "Виртуальный хоÑÑ‚ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ %s уÑтановÐ
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [#канал] [ÑпиÑок_запиÑей | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -11002,7 +10968,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "Ð’Ñе права на владение каналом %s уÑпешно переданы пользователю %s."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -11040,7 +11006,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -11135,7 +11101,7 @@ msgstr ""
"Параметр ALL выведет общую ÑтатиÑтику в комбинации Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ из\n"
"MEMORY и UPLINK."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -11144,7 +11110,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "Ð’Ñ‹ уже ÑоÑтоите в группе %s."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "Вы уже идентифицированы."
@@ -11210,7 +11176,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -11237,13 +11203,22 @@ msgstr ""
"Ð’Ñ‹ не можете запроÑить информацию о получении, когда поÑылаете Ñообщение "
"Ñебе."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Ð’Ñ‹ не можете закрыть Ñвою ÑеÑÑию!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Совпадающих запиÑей в ÑпиÑке доÑтупа канала %s не обнаружено."
@@ -11253,16 +11228,11 @@ msgstr "Совпадающих запиÑей в ÑпиÑке доÑтупа кÐ
msgid "You can't logout %s, they are a Services Operator."
msgstr "Ðевозможно деидентифицировать %s так как он ÐдминиÑтратор ÑервиÑов."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "ВозможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ email-адреÑа в вашей IRC-Ñети недоÑтупна."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -11273,12 +11243,7 @@ msgstr "Ð’Ñ‹ не можете уÑтановить лимит ÑообщениÐ
msgid "You cannot set your memo limit higher than %d."
msgstr "Ð’Ñ‹ не можете уÑтановить лимит Ñообщений больше чем %d."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "ВозможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ email-адреÑа в вашей IRC-Ñети недоÑтупна."
@@ -11319,12 +11284,12 @@ msgstr "Ðа данный момент у Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ 1 Ñообще
msgid "You currently have no memos."
msgstr "Ðа данный момент у Ð²Ð°Ñ Ð½ÐµÑ‚ Ñообщений."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11360,7 +11325,7 @@ msgstr "You have been invited to %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "Ð”ÐµÐ¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð° уÑпешно."
@@ -11403,32 +11368,27 @@ msgstr ""
"Внимание: вы доÑтигли макÑимально допуÑтимого чиÑла хранимых Ñообщений (%d). "
"Ð’Ñ‹ не Ñможете принимать новые ÑообщениÑ, пока не удалите лишние."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Удаление вирт. хоÑта у вÑех ников указанной группы"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "ВозможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ email-адреÑа в вашей IRC-Ñети недоÑтупна."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "ВозможноÑть ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ email-адреÑа в вашей IRC-Ñети недоÑтупна."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "Ðевозможно деидентифицировать %s так как он ÐдминиÑтратор ÑервиÑов."
@@ -11473,26 +11433,11 @@ msgstr ""
msgid "You must be a channel operator to register the channel."
msgstr "Чтобы зарегиÑтрировать канал, вы должны быть его оператором."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
msgstr "Чтобы зарегиÑтрировать канал, вы должны быть его оператором."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr "Чтобы зарегиÑтрировать канал, вы должны быть его оператором."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr "Чтобы зарегиÑтрировать канал, вы должны быть его оператором."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11500,19 +11445,19 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr ""
"Чтобы начать региÑтрацию вашего текущего ника, вы должны иÑпользовать его не "
"менее %d Ñекунд"
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11527,40 +11472,18 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу при поÑтуплении оных."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу поÑле идентификации к нику или "
-"при поÑтуплении новых Ñообщений."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу поÑле идентификации к нику или "
"при поÑтуплении новых Ñообщений."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу поÑле идентификации к нику или "
-"при поÑтуплении новых Ñообщений."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr ""
"Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу поÑле идентификации к нику"
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Ð’Ñ‹ будете уведомлены о новых ÑообщениÑÑ… Ñразу при поÑтуплении оных."
@@ -11572,7 +11495,7 @@ msgstr "Лимит Ñообщений уÑтановлен на 0, возможÐ
msgid "You will no longer be informed via email."
msgstr "Оповещение о новых ÑообщениÑÑ… поÑредÑтвом email отключено"
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Уведомление о новых ÑообщениÑÑ… отключено."
@@ -11599,23 +11522,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "Бот под ником %s уÑпешно удален."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "Вы уже идентифицированы."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Вы уже идентифицированы."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ %s изменен на %s."
@@ -11625,18 +11548,18 @@ msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ %s изменен на %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "Ð’Ñе OLINE-запиÑи на Ñервере %s были удалены."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "Ð’Ñе OLINE-запиÑи на Ñервере %s были удалены."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ %s изменен на %s."
@@ -11697,7 +11620,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Ðик %s уÑпешно зарегиÑтрирован."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Ваш ник изменен на %s"
@@ -11706,44 +11629,43 @@ msgstr "Ваш ник изменен на %s"
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Ваш код аутенфикации был заново выÑлан на %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr ""
"Пароль Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ ника - %s - запомните его, он пригодитÑÑ Ð²Ð°Ð¼ в дальнейшем!"
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "Бот под ником %s уÑпешно удален."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Ваш виртуальный хоÑÑ‚ %s активирован."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Ваш виртуальный хоÑÑ‚ %s@%s активирован."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -11793,7 +11715,7 @@ msgstr "[Ð¡Ð»ÑƒÑ‡Ð°Ð¹Ð½Ð°Ñ Ð½Ð¾Ð²Ð¾Ñть - %s] %s"
msgid "[account] password"
msgstr "IDENTIFY пароль"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #channel [nick]"
@@ -11851,8 +11773,8 @@ msgstr "INFO ник"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK ник"
@@ -11874,7 +11796,7 @@ msgstr "CHANKILL [+Ñрок_иÑтечениÑ] {#канал} [причин
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11882,24 +11804,24 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr ""
"[авто-Ñообщение] Мемо-Ñообщение, которые вы поÑылали %s, было прочитано."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr ""
"[авто-Ñообщение] Мемо-Ñообщение, которые вы поÑылали %s, было прочитано."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "ПоÑледнее ваше Ñообщение адреÑату %s уÑпешно отменено."
@@ -12004,12 +11926,12 @@ msgstr ""
msgid "seconds"
msgstr "СпиÑок команд %s:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Ваш виртуальный хоÑÑ‚ %s активирован."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "Бот под ником %s уÑпешно удален."
@@ -12045,27 +11967,7 @@ msgstr "UNBAN #канал [nick]"
msgid "{nick | channel}"
msgstr "CANCEL {ник | #канал}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {ник | #канал} текÑÑ‚_ÑообщениÑ"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "ИÑключение Ð´Ð»Ñ %s (#%d) перемещено в позицию %d."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Ð¡Ñ‚Ð°Ñ€Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ боте не отличаетÑÑ Ð¾Ñ‚ новой."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "СинтакÑиÑ: GETEMAIL user@emailhost\n"
-#~ "Выводит ÑпиÑок ников, в наÑтройках у которых Ñтоит указанный email.\n"
-#~ "Примечание: вы не можете иÑпользовать Ñимвольные маÑки ни Ð´Ð»Ñ user,\n"
-#~ "ни Ð´Ð»Ñ emailhost. Каждый раз, при иÑпользовании данной команды,\n"
-#~ "Ñообщение, включающее ник вызвавшего команду и указанный email,\n"
-#~ "будет запиÑано в лог-файл ÑервиÑов."
diff --git a/language/anope.tr_TR.po b/language/anope.tr_TR.po
index f198482c5..2a41b4f34 100644
--- a/language/anope.tr_TR.po
+++ b/language/anope.tr_TR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-27 14:22-0500\n"
+"POT-Creation-Date: 2014-05-30 15:56-0400\n"
"PO-Revision-Date: 2010-09-19 21:13-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Turkish\n"
@@ -27,17 +27,17 @@ msgstr ""
msgid "%d nickname(s) dropped."
msgstr "Nickinizin kaydı silindi (dropped)."
-#: modules/commands/cs_xop.cpp:223
+#: modules/commands/cs_xop.cpp:219
#, fuzzy, c-format
msgid "%s added to %s %s list."
msgstr "%s AKILL listesine eklendi."
-#: modules/commands/cs_access.cpp:225
+#: modules/commands/cs_access.cpp:220
#, c-format
msgid "%s added to %s access list at level %d."
msgstr "%s nicki %s kanalinin access listesine %d seviyeden eklendi."
-#: modules/commands/cs_access.cpp:223
+#: modules/commands/cs_access.cpp:218
#, fuzzy, c-format
msgid "%s added to %s access list at privilege %s (level %d)"
msgstr "%s nicki %s kanalinin access listesine %d seviyeden eklendi."
@@ -47,7 +47,7 @@ msgstr "%s nicki %s kanalinin access listesine %d seviyeden eklendi."
msgid "%s added to %s autokick list."
msgstr "%s nicki %s kanalının akick listesine eklendi."
-#: modules/commands/bs_badwords.cpp:307
+#: modules/commands/bs_badwords.cpp:306
#, c-format
msgid "%s added to %s bad words list."
msgstr "%s %s kanalının küfür listesine eklendi."
@@ -62,17 +62,17 @@ msgstr "%s access listenize eklendi."
msgid "%s added to %s's certificate list."
msgstr "%s access listenize eklendi."
-#: modules/commands/ms_ignore.cpp:62
+#: modules/commands/ms_ignore.cpp:56
#, fuzzy, c-format
msgid "%s added to ignore list."
msgstr "%s access listenize eklendi."
-#: modules/commands/os_sxline.cpp:415 modules/commands/os_sxline.cpp:649
+#: modules/commands/os_sxline.cpp:408 modules/commands/os_sxline.cpp:641
#, fuzzy, c-format
msgid "%s added to the %s list."
msgstr "%s AKILL listesine eklendi."
-#: modules/commands/os_akill.cpp:203
+#: modules/commands/os_akill.cpp:202
#, c-format
msgid "%s added to the AKILL list."
msgstr "%s AKILL listesine eklendi."
@@ -107,7 +107,7 @@ msgstr ""
"daha fazla bilgi için, /msg %s HELP komut\n"
"yazın."
-#: modules/pseudoclients/nickserv.cpp:466
+#: modules/pseudoclients/nickserv.cpp:437
#, fuzzy, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -123,7 +123,7 @@ msgstr ""
"/msg %s komut yazın. Belirli bir komut hakkında daha \n"
"fazla bilgi için, /msg %s HELP komut yazın."
-#: modules/pseudoclients/nickserv.cpp:473
+#: modules/pseudoclients/nickserv.cpp:444
#, fuzzy, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -138,7 +138,7 @@ msgstr ""
"/msg %s komut yazın. Belirli bir komut hakkında daha \n"
"fazla bilgi için, /msg %s HELP komut yazın."
-#: modules/pseudoclients/chanserv.cpp:255
+#: modules/pseudoclients/chanserv.cpp:248
#, fuzzy, c-format
msgid ""
"%s allows you to register and control various\n"
@@ -158,7 +158,7 @@ msgstr ""
"/msg %s HELP komut yazın.\n"
" "
-#: modules/commands/bs_badwords.cpp:298
+#: modules/commands/bs_badwords.cpp:297
#, c-format
msgid "%s already exists in %s bad words list."
msgstr "%s zaten %s kanalının küfür listesinde var."
@@ -179,7 +179,7 @@ msgstr "%s already exists on the EXCEPTION list."
msgid "%s cannot be taken as times to ban."
msgstr "%s değeri kullanılamaz."
-#: modules/commands/os_mode.cpp:163
+#: modules/commands/os_mode.cpp:157
#, fuzzy, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s changed your usermodes."
@@ -189,12 +189,12 @@ msgstr "%s changed your usermodes."
msgid "%s channel list:"
msgstr "Kanal listesi sonu."
-#: modules/commands/cs_xop.cpp:351
+#: modules/commands/cs_xop.cpp:347
#, fuzzy, c-format
msgid "%s deleted from %s %s list."
msgstr "%s %s kanali AOP listesinden silindi."
-#: modules/commands/cs_access.cpp:326
+#: modules/commands/cs_access.cpp:321
#, c-format
msgid "%s deleted from %s access list."
msgstr "%s %s kanalının access listesinden silindi."
@@ -204,7 +204,7 @@ msgstr "%s %s kanalının access listesinden silindi."
msgid "%s deleted from %s autokick list."
msgstr "%s %s kanalının akick listesinden silindi."
-#: modules/commands/bs_badwords.cpp:348
+#: modules/commands/bs_badwords.cpp:347
#, c-format
msgid "%s deleted from %s bad words list."
msgstr "%s %s kanalının küfür listesinden çıkarıldı."
@@ -229,12 +229,12 @@ msgstr "%s session-limit exception listesinden silindi."
msgid "%s deleted from the %s list."
msgstr "%s %s kanali AOP listesinden silindi."
-#: modules/commands/os_akill.cpp:246
+#: modules/commands/os_akill.cpp:245
#, c-format
msgid "%s deleted from the AKILL list."
msgstr "%s AKILL listesinden silindi."
-#: modules/commands/cs_access.cpp:685
+#: modules/commands/cs_access.cpp:678
#, c-format
msgid "%s disabled on channel %s."
msgstr "%s %s kanalında iptal edildi."
@@ -306,7 +306,7 @@ msgstr "You are already in %s! "
msgid "%s is already in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:65
+#: modules/commands/ms_ignore.cpp:59
#, fuzzy, c-format
msgid "%s is already on the ignore list."
msgstr "%s access listenize eklendi."
@@ -316,7 +316,7 @@ msgstr "%s access listenize eklendi."
msgid "%s is already suspended."
msgstr "You are already in %s! "
-#: modules/commands/ms_send.cpp:55 modules/commands/ms_rsend.cpp:56
+#: modules/commands/ms_rsend.cpp:56 modules/commands/ms_send.cpp:46
#, fuzzy, c-format
msgid "%s is not a registered unforbidden nick or channel."
msgstr "%s geçerli bir bot yada kanal değil."
@@ -346,7 +346,7 @@ msgstr "%s %s kanalında iptal edildi."
msgid "%s is not in %s."
msgstr "You are already in %s! "
-#: modules/commands/ms_ignore.cpp:77
+#: modules/commands/ms_ignore.cpp:71
#, fuzzy, c-format
msgid "%s is not on the ignore list."
msgstr "%s not found on ignore list."
@@ -378,12 +378,12 @@ msgstr ""
msgid "%s matches auto kick entry %s on %s (%s)."
msgstr "%s nicki %s kanalının akick listesine eklendi."
-#: modules/commands/cs_xop.cpp:361
+#: modules/commands/cs_xop.cpp:357
#, fuzzy, c-format
msgid "%s not found on %s %s list."
msgstr "%s %s kanali AOP listesinde bulunamadi."
-#: modules/commands/cs_flags.cpp:255 modules/commands/cs_access.cpp:338
+#: modules/commands/cs_access.cpp:333 modules/commands/cs_flags.cpp:254
#, c-format
msgid "%s not found on %s access list."
msgstr "%s %s kanalının access listesinde bulunamadı."
@@ -393,7 +393,7 @@ msgstr "%s %s kanalının access listesinde bulunamadı."
msgid "%s not found on %s autokick list."
msgstr "%s %s kanalının akick listesinde bulunamadı."
-#: modules/commands/bs_badwords.cpp:341
+#: modules/commands/bs_badwords.cpp:340
#, c-format
msgid "%s not found on %s bad words list."
msgstr "%s %s kanalının küfür listesinde bulunamadı."
@@ -430,17 +430,17 @@ msgstr "%s session-limit exception listesinde bulunamadı."
msgid "%s not found on the %s list."
msgstr "%s %s kanali AOP listesinde bulunamadi."
-#: modules/commands/os_akill.cpp:237
+#: modules/commands/os_akill.cpp:236
#, c-format
msgid "%s not found on the AKILL list."
msgstr "%s AKILL listesinde bulunamadı."
-#: modules/commands/cs_flags.cpp:251
+#: modules/commands/cs_flags.cpp:250
#, fuzzy, c-format
msgid "%s removed from the %s access list."
msgstr "%s %s kanalının access listesinden silindi."
-#: modules/commands/ms_ignore.cpp:74
+#: modules/commands/ms_ignore.cpp:68
#, fuzzy, c-format
msgid "%s removed from the ignore list."
msgstr "%s access listenizden silindi."
@@ -472,11 +472,11 @@ msgstr ""
"Belirli bir özellik hakkında daha fazla bilgi için\n"
"/msg %s HELP özellik yazın."
-#: modules/commands/bs_bot.cpp:270
+#: modules/commands/bs_bot.cpp:254
msgid "ADD nick user host real"
msgstr ""
-#: modules/commands/bs_bot.cpp:271
+#: modules/commands/bs_bot.cpp:255
#, fuzzy
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr ""
@@ -484,12 +484,12 @@ msgstr ""
"BOT CHANGE eskinick yeninick [user [host [gerçekismi]]]\n"
"BOT DEL nick"
-#: modules/commands/bs_bot.cpp:272
+#: modules/commands/bs_bot.cpp:256
#, fuzzy
msgid "DEL nick"
msgstr "DEL <nick>."
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:601
#, fuzzy
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
@@ -504,6 +504,9 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
+"EXCEPTION MOVE moves exception num to position. The\n"
+"sessions inbetween will be shifted up or down to fill the gap.\n"
+" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -564,7 +567,7 @@ msgid ""
"restriction."
msgstr ""
-#: modules/commands/cs_access.cpp:611
+#: modules/commands/cs_access.cpp:604
#, c-format
msgid ""
"User access levels can be seen by using the\n"
@@ -582,18 +585,18 @@ msgstr "[auto-memo] The memo you sent to %s has been viewed."
msgid "[target] [password]"
msgstr "GROUP hedef ÅŸifre"
-#: modules/commands/ns_set.cpp:442
+#: modules/commands/ns_set.cpp:435
msgid "address"
msgstr ""
-#: modules/commands/bs_set.cpp:159
+#: modules/commands/bs_set.cpp:150
#, fuzzy
msgid "botname {ON|OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/bs_assign.cpp:91 modules/commands/cs_info.cpp:20
-#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_getkey.cpp:20
-#: modules/commands/cs_log.cpp:106 modules/commands/cs_sync.cpp:20
+#: modules/commands/cs_suspend.cpp:152 modules/commands/cs_sync.cpp:20
+#: modules/commands/bs_assign.cpp:91 modules/commands/cs_log.cpp:106
+#: modules/commands/cs_getkey.cpp:20 modules/commands/cs_info.cpp:20
#: modules/extra/stats/cs_fantasy_top.cpp:39
#: modules/extra/stats/cs_fantasy_top.cpp:51
#, fuzzy
@@ -636,7 +639,7 @@ msgstr "UNBAN kanaladı [name]"
msgid "channel nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_clone.cpp:115
+#: modules/commands/cs_clone.cpp:21
#, fuzzy
msgid "channel target [what]"
msgstr "CLEAR kanaladı neyi"
@@ -646,7 +649,7 @@ msgstr "CLEAR kanaladı neyi"
msgid "channel text"
msgstr "ACT kanaladı yazı"
-#: modules/commands/bs_set.cpp:88
+#: modules/commands/bs_set.cpp:79
#, fuzzy
msgid "channel time"
msgstr "ACT kanaladı yazı"
@@ -661,12 +664,12 @@ msgstr "KICK kanaladı kullanıcı sebep"
msgid "channel what"
msgstr "TOPIC kanaladi [konu]"
-#: modules/commands/cs_xop.cpp:489
+#: modules/commands/cs_xop.cpp:485
#, fuzzy
msgid "channel ADD mask"
msgstr "MODE kanaladı modlar"
-#: modules/commands/cs_access.cpp:499
+#: modules/commands/cs_access.cpp:494
msgid "channel ADD mask level"
msgstr ""
@@ -675,7 +678,7 @@ msgstr ""
msgid "channel ADD message"
msgstr "MODE kanaladı modlar"
-#: modules/commands/bs_badwords.cpp:371
+#: modules/commands/bs_badwords.cpp:370
msgid "channel ADD word [SINGLE | START | END]"
msgstr ""
@@ -684,19 +687,19 @@ msgstr ""
msgid "channel ADD {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_topic.cpp:151
+#: modules/commands/cs_topic.cpp:158
#, fuzzy
msgid "channel APPEND topic"
msgstr "TOPIC kanaladi [konu]"
-#: modules/commands/bs_badwords.cpp:374 modules/commands/cs_xop.cpp:492
-#: modules/commands/cs_entrymsg.cpp:197 modules/commands/cs_flags.cpp:376
-#: modules/commands/cs_akick.cpp:428 modules/commands/cs_access.cpp:503
+#: modules/commands/cs_access.cpp:498 modules/commands/bs_badwords.cpp:373
+#: modules/commands/cs_xop.cpp:488 modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_akick.cpp:428 modules/commands/cs_entrymsg.cpp:197
#, fuzzy
msgid "channel CLEAR"
msgstr "DROP kanaladı"
-#: modules/commands/cs_mode.cpp:679
+#: modules/commands/cs_mode.cpp:681
#, fuzzy
msgid "channel CLEAR [what]"
msgstr "TOPIC kanaladi [konu]"
@@ -711,7 +714,7 @@ msgstr "DROP kanaladı"
msgid "channel DEL num"
msgstr "MODE kanaladı modlar"
-#: modules/commands/cs_xop.cpp:490 modules/commands/cs_access.cpp:500
+#: modules/commands/cs_access.cpp:495 modules/commands/cs_xop.cpp:486
#, fuzzy
msgid "channel DEL {mask | entry-num | list}"
msgstr "DEL [kanaladı] {num | liste | ALL}"
@@ -721,7 +724,7 @@ msgstr "DEL [kanaladı] {num | liste | ALL}"
msgid "channel DEL {nick | mask | entry-num | list}"
msgstr "AOP kanal {ADD|DEL|LIST|CLEAR} [nick | liste-no]"
-#: modules/commands/bs_badwords.cpp:372
+#: modules/commands/bs_badwords.cpp:371
#, fuzzy
msgid "channel DEL {word | entry-num | list}"
msgstr "DEL [kanaladı] {num | liste | ALL}"
@@ -730,7 +733,7 @@ msgstr "DEL [kanaladı] {num | liste | ALL}"
msgid "channel ENFORCE"
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:196 modules/commands/cs_access.cpp:744
+#: modules/commands/cs_access.cpp:737 modules/commands/cs_entrymsg.cpp:196
#, fuzzy
msgid "channel LIST"
msgstr "DROP kanaladı"
@@ -740,41 +743,50 @@ msgstr "DROP kanaladı"
msgid "channel LIST [mask | entry-num | list]"
msgstr "AOP kanal {ADD|DEL|LIST|CLEAR} [nick | liste-no]"
-#: modules/commands/bs_badwords.cpp:373 modules/commands/cs_xop.cpp:491
-#: modules/commands/cs_access.cpp:501
+#: modules/commands/cs_access.cpp:496 modules/commands/bs_badwords.cpp:372
+#: modules/commands/cs_xop.cpp:487
#, fuzzy
msgid "channel LIST [mask | list]"
msgstr "AOP kanal {ADD|DEL|LIST|CLEAR} [nick | liste-no]"
-#: modules/commands/cs_flags.cpp:375
+#: modules/commands/cs_flags.cpp:374
msgid "channel LIST [mask | +flags]"
msgstr ""
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:679
#, fuzzy
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "AOP kanal {ADD|DEL|LIST|CLEAR} [nick | liste-no]"
-#: modules/commands/cs_access.cpp:745
+#: modules/commands/cs_flags.cpp:373
+msgid "channel MODIFY mask changes"
+msgstr ""
+
+#: modules/commands/cs_access.cpp:738
#, fuzzy
msgid "channel RESET"
msgstr "SET kanaladı GREET {ON|OFF}"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:680
#, fuzzy
msgid "channel SET modes"
msgstr "MODE kanaladı modlar"
-#: modules/commands/cs_access.cpp:742
+#: modules/commands/cs_access.cpp:735
msgid "channel SET type level"
msgstr ""
+#: modules/commands/cs_topic.cpp:157
+#, fuzzy
+msgid "channel SET [topic]"
+msgstr "TOPIC kanaladi [konu]"
+
#: modules/commands/cs_akick.cpp:426
#, fuzzy
msgid "channel VIEW [mask | entry-num | list]"
msgstr "AOP kanal {ADD|DEL|LIST|CLEAR} [nick | liste-no]"
-#: modules/commands/cs_access.cpp:502
+#: modules/commands/cs_access.cpp:497
#, fuzzy
msgid "channel VIEW [mask | list]"
msgstr "DEL [kanaladı] {num | liste | ALL}"
@@ -784,7 +796,7 @@ msgstr "DEL [kanaladı] {num | liste | ALL}"
msgid "channel [description]"
msgstr "REGISTER kanaladı açıklama"
-#: modules/commands/cs_unban.cpp:20 modules/commands/cs_invite.cpp:20
+#: modules/commands/cs_invite.cpp:20 modules/commands/cs_unban.cpp:20
#, fuzzy
msgid "channel [nick]"
msgstr "UNBAN kanaladı [name]"
@@ -794,7 +806,7 @@ msgstr "UNBAN kanaladı [name]"
msgid "channel [parameters]"
msgstr "CLEAR kanaladı neyi"
-#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:750
+#: modules/commands/cs_status.cpp:20 modules/commands/cs_mode.cpp:752
#, fuzzy
msgid "channel [user]"
msgstr "UNBAN kanaladı [name]"
@@ -809,23 +821,13 @@ msgstr "BAN #channel nick [reason]"
msgid "channel [+expiry] {nick | mask} [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/cs_flags.cpp:374
-#, fuzzy
-msgid "channel [MODIFY] mask changes"
-msgstr "BAN #channel nick [reason]"
-
-#: modules/commands/cs_topic.cpp:150
-#, fuzzy
-msgid "channel [SET] [topic]"
-msgstr "TOPIC kanaladi [konu]"
-
-#: modules/commands/cs_topic.cpp:152
+#: modules/commands/cs_topic.cpp:159
#, fuzzy
msgid "channel [UNLOCK|LOCK]"
msgstr "DROP kanaladı"
-#: modules/commands/bs_assign.cpp:154 modules/commands/greet.cpp:20
-#: modules/fantasy.cpp:20
+#: modules/fantasy.cpp:20 modules/commands/greet.cpp:20
+#: modules/commands/bs_assign.cpp:154
#, fuzzy
msgid "channel {ON|OFF}"
msgstr "SET kanaladi XOP {ON | OFF}"
@@ -853,7 +855,7 @@ msgstr "KICK kanaladı özellik {ON|OFF} [ayarlar]"
msgid "channel {ON|OFF} [ttb]"
msgstr "SET kanaladi XOP {ON | OFF}"
-#: modules/commands/cs_access.cpp:743
+#: modules/commands/cs_access.cpp:736
msgid "channel {DIS | DISABLE} type"
msgstr ""
@@ -877,27 +879,27 @@ msgstr "SET kanaladi XOP {ON | OFF}"
msgid "email"
msgstr ""
-#: modules/commands/ns_set.cpp:780
+#: modules/commands/ns_set.cpp:773
#, fuzzy
msgid "language"
msgstr "SET LANGUAGE numara"
-#: modules/commands/ms_staff.cpp:25 modules/commands/ms_sendall.cpp:25
+#: modules/commands/ms_sendall.cpp:25 modules/commands/ms_staff.cpp:25
#, fuzzy
msgid "memo-text"
msgstr "STAFF memo-text"
-#: modules/commands/greet.cpp:84 modules/commands/gl_global.cpp:22
+#: modules/commands/gl_global.cpp:22 modules/commands/greet.cpp:84
#, fuzzy
msgid "message"
msgstr "GLOBAL mesaj"
-#: modules/commands/os_modinfo.cpp:20 modules/commands/os_module.cpp:20
-#: modules/commands/os_module.cpp:57 modules/commands/os_module.cpp:129
+#: modules/commands/os_module.cpp:20 modules/commands/os_module.cpp:57
+#: modules/commands/os_module.cpp:129 modules/commands/os_modinfo.cpp:20
msgid "modname"
msgstr ""
-#: modules/commands/ns_set.cpp:327
+#: modules/commands/ns_set.cpp:322
msgid "new-display"
msgstr ""
@@ -907,8 +909,9 @@ msgid "new-password"
msgstr "GROUP hedef ÅŸifre"
#: modules/commands/cs_seen.cpp:258 modules/commands/hs_del.cpp:20
-#: modules/commands/hs_del.cpp:60 modules/commands/hs_request.cpp:193
-#: modules/commands/ms_check.cpp:20 modules/extra/stats/cs_fantasy_stats.cpp:52
+#: modules/commands/hs_del.cpp:60 modules/commands/ms_check.cpp:20
+#: modules/commands/hs_request.cpp:187
+#: modules/extra/stats/cs_fantasy_stats.cpp:52
#, fuzzy
msgid "nick"
msgstr "INFO nick"
@@ -938,18 +941,18 @@ msgstr "SET <nick> <hostmask>."
msgid "nick newnick"
msgstr "SVSNICK nick newnick "
-#: modules/commands/hs_request.cpp:242
+#: modules/commands/hs_request.cpp:236
#, fuzzy
msgid "nick [reason]"
msgstr "BAN #channel nick [reason]"
-#: modules/commands/ns_getpass.cpp:20 modules/commands/ns_suspend.cpp:161
-#: modules/commands/ns_drop.cpp:19
+#: modules/commands/ns_drop.cpp:19 modules/commands/ns_getpass.cpp:20
+#: modules/commands/ns_suspend.cpp:161
#, fuzzy
msgid "nickname"
msgstr "CHECK nickname"
-#: modules/commands/ns_set.cpp:532
+#: modules/commands/ns_set.cpp:525
#, fuzzy
msgid "nickname address"
msgstr "FORBID nick sebep"
@@ -959,7 +962,7 @@ msgstr "FORBID nick sebep"
msgid "nickname email"
msgstr "FORBID nick sebep"
-#: modules/commands/ns_set.cpp:858
+#: modules/commands/ns_set.cpp:848
#, fuzzy
msgid "nickname language"
msgstr "FORBID nick sebep"
@@ -969,12 +972,12 @@ msgstr "FORBID nick sebep"
msgid "nickname message"
msgstr "FORBID nick sebep"
-#: modules/commands/ns_set.cpp:390
+#: modules/commands/ns_set.cpp:385
#, fuzzy
msgid "nickname new-display"
msgstr "FORBID nick sebep"
-#: modules/commands/ns_set.cpp:170
+#: modules/commands/ns_set.cpp:168
#, fuzzy
msgid "nickname new-password"
msgstr "GHOST nick [ÅŸifre]"
@@ -984,7 +987,7 @@ msgstr "GHOST nick [ÅŸifre]"
msgid "nickname [parameter]"
msgstr "GHOST nick [ÅŸifre]"
-#: modules/commands/ns_recover.cpp:150
+#: modules/commands/ns_recover.cpp:130
#, fuzzy
msgid "nickname [password]"
msgstr "GHOST nick [ÅŸifre]"
@@ -999,15 +1002,15 @@ msgstr "FORBID nick sebep"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/commands/ns_set.cpp:299 modules/commands/ns_set.cpp:617
-#: modules/commands/ns_set.cpp:971 modules/commands/ns_set.cpp:1062
-#: modules/commands/ns_set.cpp:1091 modules/commands/ns_list.cpp:252
+#: modules/commands/ns_set.cpp:294 modules/commands/ns_set.cpp:610
+#: modules/commands/ns_set.cpp:961 modules/commands/ns_set.cpp:1052
+#: modules/commands/ns_set.cpp:1081 modules/commands/ns_list.cpp:252
#: modules/extra/stats/m_chanstats.cpp:122
#, fuzzy
msgid "nickname {ON | OFF}"
msgstr "SASET nickname AUTOOP {ON | OFF}"
-#: modules/commands/ns_set.cpp:746
+#: modules/commands/ns_set.cpp:739
#, fuzzy
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "SASET nickname KILL {ON | QUICK | IMMED | OFF}"
@@ -1051,12 +1054,12 @@ msgstr "REGISTER ÅŸifreniz emailiniz"
msgid "password"
msgstr "GROUP hedef ÅŸifre"
-#: modules/commands/ns_register.cpp:110
+#: modules/commands/ns_register.cpp:108
#, fuzzy
msgid "password [email]"
msgstr "REGISTER ÅŸifreniz emailiniz"
-#: modules/commands/ns_register.cpp:108
+#: modules/commands/ns_register.cpp:106
#, fuzzy
msgid "password email"
msgstr "REGISTER ÅŸifreniz emailiniz"
@@ -1076,7 +1079,7 @@ msgstr "LIST model [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "JUPE serverismi [sebep]"
-#: modules/commands/os_mode.cpp:147
+#: modules/commands/os_mode.cpp:141
#, fuzzy
msgid "user modes"
msgstr "MODE kanaladı modlar"
@@ -1086,7 +1089,7 @@ msgstr "MODE kanaladı modlar"
msgid "user [reason]"
msgstr "JUPE serverismi [sebep]"
-#: modules/pseudoclients/nickserv.cpp:496
+#: modules/pseudoclients/nickserv.cpp:467
#, fuzzy, c-format
msgid ""
" \n"
@@ -1103,7 +1106,7 @@ msgstr ""
"amaçlı değildir. %s 'ün kötüye Kullanımı kötüye \n"
"kullanılan kişinin nickini kaybetmesiyle sonuçlanacaktır."
-#: modules/commands/os_sxline.cpp:440
+#: modules/commands/os_sxline.cpp:433
#, fuzzy
msgid ""
" \n"
@@ -1162,7 +1165,7 @@ msgstr ""
"\n"
"Servis operatörlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/os_sxline.cpp:678
+#: modules/commands/os_sxline.cpp:668
#, fuzzy
msgid ""
" \n"
@@ -1218,7 +1221,7 @@ msgstr ""
"\n"
"Servis operatörlerinin Kullanımıyla sınırlıdır."
-#: modules/pseudoclients/nickserv.cpp:492
+#: modules/pseudoclients/nickserv.cpp:463
#, fuzzy, c-format
msgid ""
" \n"
@@ -1333,7 +1336,7 @@ msgid ""
"first registered your nickname."
msgstr ""
-#: modules/pseudoclients/chanserv.cpp:272
+#: modules/pseudoclients/chanserv.cpp:265
#, fuzzy, c-format
msgid ""
" \n"
@@ -1354,7 +1357,7 @@ msgid ""
"other channel users.\n"
msgstr ""
-#: modules/pseudoclients/nickserv.cpp:486
+#: modules/pseudoclients/nickserv.cpp:457
#, fuzzy
msgid ""
" \n"
@@ -1366,7 +1369,7 @@ msgstr ""
"kaydını silebilir(drop) ve herhangi bir nickin access listesini \n"
"görüntüleyebilir. (/msg %s ACCESS LIST nick)."
-#: modules/pseudoclients/chanserv.cpp:277
+#: modules/pseudoclients/chanserv.cpp:270
#, fuzzy
msgid ""
" \n"
@@ -1378,7 +1381,7 @@ msgstr ""
"Servis adminleri kanalın kaydını şifreyle tanıtmadan silebilir,\n"
"ve access, Akick ve seviye ayarlarını görüntüleyebilirler."
-#: modules/commands/bs_set.cpp:144
+#: modules/commands/bs_set.cpp:135
msgid ""
" \n"
"Sets the time bot bans expire in. If enabled, any bans placed by\n"
@@ -1387,7 +1390,17 @@ msgid ""
"automatically expiring."
msgstr ""
-#: modules/commands/cs_xop.cpp:550
+#: modules/commands/cs_xop.cpp:565
+#, c-format
+msgid ""
+" \n"
+"The %s commands are limited to founders\n"
+"(unless SECUREOPS is off). However, any user on the\n"
+"VOP list or above may use the %s LIST command.\n"
+" \n"
+msgstr ""
+
+#: modules/commands/cs_xop.cpp:546
#, fuzzy, c-format
msgid ""
" \n"
@@ -1442,7 +1455,7 @@ msgstr ""
"Access ile xOP arasinda geçis yapabilmek için gerekli bilgilere\n"
"/msg %s HELP SET XOP yazarak ulasabilirsiniz."
-#: modules/commands/cs_akick.cpp:496
+#: modules/commands/cs_akick.cpp:488
#, c-format
msgid ""
" \n"
@@ -1466,7 +1479,7 @@ msgid ""
"akick list."
msgstr ""
-#: modules/commands/os_akill.cpp:448
+#: modules/commands/os_akill.cpp:442
#, fuzzy
msgid ""
" \n"
@@ -1522,7 +1535,7 @@ msgstr ""
"Access ile xOP arasinda geçis yapabilmek için gerekli bilgilere\n"
"/msg %s HELP SET XOP yazarak ulasabilirsiniz."
-#: modules/commands/os_sxline.cpp:462
+#: modules/commands/os_sxline.cpp:455
#, fuzzy
msgid ""
" \n"
@@ -1578,7 +1591,7 @@ msgstr ""
"Access ile xOP arasinda geçis yapabilmek için gerekli bilgilere\n"
"/msg %s HELP SET XOP yazarak ulasabilirsiniz."
-#: modules/commands/os_sxline.cpp:697
+#: modules/commands/os_sxline.cpp:687
#, fuzzy
msgid ""
" \n"
@@ -1638,9 +1651,9 @@ msgstr ""
#, fuzzy
msgid ""
" \n"
-"This option makes a channel unassignable. If a bot\n"
+"This option makes a channel be unassignable. If a bot\n"
"is already assigned to the channel, it is unassigned\n"
-"automatically when you enable it."
+"automatically when you enable the option."
msgstr ""
"Kullanımı: SET kanaladı NOBOT {ON|OFF}\n"
"\n"
@@ -1650,7 +1663,7 @@ msgstr ""
"\n"
"Servis adminlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/bs_set.cpp:196
+#: modules/commands/bs_set.cpp:187
#, fuzzy
msgid ""
" \n"
@@ -1672,7 +1685,7 @@ msgid ""
"above commands."
msgstr ""
-#: modules/commands/os_oper.cpp:168
+#: modules/commands/os_oper.cpp:153
#, c-format
msgid " %s is online using this oper block."
msgstr ""
@@ -1687,7 +1700,7 @@ msgstr ""
msgid " Providing service: %s"
msgstr "Providing command: /msg %s %s"
-#: modules/commands/os_oper.cpp:164
+#: modules/commands/os_oper.cpp:149
msgid " This oper is configured in the configuration file."
msgstr ""
@@ -1701,7 +1714,7 @@ msgstr ""
msgid " but %s mysteriously dematerialized."
msgstr ""
-#: src/messages.cpp:340
+#: src/messages.cpp:335
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1713,7 +1726,7 @@ msgstr ""
msgid "\"Jupiter\" a server"
msgstr " JUPE Bir server'ı \"Kullanılmaz\" yapar"
-#: modules/commands/os_oper.cpp:162
+#: modules/commands/os_oper.cpp:147
#, fuzzy, c-format
msgid "%-8s %s"
msgstr "%-20s %s@%s"
@@ -1732,17 +1745,17 @@ msgstr ""
msgid "%c is an unknown status mode."
msgstr ""
-#: modules/commands/cs_mode.cpp:416
+#: modules/commands/cs_mode.cpp:413
#, fuzzy, c-format
msgid "%c%c is not locked on %s."
msgstr "%s yeni mesajlar için uyarılmayacak."
-#: modules/commands/cs_mode.cpp:412
+#: modules/commands/cs_mode.cpp:409
#, fuzzy, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "Nick %s has been ungrouped from %s."
-#: modules/commands/cs_clone.cpp:56
+#: modules/commands/cs_clone.cpp:140
#, fuzzy, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -1767,8 +1780,8 @@ msgstr "Grupta %d nick var."
msgid "%lu nicks are stored in the database, using %.2Lf kB of memory."
msgstr ""
-#: modules/commands/cs_xop.cpp:245 modules/commands/cs_xop.cpp:380
-#: modules/commands/cs_xop.cpp:458
+#: modules/commands/cs_xop.cpp:241 modules/commands/cs_xop.cpp:376
+#: modules/commands/cs_xop.cpp:454
#, fuzzy, c-format
msgid "%s %s list is empty."
msgstr "%s kanalinin AOP listesi bos."
@@ -1860,9 +1873,9 @@ msgstr ""
msgid "%s (minimum %d/%d%%)"
msgstr " Büyük yazıda atma : %s (minimum %d/%d%%)"
-#: modules/commands/cs_flags.cpp:295 modules/commands/cs_access.cpp:245
-#: modules/commands/cs_access.cpp:349 modules/commands/cs_access.cpp:454
-#: modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:240 modules/commands/cs_access.cpp:344
+#: modules/commands/cs_access.cpp:449 modules/commands/cs_access.cpp:462
+#: modules/commands/cs_flags.cpp:294
#, c-format
msgid "%s access list is empty."
msgstr "%s kanalının access listesi boş."
@@ -1872,7 +1885,7 @@ msgstr "%s kanalının access listesi boş."
msgid "%s added to %s's auto join list."
msgstr "%s nicki %s kanalının akick listesine eklendi."
-#: src/xline.cpp:390
+#: src/xline.cpp:360
#, fuzzy, c-format
msgid "%s already exists."
msgstr "%s nickli bot zaten var."
@@ -1883,7 +1896,7 @@ msgstr "%s nickli bot zaten var."
msgid "%s autokick list is empty."
msgstr "%s kanalının akick listesi boş."
-#: modules/commands/bs_badwords.cpp:198 modules/commands/bs_badwords.cpp:316
+#: modules/commands/bs_badwords.cpp:197 modules/commands/bs_badwords.cpp:315
#, c-format
msgid "%s bad words list is empty."
msgstr "%s kanalının küfür listesi boş."
@@ -1893,8 +1906,8 @@ msgstr "%s kanalının küfür listesi boş."
msgid "%s cannot be the successor on channel %s as they are the founder."
msgstr "%s %s kanalında successor olamaz çünkü zaten o kanalın founderı."
-#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/operserv.cpp:282
-#: modules/pseudoclients/hostserv.cpp:78
+#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/hostserv.cpp:78 modules/pseudoclients/global.cpp:90
#, c-format
msgid "%s commands:"
msgstr "%s commands:"
@@ -1994,7 +2007,7 @@ msgstr " %s şu an bağlı."
msgid "%s is a network service."
msgstr " %s şu an bağlı."
-#: src/xline.cpp:408
+#: src/xline.cpp:378
#, fuzzy, c-format
msgid "%s is already covered by %s."
msgstr "%s zaten %s tarafından değiştirildi."
@@ -2009,7 +2022,7 @@ msgstr "%s access listenize eklendi."
msgid "%s is an unconfirmed nickname."
msgstr "Bu nick zaman aşımına uğramayacak."
-#: modules/commands/cs_flags.cpp:432
+#: modules/commands/cs_flags.cpp:417
#, c-format
msgid ""
"%s is another way to modify the channel access list, similar to\n"
@@ -2033,7 +2046,7 @@ msgstr "%s is disabled"
msgid "%s is enabled"
msgstr "%s is enable"
-#: modules/commands/os_dns.cpp:506
+#: modules/commands/os_dns.cpp:505
#, fuzzy, c-format
msgid "%s is not a valid IP address."
msgstr "%s geçerli bir ban tipi değil."
@@ -2079,7 +2092,7 @@ msgstr ""
msgid "%s is on the channel right now!"
msgstr "%s %s kanalında iptal edildi."
-#: modules/commands/cs_xop.cpp:442
+#: modules/commands/cs_xop.cpp:438
#, fuzzy, c-format
msgid "%s list for %s"
msgstr "%s nickinin access listesi:"
@@ -2089,7 +2102,7 @@ msgstr "%s nickinin access listesi:"
msgid "%s list is empty."
msgstr "%s kanalinin AOP listesi bos."
-#: modules/commands/cs_mode.cpp:361
+#: modules/commands/cs_mode.cpp:358
#, fuzzy, c-format
msgid "%s locked on %s."
msgstr "%s yeni mesajlar için uyarılmayacak."
@@ -2145,7 +2158,7 @@ msgstr ""
"%s sizi yeni mesajlar için bağlandığınızda veya AWAY modundan dönüşte "
"uyaracak."
-#: modules/commands/bs_bot.cpp:89
+#: modules/commands/bs_bot.cpp:82
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) bot listesine eklendi."
@@ -2199,12 +2212,12 @@ msgstr ""
msgid "(by %s on %s) %s"
msgstr ""
-#: modules/commands/cs_access.cpp:710
+#: modules/commands/cs_access.cpp:703
#, fuzzy
msgid "(disabled)"
msgstr "%s is enable"
-#: modules/commands/cs_access.cpp:712
+#: modules/commands/cs_access.cpp:705
msgid "(founder only)"
msgstr ""
@@ -2271,7 +2284,7 @@ msgstr " %s şu an bağlı."
msgid "<unknown>"
msgstr ""
-#: modules/commands/ns_set.cpp:491
+#: modules/commands/ns_set.cpp:484
#, fuzzy, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2284,13 +2297,13 @@ msgstr ""
msgid "A massmemo has been sent to all registered users."
msgstr "A massmemo has been sent to all registered users."
-#: modules/commands/hs_request.cpp:286
+#: modules/commands/hs_request.cpp:280
msgid ""
"A memo informing the user will also be sent, which includes the reason for "
"the rejection if supplied."
msgstr ""
-#: modules/commands/hs_request.cpp:230
+#: modules/commands/hs_request.cpp:224
msgid "A memo informing the user will also be sent."
msgstr ""
@@ -2329,7 +2342,7 @@ msgstr "GROUP hedef ÅŸifre"
msgid "ADD text"
msgstr ""
-#: modules/commands/os_session.cpp:523
+#: modules/commands/os_session.cpp:561
#, fuzzy
msgid "ADD [+expiry] mask limit reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
@@ -2349,12 +2362,12 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "ADD [nickname] [fingerprint]"
msgstr "FORBID nick sebep"
-#: modules/commands/os_akill.cpp:386 modules/commands/os_sxline.cpp:659
+#: modules/commands/os_akill.cpp:380 modules/commands/os_sxline.cpp:651
#, fuzzy
msgid "ADD [+expiry] mask reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
-#: modules/commands/os_sxline.cpp:425
+#: modules/commands/os_sxline.cpp:418
#, fuzzy
msgid "ADD [+expiry] mask:reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
@@ -2364,15 +2377,15 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason"
msgstr "CHANKILL [+expiry] {#channel} [reason]"
-#: modules/commands/os_dns.cpp:664
+#: modules/commands/os_dns.cpp:663
msgid "ADDIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:662
+#: modules/commands/os_dns.cpp:661
msgid "ADDSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:660
+#: modules/commands/os_dns.cpp:659
msgid "ADDZONE zone.name"
msgstr ""
@@ -2386,8 +2399,8 @@ msgstr " %s için AKICK uygulaması tamam; %d kullanıcı için geçerli."
msgid "AKILL all users on a specific channel"
msgstr " CHANKILL AKILL all users on a specific channel"
-#: modules/commands/os_akill.cpp:222 modules/commands/os_akill.cpp:339
-#: modules/commands/os_akill.cpp:353
+#: modules/commands/os_akill.cpp:221 modules/commands/os_akill.cpp:336
+#: modules/commands/os_akill.cpp:350
msgid "AKILL list is empty."
msgstr "AKILL listesi boÅŸ."
@@ -2421,17 +2434,17 @@ msgstr "Level %d ile %d arasında olmalıdır."
msgid "Access level must be non-zero."
msgstr "Access seviyesi sıfırdan farklı bir sayı olmalıdır."
-#: modules/commands/cs_access.cpp:694
+#: modules/commands/cs_access.cpp:687
#, c-format
msgid "Access level settings for channel %s:"
msgstr "%s kanalı için access level ayarları:"
-#: modules/commands/cs_access.cpp:734
+#: modules/commands/cs_access.cpp:727
#, c-format
msgid "Access levels for %s reset to defaults."
msgstr "%s için access levelleri varsayılanlarla değiştirildi."
-#: modules/commands/ns_access.cpp:87 modules/commands/cs_access.cpp:439
+#: modules/commands/cs_access.cpp:434 modules/commands/ns_access.cpp:87
#, fuzzy, c-format
msgid "Access list for %s:"
msgstr "%s nickinin access listesi:"
@@ -2445,24 +2458,16 @@ msgstr ""
"Access to this command requires the permission %s to be present in your "
"opertype."
-#: modules/commands/ns_identify.cpp:94 modules/commands/ns_cert.cpp:368
-#: modules/commands/ns_cert.cpp:392
-#, c-format
-msgid ""
-"Account %s has already reached the maximum number of simultaneous logins "
-"(%u)."
-msgstr ""
-
#: modules/commands/cs_set.cpp:694
#, fuzzy
msgid "Activate security features"
msgstr " SECURE %s güvenlik özelliklerini aktifleştirir"
-#: modules/commands/hs_request.cpp:228
+#: modules/commands/hs_request.cpp:222
msgid "Activate the requested vHost for the given nick."
msgstr ""
-#: modules/commands/hs_on.cpp:55
+#: modules/commands/hs_on.cpp:53
#, fuzzy
msgid ""
"Activates the vhost currently assigned to the nick in use.\n"
@@ -2486,7 +2491,7 @@ msgid ""
"the nick or channel."
msgstr ""
-#: modules/commands/os_dns.cpp:514
+#: modules/commands/os_dns.cpp:513
#, c-format
msgid "Added IP %s to %s."
msgstr ""
@@ -2526,13 +2531,7 @@ msgstr "Uplink server: %s"
msgid "Added zone %s."
msgstr ""
-#: modules/commands/cs_entrymsg.cpp:257
-msgid ""
-"Adding, deleting, or clearing entry messages requires the\n"
-"SET permission."
-msgstr ""
-
-#: modules/commands/ns_register.cpp:90
+#: modules/commands/ns_register.cpp:88
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -2553,7 +2552,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "%s serverındaki tüm O:line lar resetlendi."
-#: modules/commands/cs_clone.cpp:71
+#: modules/commands/cs_clone.cpp:154
#, fuzzy, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -2563,16 +2562,11 @@ msgstr "All vhost's in the group %s have been set to %s"
msgid "All available commands for %s:"
msgstr "%s hakkında yardım bulunamadı."
-#: modules/commands/cs_clone.cpp:96
+#: modules/commands/cs_clone.cpp:178
#, fuzzy, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
-#: modules/commands/cs_clone.cpp:108
-#, fuzzy, c-format
-msgid "All level entries from %s have been cloned into %s."
-msgstr "All vhost's in the group %s have been set to %s"
-
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Tüm bağlantı haberleri silindi."
@@ -2582,12 +2576,12 @@ msgstr "Tüm bağlantı haberleri silindi."
msgid "All memos for channel %s have been deleted."
msgstr "All memos for channel %s have been deleted."
-#: modules/commands/os_mode.cpp:61
+#: modules/commands/os_mode.cpp:55
#, c-format
msgid "All modes cleared on %s."
msgstr ""
-#: modules/commands/ns_register.cpp:368
+#: modules/commands/ns_register.cpp:358
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2610,7 +2604,7 @@ msgstr "%s serverındaki tüm O:line lar silindi."
msgid "All random news items deleted."
msgstr "Tüm karisik haberler silindi."
-#: modules/commands/cs_clone.cpp:210
+#: modules/commands/cs_clone.cpp:105
#, fuzzy, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "All vhost's in the group %s have been set to %s"
@@ -2622,12 +2616,12 @@ msgstr "%s serverındaki tüm O:line lar resetlendi."
#: modules/commands/hs_group.cpp:60
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s."
+msgid "All vhost's in the group %s have been set to %s."
msgstr "All vhost's in the group %s have been set to %s"
#: modules/commands/hs_group.cpp:58
#, fuzzy, c-format
-msgid "All vhosts in the group %s have been set to %s@%s."
+msgid "All vhost's in the group %s have been set to %s@%s."
msgstr "All vhost's in the group %s have been set to %s@%s"
#: src/access.cpp:41
@@ -2761,7 +2755,7 @@ msgstr ""
"IRCopların networkteki tüm kullanıcılara mesaj yollamasını\n"
"sağlar. Mesajlar %s nickinden gönderilir."
-#: modules/commands/os_mode.cpp:133
+#: modules/commands/os_mode.cpp:127
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any channel.\n"
@@ -2777,7 +2771,7 @@ msgstr ""
"\n"
"Servis operatörlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/os_mode.cpp:173
+#: modules/commands/os_mode.cpp:167
#, fuzzy
msgid ""
"Allows Services Operators to change modes for any user.\n"
@@ -2791,7 +2785,7 @@ msgstr ""
"\n"
"Servis operatörlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/bs_bot.cpp:352
+#: modules/commands/bs_bot.cpp:336
#, fuzzy
msgid ""
"Allows Services Operators to create, modify, and delete\n"
@@ -2802,13 +2796,13 @@ msgid ""
"hostname and realname. Since no integrity checks are done\n"
"for these settings, be really careful.\n"
" \n"
-"BOT CHANGE allows you to change the nickname, username, hostname\n"
-"or realname of a bot without deleting it (and\n"
+"BOT CHANGE allows to change the nickname, username, hostname\n"
+"or realname of a bot without actually having to delete it (and\n"
"all the data associated with it).\n"
" \n"
"BOT DEL removes the given bot from the bot list.\n"
" \n"
-"Note: You cannot create a bot with a nick that is\n"
+"Note: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."
msgstr ""
@@ -2873,7 +2867,7 @@ msgstr ""
"\n"
"Ignores will not be enforced on IRC Operators."
-#: modules/commands/os_akill.cpp:420
+#: modules/commands/os_akill.cpp:414
#, fuzzy
msgid ""
"Allows Services Operators to manipulate the AKILL list. If\n"
@@ -2937,7 +2931,7 @@ msgstr ""
"\n"
"Servis operatörlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/os_sxline.cpp:436
+#: modules/commands/os_sxline.cpp:429
msgid ""
"Allows Services Operators to manipulate the SNLINE list. If\n"
"a user with a realname matching an SNLINE mask attempts to\n"
@@ -2945,19 +2939,17 @@ msgid ""
"session."
msgstr ""
-#: modules/commands/os_sxline.cpp:670
+#: modules/commands/os_sxline.cpp:662
msgid ""
"Allows Services Operators to manipulate the SQLINE list. If\n"
"a user with a nick matching an SQLINE mask attempts to\n"
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels. If the mask is a\n"
-"regular expression, the expression will be matched against\n"
-"channels too."
+"prevent the use of matching channels."
msgstr ""
-#: modules/commands/os_session.cpp:551
+#: modules/commands/os_session.cpp:592
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -3006,7 +2998,7 @@ msgstr ""
"\n"
"Servis adminleri tarafından kullanılabilir."
-#: modules/commands/cs_topic.cpp:193
+#: modules/commands/cs_topic.cpp:189
msgid ""
"Allows manipulating the topic of the specified channel.\n"
"The SET command changes the topic of the channel to the given topic\n"
@@ -3014,12 +3006,11 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable by users who do "
-"not have\n"
-"the TOPIC privilege."
+"topic lock is set, the channel topic will be unchangeable except via this "
+"command."
msgstr ""
-#: modules/commands/os_kick.cpp:62
+#: modules/commands/os_kick.cpp:56
#, fuzzy, c-format
msgid ""
"Allows staff to kick a user from any channel.\n"
@@ -3055,7 +3046,7 @@ msgstr ""
"\n"
"Mevcut özellikler:"
-#: modules/commands/os_oper.cpp:251
+#: modules/commands/os_oper.cpp:225
msgid ""
"Allows you to change and view Services Operators.\n"
"Note that operators removed by this command but are still set in\n"
@@ -3073,7 +3064,7 @@ msgid ""
" MODIFY nickserv forcemail no"
msgstr ""
-#: modules/commands/ns_set.cpp:978
+#: modules/commands/ns_set.cpp:968
#, fuzzy
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3086,7 +3077,7 @@ msgstr ""
"the given user. With MSG set, Services will use messages,\n"
"else they'll use notices."
-#: modules/commands/ns_set.cpp:952
+#: modules/commands/ns_set.cpp:942
#, fuzzy, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -3099,7 +3090,7 @@ msgstr ""
"you. With MSG set, Services will use messages, else they'll \n"
"use notices."
-#: modules/commands/ms_ignore.cpp:113
+#: modules/commands/ms_ignore.cpp:107
msgid ""
"Allows you to ignore users by nick or host from memoing\n"
"you or a channel. If someone on the memo ignore list tries\n"
@@ -3178,13 +3169,13 @@ msgstr ""
"alırsınız. Eğer parametre nickse, bot hakkında yaratılma \n"
"zamanı veya bulunduğu kanal sayısı gibi bilgiler alırsınız."
-#: modules/commands/cs_xop.cpp:575
+#: modules/commands/cs_xop.cpp:576
msgid ""
"Alternative methods of modifying channel access lists are\n"
"available. "
msgstr ""
-#: modules/commands/hs_request.cpp:192
+#: modules/commands/hs_request.cpp:186
#, fuzzy
msgid "Approve the requested vHost of a user"
msgstr " DEL Delete the vhost of another user"
@@ -3194,15 +3185,10 @@ msgstr " DEL Delete the vhost of another user"
msgid "As a Services Operator, you may drop any nick."
msgstr "%s is a services operator of type %s."
-#: modules/commands/bs_assign.cpp:19
-#, fuzzy
-msgid "Assigns a bot to a channel"
-msgstr "ASSIGN Kanala bot sokar"
-
#: modules/commands/bs_assign.cpp:78
#, fuzzy
msgid ""
-"Assigns the specified bot to a channel. You\n"
+"Assigns a bot pointed out by nick to a channel. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."
msgstr ""
@@ -3212,16 +3198,21 @@ msgstr ""
"sonra botun ayarlarını ihtiyaçlarınıza uygun şekilde \n"
"yapabilirsiniz."
-#: data/chanserv.example.conf:1200
+#: modules/commands/bs_assign.cpp:19
+#, fuzzy
+msgid "Assigns a bot to a channel"
+msgstr "ASSIGN Kanala bot sokar"
+
+#: data/chanserv.example.conf:1186
#, fuzzy
msgid "Associate a URL with the channel"
msgstr "ASSIGN Kanala bot sokar"
-#: data/nickserv.example.conf:593
+#: data/nickserv.example.conf:584
msgid "Associate a URL with this account"
msgstr ""
-#: data/nickserv.example.conf:592
+#: data/nickserv.example.conf:583
#, fuzzy
msgid "Associate a URL with your account"
msgstr " GREET Nickiniz için bir karşılama mesajı belirler"
@@ -3231,12 +3222,12 @@ msgstr " GREET Nickiniz için bir karşılama mesajı belirler"
msgid "Associate a greet message with your nickname"
msgstr " GREET Nickiniz için bir karşılama mesajı belirler"
-#: data/chanserv.example.conf:1201
+#: data/chanserv.example.conf:1187
#, fuzzy
msgid "Associate an E-mail address with the channel"
msgstr " EMAIL Nickinizle bir email adresini iliÅŸkilendirir"
-#: modules/commands/ns_set.cpp:441
+#: modules/commands/ns_set.cpp:434
#, fuzzy
msgid "Associate an E-mail address with your nickname"
msgstr " EMAIL Nickinizle bir email adresini iliÅŸkilendirir"
@@ -3246,12 +3237,12 @@ msgstr " EMAIL Nickinizle bir email adresini iliÅŸkilendirir"
msgid "Associate oper info with a nick or channel"
msgstr "ASSIGN Kanala bot sokar"
-#: modules/commands/ns_set.cpp:544
+#: modules/commands/ns_set.cpp:537
#, fuzzy
msgid "Associates the given E-mail address with the nickname."
msgstr " EMAIL Nickinizle bir email adresini iliÅŸkilendirir"
-#: modules/commands/ns_set.cpp:519
+#: modules/commands/ns_set.cpp:512
#, fuzzy
msgid ""
"Associates the given E-mail address with your nickname.\n"
@@ -3264,7 +3255,7 @@ msgstr ""
"birisi sizin hakkınızda bilgi almak için INFO komutunu \n"
"kullandığında görünür."
-#: modules/commands/ns_set.cpp:1300
+#: modules/commands/ns_set.cpp:1290
msgid "Auto-op"
msgstr "Auto-op"
@@ -3293,17 +3284,12 @@ msgstr ""
msgid "Automatic voice on join"
msgstr ""
-#: modules/commands/os_oper.cpp:197
+#: modules/commands/os_oper.cpp:171
#, fuzzy, c-format
msgid "Available commands for %s:"
msgstr "%s hakkında yardım bulunamadı."
-#: modules/commands/os_oper.cpp:176
-#, fuzzy
-msgid "Available opertypes:"
-msgstr "%s hakkında yardım bulunamadı."
-
-#: modules/commands/os_oper.cpp:219
+#: modules/commands/os_oper.cpp:193
#, c-format
msgid "Available privileges for %s:"
msgstr ""
@@ -3318,20 +3304,20 @@ msgstr ""
msgid "Bad words kicker"
msgstr " Küfürde atma : %s"
-#: modules/commands/bs_badwords.cpp:252
+#: modules/commands/bs_badwords.cpp:251
#, fuzzy, c-format
msgid "Bad words list for %s:"
msgstr "%s nickinin access listesi:"
-#: modules/commands/bs_badwords.cpp:364
+#: modules/commands/bs_badwords.cpp:363
msgid "Bad words list is now empty."
msgstr "Küfür listesi şimdi boş."
-#: modules/commands/bs_set.cpp:126
+#: modules/commands/bs_set.cpp:117
msgid "Ban expiry may not be longer than 1 day."
msgstr ""
-#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
+#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
#, fuzzy, c-format
msgid "Ban on %s expires in %s."
msgstr "%s nickli bot zaten var."
@@ -3350,7 +3336,7 @@ msgstr "%s kanalının ban tipi #%d olarak değiştirildi."
msgid "Bans a given nick or mask on a channel"
msgstr " BAN Bans a selected nick on a channel"
-#: modules/commands/cs_ban.cpp:228
+#: modules/commands/cs_ban.cpp:214
#, fuzzy
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
@@ -3378,7 +3364,7 @@ msgstr "%s yeni mesajlar için uyarılmayacak."
msgid "Bolds kicker"
msgstr " Kalın yazıda atma : %s"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
#, c-format
msgid "Bot %s already exists."
msgstr "%s nickli bot zaten var."
@@ -3393,12 +3379,12 @@ msgstr "%s nickli bot zaten var."
msgid "Bot %s has been assigned to %s."
msgstr "%s botu %s kanalına sokuldu."
-#: modules/commands/bs_bot.cpp:228
+#: modules/commands/bs_bot.cpp:212
#, fuzzy, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "%s botu %s!%s@%s (%s) olarak deÄŸiÅŸtirildi."
-#: modules/commands/bs_bot.cpp:262
+#: modules/commands/bs_bot.cpp:246
#, c-format
msgid "Bot %s has been deleted."
msgstr "%s botu silindi."
@@ -3428,42 +3414,42 @@ msgstr "Bot %s kanalında opları atmayacak ."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot %s kanalında voiceları atmayacak."
-#: modules/commands/bs_bot.cpp:118
+#: modules/commands/bs_bot.cpp:111
#, fuzzy, c-format
msgid "Bot %s is not changeable."
msgstr "Bot yok modu %s kanalı için AKTİF."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:238
#, fuzzy, c-format
msgid "Bot %s is not deletable."
msgstr "%s botu silindi."
-#: modules/commands/bs_set.cpp:138
+#: modules/commands/bs_set.cpp:129
#, c-format
msgid "Bot bans will automatically expire after %s."
msgstr ""
-#: modules/commands/bs_set.cpp:136
+#: modules/commands/bs_set.cpp:127
#, fuzzy
msgid "Bot bans will no longer automatically expire."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
#, fuzzy, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot Hosts may only contain %d characters."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
#, fuzzy
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot Hosts may only contain valid host characters."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
#, fuzzy, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
#, fuzzy
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot Idents may only contain valid characters."
@@ -3481,12 +3467,12 @@ msgstr "Bot listesi:"
msgid "Bot nick"
msgstr ""
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
#, fuzzy, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot Idents may only contain %d characters."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
#, fuzzy
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot Nicks may only contain valid nick characters."
@@ -3579,8 +3565,8 @@ msgstr "Bot artık text floodda atmayacak."
msgid "Bot won't kick for repeats anymore."
msgstr "Bot artık tekrarda atmayacak."
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/os_session.cpp:552
+#: modules/commands/os_sxline.cpp:199
msgid "By"
msgstr ""
@@ -3618,12 +3604,12 @@ msgstr ""
"Belirtilen kanala yada nicke gönderilen son mesajı iptal eder,\n"
"tabi eğer o mesaj siz komutu kullandığınız sırada okunmamışsa."
-#: modules/commands/cs_clone.cpp:149
+#: modules/commands/cs_clone.cpp:55
#, fuzzy, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Bot %s kanalında oplarıda atacak."
-#: modules/commands/ns_register.cpp:311
+#: modules/commands/ns_register.cpp:301
msgid "Cannot send mail now; please retry a little later."
msgstr "Şu an mail gönderilemiyor; lütfen az sonra tekrar deneyin."
@@ -3718,22 +3704,22 @@ msgstr ""
msgid "Change channel modes"
msgstr "%s changed your usermodes."
-#: modules/commands/ns_set.cpp:891
+#: modules/commands/ns_set.cpp:881
#, fuzzy
msgid "Change the communication method of Services"
msgstr " MSG Change the communication method of Services"
-#: modules/commands/os_mode.cpp:146
+#: modules/commands/os_mode.cpp:140
#, fuzzy
msgid "Change user modes"
msgstr "%s changed your usermodes."
-#: modules/commands/os_mode.cpp:161
+#: modules/commands/os_mode.cpp:155
#, fuzzy, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Changed usermodes of %s."
-#: modules/commands/ns_set.cpp:402
+#: modules/commands/ns_set.cpp:397
#, fuzzy
msgid ""
"Changes the display used to refer to the nickname group in\n"
@@ -3745,7 +3731,7 @@ msgstr ""
"ayarlar. Yeni görünüm grubunuzda bulunan nicklerden biri \n"
"olmalıdır."
-#: modules/commands/ns_set.cpp:378
+#: modules/commands/ns_set.cpp:373
#, fuzzy
msgid ""
"Changes the display used to refer to your nickname group in\n"
@@ -3768,7 +3754,7 @@ msgstr ""
"Kanal founderını değiştirir. Yeni nickin kayıtlı \n"
"olması gereklidir."
-#: modules/commands/ns_set.cpp:870
+#: modules/commands/ns_set.cpp:860
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3783,7 +3769,7 @@ msgstr ""
"numara aşağıdaki listede desteklenen dillerden biri olarak \n"
"belirlenir:"
-#: modules/commands/ns_set.cpp:834
+#: modules/commands/ns_set.cpp:824
#, fuzzy
msgid ""
"Changes the language Services uses when sending messages to\n"
@@ -3798,7 +3784,7 @@ msgstr ""
"numara aşağıdaki listede desteklenen dillerden biri olarak \n"
"belirlenir:"
-#: modules/commands/ns_set.cpp:224
+#: modules/commands/ns_set.cpp:219
#, fuzzy
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
@@ -3807,7 +3793,7 @@ msgstr ""
"Nickinizi tanıtmak için kullandığınız şifreyi\n"
"deÄŸiÅŸtirir."
-#: modules/commands/ns_set.cpp:158
+#: modules/commands/ns_set.cpp:156
#, fuzzy
msgid ""
"Changes the password used to identify you as the nick's\n"
@@ -3836,7 +3822,7 @@ msgstr ""
"için bir successor belirtilmemişse kanalın kaydı silinir(drop).\n"
"Komutta belirtilen nickin kayıtlı olması gereklidir."
-#: modules/commands/ns_alist.cpp:48 modules/commands/ns_ajoin.cpp:100
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Channel"
msgstr "DROP kanaladı"
@@ -3916,12 +3902,12 @@ msgstr "%s kanalı zaman aşımına eklendi."
msgid "Channel %s will not expire."
msgstr "%s kanalı zaman aşımından çıkarıldı."
-#: modules/commands/cs_xop.cpp:483
+#: modules/commands/cs_xop.cpp:479
#, fuzzy, c-format
msgid "Channel %s %s list has been cleared."
msgstr "Kanalin %s AOP listesi temizlendi."
-#: modules/commands/cs_flags.cpp:361 modules/commands/cs_access.cpp:486
+#: modules/commands/cs_access.cpp:481 modules/commands/cs_flags.cpp:360
#, c-format
msgid "Channel %s access list has been cleared."
msgstr "Kanal %s access listesi temizlendi."
@@ -3931,7 +3917,7 @@ msgstr "Kanal %s access listesi temizlendi."
msgid "Channel %s akick list has been cleared."
msgstr "Kanal %s akick listesi temizlendi."
-#: modules/commands/cs_mode.cpp:429
+#: modules/commands/cs_mode.cpp:426
#, fuzzy, c-format
msgid "Channel %s has no mode locks."
msgstr "Channel %s is now released."
@@ -3958,8 +3944,8 @@ msgstr ""
"Channels that %s has access on:\n"
" Num Channel Level Description "
-#: modules/commands/cs_xop.cpp:143 modules/commands/cs_flags.cpp:97
-#: modules/commands/cs_access.cpp:142
+#: modules/commands/cs_access.cpp:141 modules/commands/cs_xop.cpp:142
+#: modules/commands/cs_flags.cpp:99
#, fuzzy
msgid "Channels may not be on access lists."
msgstr "%s %s kanalının access listesinde bulunamadı."
@@ -4025,7 +4011,7 @@ msgstr " CHECK Checks if last memo to a nick was read"
#, fuzzy
msgid ""
"Checks whether the _last_ memo you sent to nick has been read\n"
-"or not. Note that this only works with nicks, not with channels."
+"or not. Note that this does only work with nicks, not with channels."
msgstr ""
"Syntax: CHECK nick\n"
"\n"
@@ -4125,7 +4111,7 @@ msgstr "KICK Atma özelliklerini ayarlar"
msgid "Configures reverses kicker"
msgstr "KICK Atma özelliklerini ayarlar"
-#: modules/commands/bs_set.cpp:87
+#: modules/commands/bs_set.cpp:78
#, fuzzy
msgid "Configures the time bot bans expire in"
msgstr "SET Bot özelliklerini ayarlar"
@@ -4140,7 +4126,7 @@ msgstr "KICK Atma özelliklerini ayarlar"
msgid "Confirm a passcode"
msgstr " CONFIRM Confirm a nickserv auth code"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:678
#, fuzzy
msgid "Control modes and mode locks on a channel"
msgstr " CLEARMODES Bir kanalın modlarını temizler"
@@ -4150,50 +4136,50 @@ msgid ""
"Controls what messages will be sent to users when they join the channel."
msgstr ""
-#: modules/commands/cs_clone.cpp:241
+#: modules/commands/cs_clone.cpp:193
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
-"or LEVELS then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
+"then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
-#: modules/commands/cs_clone.cpp:114
+#: modules/commands/cs_clone.cpp:20
#, fuzzy
msgid "Copy all settings from one channel to another"
msgstr ""
" UNBAN Remove all bans preventing a user from entering a channel"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
#: modules/commands/os_news.cpp:156 modules/commands/bs_info.cpp:58
-#: modules/commands/cs_mode.cpp:434 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:201
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/cs_mode.cpp:431
+#: modules/commands/hs_request.cpp:300
#, fuzzy
msgid "Created"
msgstr " Yaratılış : %s"
-#: modules/commands/os_akill.cpp:358 modules/commands/hs_list.cpp:58
-#: modules/commands/os_news.cpp:156 modules/commands/cs_mode.cpp:434
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_news.cpp:156 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_akill.cpp:355 modules/commands/hs_list.cpp:58
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:431
#, fuzzy
msgid "Creator"
msgstr " Yaratılış : %s"
-#: modules/commands/os_sxline.cpp:180
+#: modules/commands/os_sxline.cpp:178
#, fuzzy, c-format
msgid "Current %s list:"
msgstr "Åžu anki AKILL listesi:"
-#: modules/commands/os_akill.cpp:323
+#: modules/commands/os_akill.cpp:320
#, fuzzy
msgid "Current AKILL list:"
msgstr "Åžu anki AKILL listesi:"
-#: modules/commands/os_session.cpp:493
+#: modules/commands/os_session.cpp:531
msgid "Current Session Limit Exception list:"
msgstr "Åžu anki Session Limit Exception listesi:"
@@ -4247,13 +4233,13 @@ msgstr "FORBID nick sebep"
msgid "DEL [nickname] mask"
msgstr "MODE kanaladı modlar"
-#: modules/commands/os_akill.cpp:387 modules/commands/os_sxline.cpp:426
-#: modules/commands/os_sxline.cpp:660
+#: modules/commands/os_akill.cpp:381 modules/commands/os_sxline.cpp:419
+#: modules/commands/os_sxline.cpp:652
#, fuzzy
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL [kanaladı] {num | liste | ALL}"
-#: modules/commands/os_session.cpp:524
+#: modules/commands/os_session.cpp:562
#, fuzzy
msgid "DEL {mask | entry-num | list}"
msgstr "DEL [kanaladı] {num | liste | ALL}"
@@ -4272,19 +4258,19 @@ msgstr "Kullanımı: OPERNEWS DEL {num | ALL}"
msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry"
msgstr ""
-#: modules/commands/os_dns.cpp:665
+#: modules/commands/os_dns.cpp:664
msgid "DELIP server.name ip"
msgstr ""
-#: modules/commands/os_dns.cpp:663
+#: modules/commands/os_dns.cpp:662
msgid "DELSERVER server.name [zone.name]"
msgstr ""
-#: modules/commands/os_dns.cpp:661
+#: modules/commands/os_dns.cpp:660
msgid "DELZONE zone.name"
msgstr ""
-#: modules/commands/os_dns.cpp:668
+#: modules/commands/os_dns.cpp:667
#, fuzzy
msgid "DEPOOL server.name"
msgstr "NOOP {SET|REVOKE} server"
@@ -4298,7 +4284,7 @@ msgstr ""
msgid "Date/Time"
msgstr ""
-#: modules/commands/hs_off.cpp:49
+#: modules/commands/hs_off.cpp:44
#, fuzzy
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
@@ -4434,17 +4420,22 @@ msgstr ""
msgid "Delete a memo or memos"
msgstr " DEL Mesajları silmenizi sağlar"
+#: modules/commands/hs_del.cpp:59
+#, fuzzy
+msgid "Delete the vhost for all nicks in a group"
+msgstr " DELALL Delete the vhost for all nicks in a group"
+
#: modules/commands/hs_del.cpp:19
#, fuzzy
msgid "Delete the vhost of another user"
msgstr " DEL Delete the vhost of another user"
-#: modules/commands/cs_xop.cpp:310
+#: modules/commands/cs_xop.cpp:306
#, fuzzy, c-format
msgid "Deleted %d entries from %s %s list."
msgstr "Deleted %d entries from %s AOP list."
-#: modules/commands/cs_access.cpp:277
+#: modules/commands/cs_access.cpp:272
#, c-format
msgid "Deleted %d entries from %s access list."
msgstr "Deleted %d entries from %s access list."
@@ -4454,7 +4445,7 @@ msgstr "Deleted %d entries from %s access list."
msgid "Deleted %d entries from %s autokick list."
msgstr "Deleted %d entries from %s autokick list."
-#: modules/commands/bs_badwords.cpp:170
+#: modules/commands/bs_badwords.cpp:169
#, c-format
msgid "Deleted %d entries from %s bad words list."
msgstr "Deleted %d entries from %s bad words list."
@@ -4474,7 +4465,7 @@ msgstr "Deleted %d entries from %s AOP list."
msgid "Deleted %d entries from the AKILL list."
msgstr "AKILL listesinden %d kayıt silindi."
-#: modules/commands/cs_access.cpp:275
+#: modules/commands/cs_access.cpp:270
#, c-format
msgid "Deleted 1 entry from %s access list."
msgstr "%s kanalının access listesinden 1 kayıt silindi."
@@ -4484,7 +4475,7 @@ msgstr "%s kanalının access listesinden 1 kayıt silindi."
msgid "Deleted 1 entry from %s autokick list."
msgstr "%s kanalının akick listesinden 1 kayıt silindi."
-#: modules/commands/bs_badwords.cpp:168
+#: modules/commands/bs_badwords.cpp:167
#, c-format
msgid "Deleted 1 entry from %s bad words list."
msgstr "%s kanalının küfür listesinden 1 kayıt silindi."
@@ -4507,7 +4498,7 @@ msgstr "AKILL listesinden 1 kayıt silindi."
msgid "Deleted info from %s."
msgstr "AKILL listesinden 1 kayıt silindi."
-#: modules/commands/cs_xop.cpp:308
+#: modules/commands/cs_xop.cpp:304
#, fuzzy, c-format
msgid "Deleted one entry from %s %s list."
msgstr "%s kanalinin AOP listesinden 1 kayit silindi."
@@ -4556,11 +4547,6 @@ msgstr ""
"Deletes the vhost assigned to the given nick from the\n"
"database."
-#: modules/commands/hs_del.cpp:59
-#, fuzzy
-msgid "Deletes the vhost for all nicks in a group"
-msgstr " DELALL Delete the vhost for all nicks in a group"
-
#: modules/commands/hs_del.cpp:93
#, fuzzy
msgid ""
@@ -4571,13 +4557,13 @@ msgstr ""
"Deletes the vhost for all nick's in the same group as\n"
"that of the given nick."
-#: modules/commands/os_dns.cpp:652
+#: modules/commands/os_dns.cpp:651
#, c-format
msgid "Depooled %s."
msgstr ""
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
-#: modules/commands/ns_alist.cpp:48 modules/commands/cs_access.cpp:799
+#: modules/commands/cs_access.cpp:784 modules/commands/cs_list.cpp:75
+#: modules/commands/cs_info.cpp:53 modules/commands/ns_alist.cpp:48
#, fuzzy
msgid "Description"
msgstr "%s kanalının açıklaması %s olarak değiştirildi."
@@ -4592,7 +4578,7 @@ msgstr "%s kanalının açıklaması %s olarak değiştirildi."
msgid "Description of %s unset."
msgstr "%s kanalının açıklaması %s olarak değiştirildi."
-#: modules/commands/bs_kick.cpp:1104 modules/commands/bs_info.cpp:91
+#: modules/commands/bs_info.cpp:91 modules/commands/bs_kick.cpp:1104
#, fuzzy
msgid "Disabled"
msgstr "%s is enable"
@@ -4617,7 +4603,7 @@ msgstr ""
"\n"
"Reason may be required on certain networks."
-#: modules/commands/hs_request.cpp:338
+#: modules/commands/hs_request.cpp:332
#, fuzzy, c-format
msgid "Displayed %d records (%d total)."
msgstr "Displayed all records (Count: %d)"
@@ -4737,12 +4723,12 @@ msgid ""
"this nick."
msgstr ""
-#: modules/commands/ns_set.cpp:499
+#: modules/commands/ns_set.cpp:492
#, c-format
msgid "E-mail address for %s changed to %s."
msgstr "E-mail address for %s changed to %s."
-#: modules/commands/ns_set.cpp:505
+#: modules/commands/ns_set.cpp:498
#, c-format
msgid "E-mail address for %s unset."
msgstr "E-mail address for %s unset."
@@ -4770,7 +4756,7 @@ msgstr ""
"to them. (However, no more than %d messages will be\n"
"sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"LOGONNEWS may only be used by Services Operators."
@@ -4792,7 +4778,7 @@ msgstr ""
"be sent to them. (However, no more than %d messages will\n"
"be sent in order to avoid flooding the user. If there are\n"
"more news messages, only the most recent will be sent.)\n"
-"NewsCount can be configured in services.conf.\n"
+"NewsCount can be configured in anope.conf.\n"
"\n"
"OPERNEWS may only be used by Services Operators."
@@ -4820,7 +4806,7 @@ msgstr " E-mail adresi: %s"
#: modules/commands/ns_getemail.cpp:41
#, fuzzy, c-format
-msgid "Email matched: %s (%s) to %s."
+msgid "Email matched: %s to %s."
msgstr "Emails Match %s to %s."
#: modules/fantasy.cpp:19
@@ -4831,11 +4817,11 @@ msgstr ""
msgid "Enable greet messages"
msgstr ""
-#: modules/commands/ns_set.cpp:554
+#: modules/commands/ns_set.cpp:547
msgid "Enable or disable keep modes"
msgstr ""
-#: modules/commands/bs_kick.cpp:1103 modules/commands/bs_info.cpp:90
+#: modules/commands/bs_info.cpp:90 modules/commands/bs_kick.cpp:1103
#, fuzzy
msgid "Enabled"
msgstr "%s is enable"
@@ -4867,14 +4853,14 @@ msgstr ""
"%s tarafından hatırlanır ve birisi kanala girdiğinde bu\n"
"topic geçerli olur."
-#: modules/commands/ns_set.cpp:629
+#: modules/commands/ns_set.cpp:622
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
"and attempt to re-set them the next time they authenticate."
msgstr ""
-#: modules/commands/ns_set.cpp:604
+#: modules/commands/ns_set.cpp:597
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4976,8 +4962,8 @@ msgstr ""
#, fuzzy
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the access list\n"
-"will not be allowed channel operator status."
+"When secure ops is set, users who are not on the userlist\n"
+"will not be allowed chanop status."
msgstr ""
"Kullanımı: %s kanaladı SECUREOPS {ON | OFF}\n"
"\n"
@@ -5020,7 +5006,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel as well.\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."
msgstr ""
@@ -5045,22 +5031,22 @@ msgstr ""
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
-#: modules/commands/os_akill.cpp:331
+#: modules/commands/os_akill.cpp:328
#, fuzzy
msgid "End of AKILL list."
msgstr "Kullanıcı listesi sonu."
-#: modules/commands/cs_access.cpp:444
+#: modules/commands/cs_access.cpp:439
#, fuzzy
msgid "End of access list"
msgstr "access listenin sonu."
-#: modules/commands/cs_flags.cpp:347
+#: modules/commands/cs_flags.cpp:346
#, fuzzy, c-format
msgid "End of access list - %d/%d entries shown."
msgstr "Liste sonu - %d/%d ."
-#: modules/commands/cs_flags.cpp:345
+#: modules/commands/cs_flags.cpp:344
msgid "End of access list."
msgstr "access listenin sonu."
@@ -5069,7 +5055,7 @@ msgstr "access listenin sonu."
msgid "End of autokick list"
msgstr "access listenin sonu."
-#: modules/commands/bs_badwords.cpp:257
+#: modules/commands/bs_badwords.cpp:256
#, fuzzy
msgid "End of bad words list."
msgstr "Kullanıcı listesi sonu."
@@ -5102,7 +5088,7 @@ msgstr "Kullanıcı listesi sonu."
msgid "End of list - %d channels shown."
msgstr "Liste sonu - %d/%d ."
-#: modules/commands/cs_list.cpp:130 modules/commands/ns_list.cpp:131
+#: modules/commands/ns_list.cpp:131 modules/commands/cs_list.cpp:130
#, c-format
msgid "End of list - %d/%d matches shown."
msgstr "Liste sonu - %d/%d ."
@@ -5137,8 +5123,8 @@ msgid ""
"user count drops below the channel limit, if one is set."
msgstr ""
-#: modules/commands/ns_set.cpp:822 modules/commands/ns_set.cpp:842
-#: modules/commands/ns_set.cpp:877 src/language.cpp:44
+#: modules/commands/ns_set.cpp:832 modules/commands/ns_set.cpp:867
+#: src/language.cpp:44
msgid "English"
msgstr "Türkçe"
@@ -5195,44 +5181,49 @@ msgstr ""
msgid ""
"Examples:\n"
" \n"
-" CERT ADD\n"
-" Adds your current fingerprint to the certificate list and\n"
+" CERT ADD <fingerprint>\n"
+" Adds this fingerprint to the certificate list and\n"
" automatically identifies you when you connect to IRC\n"
-" using this fingerprint.\n"
+" using this certificate.\n"
" \n"
" CERT DEL <fingerprint>\n"
-" Removes the fingerprint <fingerprint> from your certificate list.\n"
+" Reverses the previous command.\n"
" \n"
" CERT LIST\n"
" Displays the current certificate list."
msgstr ""
+#: modules/commands/os_session.cpp:454
+#, c-format
+msgid "Exception for %s (#%d) moved to position %d."
+msgstr "%s (#%d) için exception %d pozisyonuyla değiştirildi."
+
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Exception for %s has been updated to %d."
-#: modules/commands/os_akill.cpp:358 modules/commands/os_session.cpp:514
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/ns_group.cpp:315 modules/commands/os_ignore.cpp:266
-#: modules/pseudoclients/chanserv.cpp:463
-#: modules/pseudoclients/nickserv.cpp:564
-#: modules/pseudoclients/nickserv.cpp:569
+#: modules/pseudoclients/nickserv.cpp:535
+#: modules/pseudoclients/nickserv.cpp:540
+#: modules/pseudoclients/chanserv.cpp:460 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:199 modules/commands/os_ignore.cpp:266
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Expires"
msgstr "Expires in: %s"
-#: src/xline.cpp:398
+#: src/xline.cpp:368
#, fuzzy, c-format
msgid "Expiry and reason updated for %s."
msgstr "Exception for %s has been updated to %d."
-#: src/xline.cpp:401
+#: src/xline.cpp:371
#, fuzzy, c-format
msgid "Expiry for %s updated."
msgstr "%s nickinin zaman aşımı süresi değiştirildi."
-#: modules/fantasy.cpp:214
+#: modules/fantasy.cpp:198
msgid "Fantasy"
msgstr "Fantazi"
@@ -5261,16 +5252,16 @@ msgstr "%s access listenizde zaten var."
msgid "Fingerprint %s is already in use."
msgstr "You are already in %s! "
-#: modules/commands/cs_flags.cpp:301
+#: modules/commands/cs_flags.cpp:300
msgid "Flags"
msgstr ""
-#: modules/commands/cs_flags.cpp:286
+#: modules/commands/cs_flags.cpp:285
#, fuzzy, c-format
msgid "Flags for %s on %s set to +%s"
msgstr "%s nickinin access seviyesi %s kanalında %d olarak değiştirildi."
-#: modules/commands/cs_flags.cpp:341
+#: modules/commands/cs_flags.cpp:340
#, fuzzy, c-format
msgid "Flags list for %s"
msgstr "%s nickinin access listesi:"
@@ -5360,7 +5351,7 @@ msgstr "%s kanalının founderı %s olarak değiştirildi."
msgid "GETPASS command unavailable because encryption is in use."
msgstr "GETPASS komutu devre dışı çünkü şifreleme(encryption) devrede."
-#: modules/commands/ns_recover.cpp:84
+#: modules/commands/ns_recover.cpp:77
msgid "Ghost with your nick has been killed."
msgstr "Asılı kalan nickiniz kill lendi."
@@ -5369,14 +5360,14 @@ msgstr "Asılı kalan nickiniz kill lendi."
msgid "Give Operflags to a certain user"
msgstr " OLINE Give Operflags to a certain user"
-#: modules/commands/cs_mode.cpp:848
+#: modules/commands/cs_mode.cpp:850
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:831
+#: modules/commands/cs_mode.cpp:833
#, fuzzy, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr " OWNER Gives you owner status on channel"
@@ -5452,24 +5443,20 @@ msgstr ""
msgid "I've never seen %s on this channel."
msgstr "Lütfen bu kanalda Ctrl+R ile yazılmış yazı kullanmayın!"
-#: modules/commands/os_akill.cpp:360 modules/commands/os_sxline.cpp:203
-msgid "ID"
-msgstr ""
-
#: modules/commands/os_oper.cpp:72
-msgid "INFO [type]"
+msgid "INFO type"
msgstr ""
#: modules/commands/os_dns.cpp:217
msgid "IP"
msgstr ""
-#: modules/commands/os_dns.cpp:499
+#: modules/commands/os_dns.cpp:498
#, fuzzy, c-format
msgid "IP %s already exists for %s."
msgstr "%s nickli bot zaten var."
-#: modules/commands/os_dns.cpp:561
+#: modules/commands/os_dns.cpp:560
#, fuzzy, c-format
msgid "IP %s does not exist for %s."
msgstr "%s nickli bot zaten var."
@@ -5479,8 +5466,8 @@ msgstr "%s nickli bot zaten var."
msgid "Identify yourself with your password"
msgstr " IDENTIFY Şifrenizle nickinizi tanıtır"
-#: modules/pseudoclients/nickserv.cpp:205
-#: modules/pseudoclients/nickserv.cpp:211
+#: modules/pseudoclients/nickserv.cpp:186
+#: modules/pseudoclients/nickserv.cpp:192
#, fuzzy, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Eğer 20 saniye içinde nickinizi değiştirmezseniz, Ben değiştireceğim."
@@ -5493,12 +5480,12 @@ msgstr "Ignore list has been cleared."
msgid "Ignore list is empty."
msgstr "Ignore listesi boÅŸ."
-#: modules/commands/ms_ignore.cpp:94
+#: modules/commands/ms_ignore.cpp:88
#, fuzzy
msgid "Ignore list:"
msgstr "Bot listesi:"
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1280
#, fuzzy
msgid "Immediate protection"
msgstr "Voiceları koruma"
@@ -5554,7 +5541,7 @@ msgid ""
"Invalid passcode has been entered, please check the e-mail again, and retry."
msgstr ""
-#: modules/commands/ns_register.cpp:69 modules/commands/ns_register.cpp:72
+#: modules/commands/ns_register.cpp:67 modules/commands/ns_register.cpp:70
msgid "Invalid passcode."
msgstr ""
@@ -5571,7 +5558,7 @@ msgstr ""
msgid "Invalid threshold value. It must be a valid integer greater than 1."
msgstr "Geçersiz threshold değeri. 1 den büyük geçerli tamsayı olmalıdır."
-#: modules/commands/os_dns.cpp:590
+#: modules/commands/os_dns.cpp:589
msgid "Invalid value for LIMIT. Must be numerical."
msgstr ""
@@ -5591,17 +5578,17 @@ msgstr " Italics kicker : %s"
msgid "Join a group"
msgstr " GROUP Bir gruba dahil eder"
-#: modules/commands/ns_set.cpp:1304 modules/commands/cs_set.cpp:1351
+#: modules/commands/ns_set.cpp:1294 modules/commands/cs_set.cpp:1358
#, fuzzy
msgid "Keep modes"
msgstr "Message mode"
-#: modules/commands/ns_set.cpp:589 modules/commands/cs_set.cpp:374
+#: modules/commands/ns_set.cpp:582 modules/commands/cs_set.cpp:374
#, fuzzy, c-format
msgid "Keep modes for %s is now off."
msgstr "Peace option for %s is now ON."
-#: modules/commands/ns_set.cpp:583 modules/commands/cs_set.cpp:366
+#: modules/commands/ns_set.cpp:576 modules/commands/cs_set.cpp:366
#, fuzzy, c-format
msgid "Keep modes for %s is now on."
msgstr "Peace option for %s is now ON."
@@ -5620,7 +5607,7 @@ msgstr "Key for channel %s is %s."
msgid "Kick a user from a channel"
msgstr " KICK Bir kullanıcıyı kanaldan atar"
-#: modules/commands/cs_kick.cpp:116 modules/commands/cs_ban.cpp:218
+#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr ""
@@ -5630,13 +5617,13 @@ msgstr ""
msgid "Kicks a specified nick from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_kick.cpp:128
+#: modules/commands/cs_kick.cpp:115
#, fuzzy
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
-"and above on the channel. Channel founders can also specify masks."
+"and above on the channel. Channel founders may use masks too."
msgstr ""
"Kullanımı: KICK #kanaladı nick [sebep]\n"
"\n"
@@ -5662,19 +5649,19 @@ msgstr ""
msgid "LIST threshold"
msgstr ""
-#: modules/commands/os_akill.cpp:388 modules/commands/os_sxline.cpp:427
-#: modules/commands/os_sxline.cpp:661
+#: modules/commands/os_akill.cpp:382 modules/commands/os_sxline.cpp:420
+#: modules/commands/os_sxline.cpp:653
#, fuzzy
msgid "LIST [mask | list | id]"
msgstr "LIST [kanaladı] [liste | NEW]"
-#: modules/commands/os_session.cpp:525
+#: modules/commands/os_session.cpp:564
#, fuzzy
msgid "LIST [mask | list]"
msgstr "LIST [kanaladı] [liste | NEW]"
-#: modules/commands/ns_access.cpp:104 modules/commands/ns_cert.cpp:260
-#: modules/commands/ns_ajoin.cpp:233
+#: modules/commands/ns_ajoin.cpp:233 modules/commands/ns_cert.cpp:260
+#: modules/commands/ns_access.cpp:104
#, fuzzy
msgid "LIST [nickname]"
msgstr "CHECK nickname"
@@ -5683,15 +5670,10 @@ msgstr "CHECK nickname"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [yazı|num]"
-#: modules/commands/ns_set.cpp:820
+#: modules/commands/ns_set.cpp:812
msgid "Language changed to English."
msgstr "Dil Türkçe olarak değiştirildi."
-#: modules/commands/ns_set.cpp:822
-#, fuzzy, c-format
-msgid "Language for %s changed to %s."
-msgstr "%s için successor %s olarak değiştirildi."
-
#: modules/commands/ms_cancel.cpp:51
#, c-format
msgid "Last memo to %s has been cancelled."
@@ -5702,7 +5684,7 @@ msgstr "%s nickine gönderilen son mesaj iptal edildi."
msgid "Last quit message"
msgstr " Son çıkış mesajı: %s"
-#: modules/commands/ns_info.cpp:92 modules/commands/cs_access.cpp:472
+#: modules/commands/cs_access.cpp:467 modules/commands/ns_info.cpp:92
#, fuzzy
msgid "Last seen"
msgstr " Son görüldüğü tarih: %s"
@@ -5712,11 +5694,11 @@ msgstr " Son görüldüğü tarih: %s"
msgid "Last seen address"
msgstr " Son görüldüğü adres: %s"
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:259
msgid "Last topic"
msgstr ""
-#: modules/commands/cs_info.cpp:56 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_akick.cpp:380 modules/commands/cs_info.cpp:56
#, fuzzy
msgid "Last used"
msgstr " Son görüldüğü tarih: %s"
@@ -5726,27 +5708,27 @@ msgstr " Son görüldüğü tarih: %s"
msgid "Last usermask"
msgstr " Son görüldüğü tarih: %s"
-#: modules/commands/cs_access.cpp:459 modules/commands/cs_access.cpp:472
-#: modules/commands/cs_access.cpp:697
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/cs_access.cpp:690
msgid "Level"
msgstr ""
-#: modules/commands/cs_access.cpp:660
+#: modules/commands/cs_access.cpp:653
#, c-format
msgid "Level for %s on channel %s changed to %d."
msgstr "%s için level %s kanalında %d olarak değiştirildi."
-#: modules/commands/cs_access.cpp:658
+#: modules/commands/cs_access.cpp:651
#, c-format
msgid "Level for %s on channel %s changed to founder only."
msgstr "Level for %s on channel %s changed to founder only."
-#: modules/commands/cs_access.cpp:643
+#: modules/commands/cs_access.cpp:636
#, c-format
msgid "Level must be between %d and %d inclusive."
msgstr "Level %d ile %d arasında olmalıdır."
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
#: modules/commands/os_dns.cpp:217
msgid "Limit"
msgstr ""
@@ -5762,7 +5744,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr " ALIST List channels you have access on"
-#: modules/commands/cs_mode.cpp:330
+#: modules/commands/cs_mode.cpp:329
#, c-format
msgid "List for mode %c is full."
msgstr ""
@@ -5772,7 +5754,7 @@ msgstr ""
msgid "List loaded modules"
msgstr " MODLIST List loaded modules"
-#: modules/commands/cs_list.cpp:72 modules/commands/ns_list.cpp:123
+#: modules/commands/ns_list.cpp:123 modules/commands/cs_list.cpp:72
#, fuzzy, c-format
msgid "List of entries matching %s:"
msgstr "%s grubundaki nicklerin listesi:"
@@ -6028,18 +6010,18 @@ msgstr " MODLIST List loaded modules"
#: modules/commands/cs_info.cpp:19
#, fuzzy
-msgid "Lists information about the specified registered channel"
+msgid "Lists information about the named registered channel"
msgstr " INFO Lists information about the named registered channel"
#: modules/commands/cs_info.cpp:76
#, fuzzy
msgid ""
-"Lists information about the specified registered channel,\n"
-"including its founder, time of registration, last\n"
-"time used, and description. If the user issuing the\n"
-"command has the appropriate access for it, then the\n"
-"successor, last topic set, settings and expiration\n"
-"time will also be displayed when applicable."
+"Lists information about the named registered channel,\n"
+"including its founder, time of registration, and last\n"
+"time used. If the user issuing the command has the\n"
+"appropriate access for it, then the description, successor,\n"
+"last topic set, settings and expiration time will also\n"
+"be displayed when applicable."
msgstr ""
"Kullanımı: INFO kanaladı\n"
"\n"
@@ -6125,7 +6107,11 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr ""
-#: modules/commands/cs_mode.cpp:716
+#: modules/commands/os_session.cpp:563
+msgid "MOVE num position"
+msgstr ""
+
+#: modules/commands/cs_mode.cpp:718
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -6164,12 +6150,12 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr " AKICK Autokick listesini düzenler"
-#: modules/commands/bs_bot.cpp:269
+#: modules/commands/bs_bot.cpp:253
#, fuzzy
msgid "Maintains network bot list"
msgstr "BOT Networkün bot listesini düzenler"
-#: modules/commands/cs_xop.cpp:530
+#: modules/commands/cs_xop.cpp:526
#, c-format
msgid ""
"Maintains the %s list for a channel. Users who match an access entry\n"
@@ -6177,7 +6163,7 @@ msgid ""
" "
msgstr ""
-#: modules/commands/cs_akick.cpp:481
+#: modules/commands/cs_akick.cpp:473
#, c-format
msgid ""
"Maintains the AutoKick list for a channel. If a user\n"
@@ -6195,7 +6181,7 @@ msgid ""
"All users within that nickgroup will then be akicked.\n"
msgstr ""
-#: modules/commands/cs_access.cpp:568
+#: modules/commands/cs_access.cpp:561
#, c-format
msgid ""
"Maintains the access list for a channel. The access\n"
@@ -6207,7 +6193,7 @@ msgid ""
"of -1."
msgstr ""
-#: modules/commands/bs_badwords.cpp:424
+#: modules/commands/bs_badwords.cpp:423
#, fuzzy, c-format
msgid ""
"Maintains the bad words list for a channel. The bad\n"
@@ -6259,7 +6245,7 @@ msgstr ""
" \n"
"BADWORDS CLEAR komutu tüm küfür listesini temizler."
-#: modules/commands/bs_badwords.cpp:370
+#: modules/commands/bs_badwords.cpp:369
#, fuzzy
msgid "Maintains the bad words list"
msgstr "BADWORDS Küfür listesi oluşturur"
@@ -6274,7 +6260,7 @@ msgstr ""
#, fuzzy
msgid ""
"Makes the bot do the equivalent of a \"/me\" command\n"
-"on the specified channel using the specified text."
+"on the given channel using the given text."
msgstr ""
"Kullanımı: ACT kanaladı yazı\n"
"\n"
@@ -6283,13 +6269,13 @@ msgstr ""
#: modules/commands/bs_control.cpp:19
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel"
+msgid "Makes the bot say the given text on the given channel"
msgstr ""
"SAY Makes the bot say the given text on the given channel"
#: modules/commands/bs_control.cpp:69
#, fuzzy
-msgid "Makes the bot say the specified text on the specified channel."
+msgid "Makes the bot say the given text on the given channel."
msgstr ""
"SAY Makes the bot say the given text on the given channel"
@@ -6323,7 +6309,7 @@ msgstr ""
"girdiğinizde gönderilir, kanaldaki access seviyenize\n"
"bağlıdır."
-#: modules/commands/os_dns.cpp:659
+#: modules/commands/os_dns.cpp:658
#, fuzzy
msgid "Manage DNS zones for this network"
msgstr "E-mail adresini bu networkte silemezsiniz."
@@ -6343,12 +6329,12 @@ msgstr " IGNORE Modify the Services ignore list"
msgid "Manage your auto join list"
msgstr " AKICK Autokick listesini düzenler"
-#: modules/commands/os_sxline.cpp:233
+#: modules/commands/os_sxline.cpp:227
#, fuzzy, c-format
msgid "Manipulate the %s list"
msgstr " AKILL AKILL listesini düzenler"
-#: modules/commands/os_akill.cpp:385
+#: modules/commands/os_akill.cpp:379
#, fuzzy
msgid "Manipulate the AKILL list"
msgstr " AKILL AKILL listesini düzenler"
@@ -6358,20 +6344,20 @@ msgstr " AKILL AKILL listesini düzenler"
msgid "Manipulate the DefCon system"
msgstr " DEFCON Manipulate the DefCon system"
-#: modules/commands/cs_topic.cpp:149
+#: modules/commands/cs_topic.cpp:156
#, fuzzy
msgid "Manipulate the topic of the specified channel"
msgstr " TOPIC Manipulate the topic of the specified channel"
-#: modules/commands/os_list.cpp:147 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/bs_info.cpp:56 modules/commands/os_session.cpp:506
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_flags.cpp:301 modules/commands/ms_ignore.cpp:86
+#: modules/commands/cs_access.cpp:454 modules/commands/cs_access.cpp:467
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_botlist.cpp:27
+#: modules/commands/bs_info.cpp:56 modules/commands/os_list.cpp:147
+#: modules/commands/cs_xop.cpp:381 modules/commands/ms_ignore.cpp:80
+#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_flags.cpp:300
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/bs_botlist.cpp:27 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472 modules/commands/os_ignore.cpp:266
msgid "Mask"
msgstr ""
@@ -6384,8 +6370,8 @@ msgstr "%s access listenizde zaten var."
msgid "Mask must be in the form user@host."
msgstr ""
-#: modules/commands/cs_xop.cpp:166 modules/commands/cs_flags.cpp:120
-#: modules/commands/cs_access.cpp:166
+#: modules/commands/cs_access.cpp:164 modules/commands/cs_xop.cpp:165
+#: modules/commands/cs_flags.cpp:122
#, fuzzy
msgid "Masks and unregistered users may not be on access lists."
msgstr "%s access listenizde zaten var."
@@ -6417,7 +6403,7 @@ msgstr " Mod kilidi: %s"
msgid "Memo %d has been deleted."
msgstr "%d nolu mesaj silindi."
-#: modules/commands/ms_ignore.cpp:82
+#: modules/commands/ms_ignore.cpp:76
#, fuzzy
msgid "Memo ignore list is empty."
msgstr "Ignore listesi boÅŸ."
@@ -6437,7 +6423,7 @@ msgstr "%s nickinin mesaj limiti %d olarak ayarlandı."
msgid "Memo limit for %s set to 0."
msgstr "%s nickinin mesaj limiti 0 olarak ayarlandı."
-#: modules/commands/ms_send.cpp:51 modules/commands/ms_rsend.cpp:63
+#: modules/commands/ms_rsend.cpp:63 modules/commands/ms_send.cpp:44
#, c-format
msgid "Memo sent to %s."
msgstr "%s nickine mesajınız gönderildi."
@@ -6452,7 +6438,7 @@ msgstr " Mod kilidi: %s"
msgid "Message"
msgstr "GLOBAL mesaj"
-#: modules/commands/ns_set.cpp:1298
+#: modules/commands/ns_set.cpp:1288
msgid "Message mode"
msgstr "Message mode"
@@ -6460,26 +6446,26 @@ msgstr "Message mode"
msgid "Method"
msgstr ""
-#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
+#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:402
#, c-format
msgid "Missing parameter for mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Mode"
msgstr ""
-#: modules/commands/cs_mode.cpp:661
+#: modules/commands/cs_mode.cpp:663
#, fuzzy, c-format
msgid "Mode %s is not a status or list mode."
msgstr "%s not found on ignore list."
-#: modules/commands/cs_mode.cpp:1008
+#: modules/commands/cs_mode.cpp:986
#, fuzzy
msgid "Mode lock"
msgstr " Mod kilidi: %s"
-#: modules/commands/cs_mode.cpp:451
+#: modules/commands/cs_mode.cpp:448
#, fuzzy, c-format
msgid "Mode locks for %s:"
msgstr " Mod kilidi: %s"
@@ -6488,11 +6474,6 @@ msgstr " Mod kilidi: %s"
msgid "Modes"
msgstr ""
-#: modules/commands/os_mode.cpp:44
-#, c-format
-msgid "Modes cleared on %s and the channel destroyed."
-msgstr ""
-
#: modules/commands/ns_access.cpp:166
#, fuzzy, c-format
msgid ""
@@ -6545,7 +6526,7 @@ msgstr ""
msgid ""
"Modifies or displays the certificate list for your nick.\n"
"If you connect to IRC and provide a client certificate with a\n"
-"matching fingerprint in the cert list, you will be\n"
+"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to services. Services Operators\n"
"may provide a nick to modify other users' certificate lists.\n"
" \n"
@@ -6556,7 +6537,7 @@ msgstr ""
msgid "Modify the Services ignore list"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/cs_xop.cpp:497
+#: modules/commands/cs_xop.cpp:493
#, fuzzy, c-format
msgid "Modify the list of %s users"
msgstr " AOP AOP listesini düzenler"
@@ -6566,7 +6547,7 @@ msgstr " AOP AOP listesini düzenler"
msgid "Modify the list of authorized addresses"
msgstr " ACCESS İzinli adreslerin listesini düzenler"
-#: modules/commands/cs_flags.cpp:373 modules/commands/cs_access.cpp:498
+#: modules/commands/cs_access.cpp:493 modules/commands/cs_flags.cpp:372
#, fuzzy
msgid "Modify the list of privileged users"
msgstr " ACCESS Ayrıcalıklı kullanıcıları belirler değiştirir"
@@ -6576,7 +6557,7 @@ msgstr " ACCESS Ayrıcalıklı kullanıcıları belirler değiştirir"
msgid "Modify the nickname client certificate list"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/os_session.cpp:522
+#: modules/commands/os_session.cpp:560
#, fuzzy
msgid "Modify the session-limit exception list"
msgstr " EXCEPTION Session-limit exception listesini düzenler"
@@ -6625,14 +6606,14 @@ msgstr "Module: %s Version: %s Author: %s loaded: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module: %s [%s] [%s]"
+#: modules/commands/cs_access.cpp:690 modules/commands/cs_access.cpp:784
#: modules/commands/os_list.cpp:42 modules/commands/os_list.cpp:147
-#: modules/commands/cs_list.cpp:75 modules/commands/cs_access.cpp:697
-#: modules/commands/cs_access.cpp:799 modules/commands/os_config.cpp:66
-#: modules/commands/os_config.cpp:88
+#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
+#: modules/commands/cs_list.cpp:75
msgid "Name"
msgstr ""
-#: modules/commands/os_oper.cpp:154
+#: modules/commands/os_oper.cpp:139
msgid "Name Type"
msgstr ""
@@ -6645,19 +6626,19 @@ msgstr "%s nickinin access listesi:"
msgid "Never"
msgstr ""
-#: modules/commands/hs_list.cpp:58 modules/commands/ns_group.cpp:315
#: modules/commands/bs_botlist.cpp:27 modules/commands/ns_list.cpp:75
-#: modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_group.cpp:315
#, fuzzy
msgid "Nick"
msgstr "INFO nick"
-#: modules/commands/ns_register.cpp:42
+#: modules/commands/ns_register.cpp:41
#, fuzzy, c-format
msgid "Nick %s has been confirmed."
msgstr "%s nickinin kaydı silindi (dropped)."
-#: modules/commands/os_oper.cpp:95
+#: modules/commands/os_oper.cpp:89
#, fuzzy, c-format
msgid "Nick %s is already an operator."
msgstr "%s nicki zaten kayıtlı!"
@@ -6672,7 +6653,6 @@ msgstr "%s nicki zaten kayıtlı!"
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s is an illegal nickname and cannot be used."
-#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6688,7 +6668,7 @@ msgstr "Nick %s is currently in use."
msgid "Nick %s is forbidden."
msgstr "%s nicki zaten serbest."
-#: modules/commands/os_oper.cpp:135
+#: modules/commands/os_oper.cpp:122
#, fuzzy, c-format
msgid "Nick %s is not a Services Operator."
msgstr "%s is a services operator of type %s."
@@ -6713,12 +6693,12 @@ msgstr "Nickname %s registered."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s was truncated to %d characters."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1111
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s will expire."
-#: modules/commands/ns_set.cpp:1115
+#: modules/commands/ns_set.cpp:1105
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s will not expire."
@@ -6783,17 +6763,17 @@ msgstr "%s kanalı zaten kayıtlı!"
msgid "Nickname %s may not be registered."
msgstr "%s kanalı kayıt edilemez."
-#: modules/commands/ns_register.cpp:212
+#: modules/commands/ns_register.cpp:204
#, fuzzy, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "%s nicki sizin adınıza kayıt edildi: %s"
-#: modules/commands/ns_register.cpp:214
+#: modules/commands/ns_register.cpp:206
#, fuzzy, c-format
msgid "Nickname %s registered."
msgstr "Nickname %s registered."
-#: modules/commands/cs_set.cpp:1353
+#: modules/commands/cs_set.cpp:1360
#, fuzzy
msgid "No auto-op"
msgstr "Auto-op"
@@ -6802,7 +6782,7 @@ msgstr "Auto-op"
msgid "No bot"
msgstr "Bot yok"
-#: modules/commands/ns_set.cpp:1302 modules/commands/cs_set.cpp:1349
+#: modules/commands/ns_set.cpp:1292 modules/commands/cs_set.cpp:1356
#, fuzzy
msgid "No expire"
msgstr "zaman aşımı yok"
@@ -6831,13 +6811,13 @@ msgstr "Silebileceğiniz bağlantı haberleri maddesi yok!"
msgid "No matches for %s found."
msgstr "No Emails listed for %s."
-#: modules/commands/cs_xop.cpp:302
+#: modules/commands/cs_xop.cpp:298
#, fuzzy, c-format
msgid "No matching entries on %s %s list."
msgstr "%s kanali AOP listesinde uyusan kayit bulunamadi."
-#: modules/commands/cs_xop.cpp:436 modules/commands/cs_flags.cpp:335
-#: modules/commands/cs_access.cpp:269 modules/commands/cs_access.cpp:433
+#: modules/commands/cs_access.cpp:264 modules/commands/cs_access.cpp:428
+#: modules/commands/cs_xop.cpp:432 modules/commands/cs_flags.cpp:334
#, c-format
msgid "No matching entries on %s access list."
msgstr "Uyuşan kayıt %s kanalının access listesinde yok."
@@ -6847,21 +6827,21 @@ msgstr "Uyuşan kayıt %s kanalının access listesinde yok."
msgid "No matching entries on %s autokick list."
msgstr "Uyuşan kayıt %s kanalının akick listesinde bulunamadı."
-#: modules/commands/bs_badwords.cpp:166 modules/commands/bs_badwords.cpp:246
+#: modules/commands/bs_badwords.cpp:165 modules/commands/bs_badwords.cpp:245
#, c-format
msgid "No matching entries on %s bad words list."
msgstr "Uyuşan kayıt %s kanalının küfür listesinde bulunamadı."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
msgid "No matching entries on session-limit exception list."
msgstr "session-limit exception listesinde uyuşan kayıt bulunamadı."
-#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:177
+#: modules/commands/os_sxline.cpp:28 modules/commands/os_sxline.cpp:175
#, fuzzy, c-format
msgid "No matching entries on the %s list."
msgstr "%s kanali AOP listesinde uyusan kayit bulunamadi."
-#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:320
+#: modules/commands/os_akill.cpp:29 modules/commands/os_akill.cpp:317
msgid "No matching entries on the AKILL list."
msgstr "Uyuşan kayıt AKILL listesinde bulunamadı."
@@ -6874,7 +6854,12 @@ msgstr "İptal edilecek mesaj yoktu."
msgid "No modules currently loaded matching that criteria."
msgstr "No modules currently loaded"
-#: modules/commands/ns_recover.cpp:55
+#: modules/commands/ns_getemail.cpp:47
+#, fuzzy, c-format
+msgid "No nick registrations matching %s found."
+msgstr "* No new nick registrations"
+
+#: modules/commands/ns_recover.cpp:48
msgid "No one is using your nick, and services are not holding it."
msgstr ""
@@ -6894,12 +6879,7 @@ msgstr "Silinecek karisik haber yok!"
msgid "No records to display."
msgstr ""
-#: modules/commands/ns_getemail.cpp:47
-#, fuzzy, c-format
-msgid "No registrations matching %s were found."
-msgstr "* No new nick registrations"
-
-#: modules/commands/hs_request.cpp:221 modules/commands/hs_request.cpp:277
+#: modules/commands/hs_request.cpp:215 modules/commands/hs_request.cpp:271
#, c-format
msgid "No request for nick %s found."
msgstr ""
@@ -6908,8 +6888,8 @@ msgstr ""
msgid "No signed kick when SIGNKICK LEVEL is used"
msgstr ""
-#: modules/extra/stats/cs_fantasy_stats.cpp:156
#: modules/extra/stats/cs_fantasy_top.cpp:159
+#: modules/extra/stats/cs_fantasy_stats.cpp:156
#, fuzzy, c-format
msgid "No stats for %s."
msgstr "%s nickinin access listesi:"
@@ -6919,7 +6899,7 @@ msgstr "%s nickinin access listesi:"
msgid "No such info \"%s\" on %s."
msgstr "%s has been invited to %s."
-#: modules/commands/cs_kick.cpp:118 modules/commands/cs_ban.cpp:220
+#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
#, fuzzy, c-format
msgid "No users on %s match %s."
msgstr "Changed usermodes of %s."
@@ -6934,7 +6914,7 @@ msgstr "Bot yok modu %s kanalı için AKTİF."
msgid "No-bot mode is now on on channel %s."
msgstr "Bot yok modu %s kanalı için AKTİF."
-#: modules/commands/os_mode.cpp:64
+#: modules/commands/os_mode.cpp:58
#, c-format
msgid "Non-status modes cleared on %s."
msgstr ""
@@ -6943,21 +6923,21 @@ msgstr ""
msgid "None"
msgstr "YOK"
-#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
+#: modules/commands/cs_mode.cpp:362 modules/commands/cs_mode.cpp:419
msgid "Nothing to do."
msgstr ""
-#: modules/commands/bs_badwords.cpp:194 modules/commands/cs_xop.cpp:385
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:358
-#: modules/commands/hs_list.cpp:58 modules/commands/os_news.cpp:156
-#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
-#: modules/commands/cs_entrymsg.cpp:116 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:201 modules/commands/ns_alist.cpp:48
-#: modules/commands/cs_flags.cpp:301 modules/commands/ns_ajoin.cpp:100
-#: modules/commands/cs_log.cpp:127 modules/commands/cs_akick.cpp:367
-#: modules/commands/cs_akick.cpp:380 modules/commands/ms_list.cpp:64
-#: modules/commands/hs_request.cpp:306 modules/commands/cs_access.cpp:459
-#: modules/commands/cs_access.cpp:472
+#: modules/commands/os_news.cpp:156 modules/commands/cs_access.cpp:454
+#: modules/commands/cs_access.cpp:467 modules/commands/bs_badwords.cpp:193
+#: modules/commands/cs_xop.cpp:381 modules/commands/os_session.cpp:544
+#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_akill.cpp:355 modules/commands/os_sxline.cpp:191
+#: modules/commands/os_sxline.cpp:199 modules/commands/cs_log.cpp:127
+#: modules/commands/ns_ajoin.cpp:100 modules/commands/hs_list.cpp:58
+#: modules/commands/cs_flags.cpp:300 modules/commands/ms_list.cpp:64
+#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
+#: modules/commands/cs_entrymsg.cpp:116 modules/commands/hs_request.cpp:300
+#: modules/commands/ns_alist.cpp:48
msgid "Number"
msgstr ""
@@ -6965,18 +6945,15 @@ msgstr ""
msgid "OPERNEWS {ADD|DEL|LIST} [text|num]"
msgstr "OPERNEWS {ADD|DEL|LIST} [yazı|num]"
+#: modules/commands/bs_bot.cpp:142
+msgid "Old info is equal to the new one."
+msgstr "Eski bilgiler şimdikilerle aynı."
+
#: modules/commands/ns_info.cpp:68 modules/commands/ns_info.cpp:72
#, fuzzy
msgid "Online from"
msgstr " Bağlandığı adres: %s"
-#: modules/commands/os_oper.cpp:139
-#, c-format
-msgid ""
-"Oper %s is configured in the configuration file(s) and can not be removed by "
-"this command."
-msgstr ""
-
#: modules/commands/os_info.cpp:268
msgid "Oper Info"
msgstr ""
@@ -7000,12 +6977,12 @@ msgstr "Operatör haberleri maddesi #%d bulunamadı!"
msgid "Oper news items:"
msgstr "Operatör haberleri:"
-#: modules/commands/os_oper.cpp:149
+#: modules/commands/os_oper.cpp:134
#, c-format
msgid "Oper privileges removed from %s (%s)."
msgstr ""
-#: modules/commands/os_oper.cpp:101 modules/commands/os_oper.cpp:190
+#: modules/commands/os_oper.cpp:95 modules/commands/os_oper.cpp:164
#, fuzzy, c-format
msgid "Oper type %s has not been configured."
msgstr "%s nickinin kaydı silindi (dropped)."
@@ -7020,17 +6997,17 @@ msgstr "An O:Line with the flags %s has been added for %s."
msgid "Operflags %s have been removed from %s."
msgstr "An O:Line with the flags %s has been added for %s."
-#: modules/commands/os_oper.cpp:194
+#: modules/commands/os_oper.cpp:168
#, c-format
msgid "Opertype %s has no allowed commands."
msgstr ""
-#: modules/commands/os_oper.cpp:216
+#: modules/commands/os_oper.cpp:190
#, c-format
msgid "Opertype %s has no allowed privileges."
msgstr ""
-#: modules/commands/os_oper.cpp:238
+#: modules/commands/os_oper.cpp:212
#, c-format
msgid "Opertype %s receives modes %s once identified."
msgstr ""
@@ -7044,12 +7021,12 @@ msgstr "Opları koruma"
msgid "Options"
msgstr " Ayarlar : %s"
-#: modules/commands/os_dns.cpp:667
+#: modules/commands/os_dns.cpp:666
#, fuzzy
msgid "POOL server.name"
msgstr "NOOP {SET|REVOKE} server"
-#: modules/commands/cs_mode.cpp:434
+#: modules/commands/cs_mode.cpp:431
msgid "Param"
msgstr ""
@@ -7066,12 +7043,12 @@ msgstr "Şifre geçersiz."
msgid "Password authentication required for that command."
msgstr ""
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
+#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
#, fuzzy, c-format
msgid "Password for %s changed to %s."
msgstr "%s için successor %s olarak değiştirildi."
-#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
#, fuzzy, c-format
msgid "Password for %s changed."
msgstr "%s nickinin şifresi gönderildi."
@@ -7091,7 +7068,7 @@ msgstr "Şifre geçersiz."
msgid "Password reset email for %s has been sent."
msgstr "Password reset email for %s has been sent."
-#: modules/commands/cs_set.cpp:1335
+#: modules/commands/cs_set.cpp:1342
msgid "Peace"
msgstr "Baris"
@@ -7105,7 +7082,7 @@ msgstr "Peace option for %s is now ON."
msgid "Peace option for %s is now on."
msgstr "Peace option for %s is now ON."
-#: modules/commands/cs_set.cpp:1347
+#: modules/commands/cs_set.cpp:1354
#, fuzzy
msgid "Persistent"
msgstr "Persistant"
@@ -7136,12 +7113,12 @@ msgstr ""
msgid "Please wait %d seconds and retry."
msgstr "Lütfen %d saniye bekleyin ve tekrar deneyin."
-#: modules/commands/hs_request.cpp:159
+#: modules/commands/hs_request.cpp:153
#, fuzzy, c-format
msgid "Please wait %d seconds before requesting a new vHost."
msgstr "Lütfen %d saniye SEND komutunu tekrar kullanmak için bekleyin."
-#: modules/commands/ms_send.cpp:57 modules/commands/ms_rsend.cpp:58
+#: modules/commands/ms_rsend.cpp:58 modules/commands/ms_send.cpp:48
#, fuzzy, c-format
msgid "Please wait %d seconds before using the %s command again."
msgstr "Lütfen %d saniye SEND komutunu tekrar kullanmak için bekleyin."
@@ -7151,12 +7128,12 @@ msgstr "Lütfen %d saniye SEND komutunu tekrar kullanmak için bekleyin."
msgid "Please wait %d seconds before using the GROUP command again."
msgstr "GROUP komutunu tekrar kullanmadan önce lütfen %d saniye bekleyin."
-#: modules/commands/ns_register.cpp:184
+#: modules/commands/ns_register.cpp:174
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr "Lütfen %d saniye REGISTER komutunu tekrar kullanmak için bekleyin."
-#: modules/commands/os_dns.cpp:627
+#: modules/commands/os_dns.cpp:626
#, c-format
msgid "Pooled %s."
msgstr ""
@@ -7169,7 +7146,7 @@ msgstr ""
msgid "Pooled/Not Active"
msgstr ""
-#: modules/commands/bs_set.cpp:158
+#: modules/commands/bs_set.cpp:149
msgid "Prevent a bot from being assigned by non IRC operators"
msgstr ""
@@ -7199,7 +7176,7 @@ msgstr ""
" PRIVATE Prevent the nickname from appearing in a\n"
" /msg %s LIST"
-#: modules/commands/ns_set.cpp:1090
+#: modules/commands/ns_set.cpp:1080
#, fuzzy
msgid "Prevent the nickname from expiring"
msgstr " NOEXPIRE Prevent the nickname from expiring"
@@ -7208,17 +7185,17 @@ msgstr " NOEXPIRE Prevent the nickname from expiring"
msgid "Prevents users being kicked by Services"
msgstr ""
-#: modules/commands/cs_list.cpp:262 modules/commands/bs_info.cpp:59
-#: modules/commands/ns_list.cpp:297
+#: modules/commands/bs_info.cpp:59 modules/commands/ns_list.cpp:297
+#: modules/commands/cs_list.cpp:262
msgid "Private"
msgstr "Özel"
-#: modules/commands/bs_set.cpp:187
+#: modules/commands/bs_set.cpp:178
#, fuzzy, c-format
msgid "Private mode of bot %s is now off."
msgstr "%s botunun özel seçenegi artik AKTIF."
-#: modules/commands/bs_set.cpp:182
+#: modules/commands/bs_set.cpp:173
#, fuzzy, c-format
msgid "Private mode of bot %s is now on."
msgstr "%s botunun özel seçenegi artik AKTIF."
@@ -7243,36 +7220,36 @@ msgstr "Private option is now ON for %s."
msgid "Private option is now on for %s."
msgstr "Private option is now ON for %s."
-#: modules/commands/cs_flags.cpp:281
+#: modules/commands/cs_flags.cpp:280
#, c-format
msgid "Privilege %s added to %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/cs_flags.cpp:283
+#: modules/commands/cs_flags.cpp:282
#, c-format
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr ""
-#: modules/commands/ns_set.cpp:1294
+#: modules/commands/ns_set.cpp:1284
msgid "Protection"
msgstr "Kill koruması"
-#: modules/commands/ns_set.cpp:707
+#: modules/commands/ns_set.cpp:700
#, fuzzy, c-format
msgid "Protection is now off for %s."
msgstr "Protection is now ON for %s."
-#: modules/commands/ns_set.cpp:686
+#: modules/commands/ns_set.cpp:679
#, fuzzy, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Protection is now ON for %s, with a reduced delay."
-#: modules/commands/ns_set.cpp:696
+#: modules/commands/ns_set.cpp:689
#, fuzzy, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Protection is now ON for %s, with no delay."
-#: modules/commands/ns_set.cpp:678
+#: modules/commands/ns_set.cpp:671
#, fuzzy, c-format
msgid "Protection is now on for %s."
msgstr "Protection is now ON for %s."
@@ -7289,7 +7266,7 @@ msgstr ""
"uses the entire and complete real ident@host for every nick,\n"
"then enforces the AKILL. "
-#: modules/commands/ns_set.cpp:1292
+#: modules/commands/ns_set.cpp:1282
#, fuzzy
msgid "Quick protection"
msgstr "Voiceları koruma"
@@ -7335,20 +7312,20 @@ msgstr " READ Mesajları okumanızı sağlar"
msgid "Real name"
msgstr " Gerçek ismi : %s"
-#: modules/commands/os_akill.cpp:344 modules/commands/os_akill.cpp:361
-#: modules/commands/os_session.cpp:514 modules/commands/os_sxline.cpp:193
-#: modules/commands/os_sxline.cpp:204 modules/commands/os_forbid.cpp:346
-#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_ignore.cpp:266
+#: modules/commands/os_forbid.cpp:346 modules/commands/os_session.cpp:552
+#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
+#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
+#: modules/commands/os_ignore.cpp:266 modules/commands/cs_akick.cpp:367
+#: modules/commands/cs_akick.cpp:380
msgid "Reason"
msgstr ""
-#: src/xline.cpp:387
+#: src/xline.cpp:357
#, fuzzy, c-format
msgid "Reason for %s updated."
msgstr "%s için successor kaldırıldı."
-#: modules/commands/ns_recover.cpp:211
+#: modules/commands/ns_recover.cpp:191
msgid ""
"Recovers your nick from another user or from services.\n"
"If services are currently holding your nick, the hold\n"
@@ -7358,35 +7335,35 @@ msgid ""
"forced off of the nick."
msgstr ""
-#: modules/commands/cs_access.cpp:741
+#: modules/commands/cs_access.cpp:734
#, fuzzy
msgid "Redefine the meanings of access levels"
msgstr " LEVELS Access seviyelerini isteğinize göre düzenler"
-#: modules/commands/ns_recover.cpp:149
+#: modules/commands/ns_recover.cpp:129
#, fuzzy
msgid "Regains control of your nick"
msgstr ""
" RELEASE RECOVER komutundan sonra nickinizi serbest \n"
" bırakır"
-#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:330
-#: modules/commands/os_sxline.cpp:545
+#: modules/commands/os_akill.cpp:129 modules/commands/os_sxline.cpp:324
+#: modules/commands/os_sxline.cpp:538
#, fuzzy
msgid "Regex is disabled."
msgstr "%s is enable"
-#: modules/commands/os_akill.cpp:444 modules/commands/os_sxline.cpp:459
-#: modules/commands/os_sxline.cpp:694
+#: modules/commands/os_akill.cpp:438 modules/commands/os_sxline.cpp:452
+#: modules/commands/os_sxline.cpp:684
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
"Enclose your mask in // if this is desired."
msgstr ""
-#: modules/commands/os_list.cpp:114 modules/commands/os_list.cpp:225
-#: modules/commands/cs_list.cpp:167 modules/commands/os_forbid.cpp:416
-#: modules/commands/ns_list.cpp:172 modules/commands/os_ignore.cpp:386
+#: modules/commands/os_forbid.cpp:416 modules/commands/os_list.cpp:114
+#: modules/commands/os_list.cpp:225 modules/commands/ns_list.cpp:172
+#: modules/commands/cs_list.cpp:167 modules/commands/os_ignore.cpp:386
#, c-format
msgid ""
"Regex matches are also supported using the %s engine.\n"
@@ -7398,12 +7375,12 @@ msgstr ""
msgid "Register a channel"
msgstr " REGISTER Nickinizi kaydeder"
-#: modules/commands/ns_register.cpp:106
+#: modules/commands/ns_register.cpp:104
#, fuzzy
msgid "Register a nickname"
msgstr " REGISTER Nickinizi kaydeder"
-#: modules/commands/ns_info.cpp:89 modules/commands/cs_info.cpp:55
+#: modules/commands/cs_info.cpp:55 modules/commands/ns_info.cpp:89
#, fuzzy
msgid "Registered"
msgstr " Kayıt zamanı: %s"
@@ -7462,7 +7439,7 @@ msgstr ""
"first registered your nickname. If you haven't,\n"
"/msg %s HELP for information on how to do so."
-#: modules/commands/ns_register.cpp:248
+#: modules/commands/ns_register.cpp:238
#, fuzzy, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7518,7 +7495,7 @@ msgstr ""
"sağlar. Bu özellik hakkında daha fazla bilgi için, \n"
"/msg %s HELP GROUP yazın."
-#: modules/commands/ns_register.cpp:131
+#: modules/commands/ns_register.cpp:129
#, fuzzy
msgid "Registration is currently disabled."
msgstr "Kanal kaydı geçici olarak devre dışıdır."
@@ -7528,12 +7505,12 @@ msgstr "Kanal kaydı geçici olarak devre dışıdır."
msgid "Regulate the use of critical commands"
msgstr " PEACE kritik komutlarin kullanilmasini engeller"
-#: modules/commands/hs_request.cpp:284
+#: modules/commands/hs_request.cpp:278
#, fuzzy
msgid "Reject the requested vHost for the given nick."
msgstr " STATUS Returns the owner status of the given nickname"
-#: modules/commands/hs_request.cpp:241
+#: modules/commands/hs_request.cpp:235
#, fuzzy
msgid "Reject the requested vHost of a user"
msgstr " DEL Delete the vhost of another user"
@@ -7580,46 +7557,46 @@ msgstr ""
msgid "Remove all operators from a server remotely"
msgstr " NOOP Geçici olarak tüm O:line ları kaldırır"
-#: modules/commands/os_dns.cpp:542
+#: modules/commands/os_dns.cpp:541
#, fuzzy, c-format
msgid "Removed IP %s from %s."
msgstr " Mod kilidi: %s"
-#: modules/commands/os_dns.cpp:459
+#: modules/commands/os_dns.cpp:458
#, c-format
msgid "Removed server %s from zone %s."
msgstr ""
-#: modules/commands/os_dns.cpp:482
+#: modules/commands/os_dns.cpp:481
#, c-format
msgid "Removed server %s."
msgstr ""
-#: modules/commands/cs_mode.cpp:852
+#: modules/commands/cs_mode.cpp:854
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
-#: modules/commands/cs_mode.cpp:833
+#: modules/commands/cs_mode.cpp:835
#, fuzzy, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr " OP Gives Op status to a selected nick on a channel"
-#: modules/commands/cs_updown.cpp:146
+#: modules/commands/cs_updown.cpp:140
#, fuzzy
msgid "Removes a selected nicks status from a channel"
msgstr " KICK Kicks a selected nick from a channel"
-#: modules/commands/cs_updown.cpp:223
+#: modules/commands/cs_updown.cpp:211
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is removed. If channel is omitted then\n"
+"ommited then your status is removed. If channel is ommited then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-#: src/xline.cpp:413
+#: src/xline.cpp:383
#, c-format
msgid "Removing %s because %s covers it."
msgstr ""
@@ -7635,14 +7612,14 @@ msgstr " Tekrarda atma : %s"
msgid "Request a vHost for your nick"
msgstr "There's no email address set for your nick."
-#: modules/commands/hs_request.cpp:180
+#: modules/commands/hs_request.cpp:174
msgid ""
-"Request the given vHost to be activated for your nick by the\n"
+"Request the given vHost to be actived for your nick by the\n"
"network administrators. Please be patient while your request\n"
"is being considered."
msgstr ""
-#: modules/commands/ns_register.cpp:291
+#: modules/commands/ns_register.cpp:281
#, fuzzy
msgid "Resend registration confirmation email"
msgstr " RELOAD Servislerin conf dosyasını yeniden yükler"
@@ -7652,7 +7629,7 @@ msgstr " RELOAD Servislerin conf dosyasını yeniden yükler"
msgid "Restrict access to the channel"
msgstr " RESTRICTED Kanala izinli giriÅŸ gerektirir"
-#: modules/commands/cs_set.cpp:1337
+#: modules/commands/cs_set.cpp:1344
#, fuzzy
msgid "Restricted access"
msgstr "Kisitli Erisim."
@@ -7689,7 +7666,7 @@ msgstr ""
" GETPASS Bir nickin şifresini öğrenmek içindir\n"
" (Sadece şifreleme(encryption) devre dışıysa)"
-#: modules/commands/hs_request.cpp:297
+#: modules/commands/hs_request.cpp:291
msgid "Retrieves the vhost requests"
msgstr ""
@@ -7705,8 +7682,17 @@ msgstr " GETKEY Returns the key of the given channel"
#: modules/commands/ns_getemail.cpp:58
#, fuzzy
-msgid "Returns the matching accounts that used given email."
-msgstr " GETKEY Returns the key of the given channel"
+msgid ""
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards. Whenever this command is used, a message\n"
+"including the person who issued the command and the email it was used\n"
+"on will be logged."
+msgstr ""
+"Syntax: GETEMAIL user@emailhost\n"
+"Returns the matching nicks that used given email. Note that\n"
+"you can not use wildcards for either user or emailhost. Whenever\n"
+"this command is used, a message including the person who issued\n"
+"the command and the email it was used on will be logged."
#: modules/commands/ns_status.cpp:19
#, fuzzy
@@ -7789,16 +7775,16 @@ msgstr " LOGOUT Reverses the effect of the IDENTIFY command"
msgid "SET server"
msgstr "NOOP {SET|REVOKE} server"
-#: modules/commands/os_dns.cpp:666
+#: modules/commands/os_dns.cpp:665
msgid "SET server.name option value"
msgstr ""
-#: modules/commands/ns_cert.cpp:378
+#: modules/commands/ns_cert.cpp:371
#, fuzzy, c-format
msgid "SSL certificate fingerprint accepted, you are now identified to %s."
msgstr "Åžifre kabul edildi."
-#: modules/commands/ns_cert.cpp:398
+#: modules/commands/ns_cert.cpp:382
#, fuzzy
msgid "SSL certificate fingerprint accepted, you are now identified."
msgstr "Åžifre kabul edildi."
@@ -7823,7 +7809,7 @@ msgstr ""
msgid "Searches logs for a matching pattern"
msgstr ""
-#: modules/commands/cs_set.cpp:1341
+#: modules/commands/cs_set.cpp:1348
#, fuzzy
msgid "Secure founder"
msgstr "Secure Founder"
@@ -7838,7 +7824,7 @@ msgstr "Secure founder option for %s is now ON."
msgid "Secure founder option for %s is now on."
msgstr "Secure founder option for %s is now ON."
-#: modules/commands/cs_set.cpp:1343
+#: modules/commands/cs_set.cpp:1350
#, fuzzy
msgid "Secure ops"
msgstr "Secure Ops"
@@ -7863,12 +7849,12 @@ msgstr "Secure option for %s is now ON."
msgid "Secure option for %s is now on."
msgstr "Secure option for %s is now ON."
-#: modules/commands/ns_set.cpp:1030
+#: modules/commands/ns_set.cpp:1020
#, fuzzy, c-format
msgid "Secure option is now off for %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1024
+#: modules/commands/ns_set.cpp:1014
#, fuzzy, c-format
msgid "Secure option is now on for %s."
msgstr "Secure option is now ON for %s."
@@ -7878,11 +7864,11 @@ msgstr "Secure option is now ON for %s."
msgid "Secureops enforced on %s."
msgstr "Secure option is now ON for %s."
-#: modules/commands/ns_set.cpp:1296 modules/commands/cs_set.cpp:1339
+#: modules/commands/ns_set.cpp:1286 modules/commands/cs_set.cpp:1346
msgid "Security"
msgstr "Güvenlik"
-#: modules/commands/cs_xop.cpp:578
+#: modules/commands/cs_xop.cpp:579
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7891,7 +7877,7 @@ msgstr ""
"Belirli bir özellik hakkında daha fazla bilgi için\n"
"/msg %s HELP özellik yazın."
-#: modules/commands/cs_xop.cpp:581
+#: modules/commands/cs_xop.cpp:582
#, fuzzy, c-format
msgid ""
"See %s%s HELP %s for more information\n"
@@ -7956,7 +7942,7 @@ msgstr ""
"Syntax: STAFF memo-text\n"
"Sends all services staff a memo containing memo-text."
-#: modules/commands/ms_send.cpp:66
+#: modules/commands/ms_send.cpp:57
#, fuzzy
msgid ""
"Sends the named nick or channel a memo containing\n"
@@ -8030,14 +8016,14 @@ msgid "Server %s already exists."
msgstr "%s nickli bot zaten var."
#: modules/commands/os_noop.cpp:31 modules/commands/os_dns.cpp:429
-#: modules/commands/os_dns.cpp:492 modules/commands/os_dns.cpp:531
-#: modules/commands/os_dns.cpp:570 modules/commands/os_dns.cpp:603
-#: modules/commands/os_dns.cpp:638
+#: modules/commands/os_dns.cpp:491 modules/commands/os_dns.cpp:530
+#: modules/commands/os_dns.cpp:569 modules/commands/os_dns.cpp:602
+#: modules/commands/os_dns.cpp:637
#, fuzzy, c-format
msgid "Server %s does not exist."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:618
+#: modules/commands/os_dns.cpp:617
#, fuzzy, c-format
msgid "Server %s has no configured IPs."
msgstr "%s nickinin kaydı silindi (dropped)."
@@ -8047,12 +8033,12 @@ msgstr "%s nickinin kaydı silindi (dropped)."
msgid "Server %s is already in zone %s."
msgstr "You are already in %s! "
-#: modules/commands/os_dns.cpp:613
+#: modules/commands/os_dns.cpp:612
#, fuzzy, c-format
msgid "Server %s is already pooled."
msgstr "Module %s is already loaded."
-#: modules/commands/os_dns.cpp:608
+#: modules/commands/os_dns.cpp:607
#, fuzzy, c-format
msgid "Server %s is not currently linked."
msgstr " %s şu an bağlı."
@@ -8067,12 +8053,12 @@ msgstr " %s (does not expire)"
msgid "Server %s is not linked to the network."
msgstr "%s kanalından bot çıkarıldı."
-#: modules/commands/os_dns.cpp:643
+#: modules/commands/os_dns.cpp:642
#, fuzzy, c-format
msgid "Server %s is not pooled."
msgstr " %s (does not expire)"
-#: modules/commands/os_dns.cpp:464
+#: modules/commands/os_dns.cpp:463
#, c-format
msgid "Server %s must be quit before it can be deleted."
msgstr ""
@@ -8092,19 +8078,18 @@ msgstr "Servers found: %d"
msgid "Service"
msgstr "Servers found: %d"
-#: modules/commands/ns_recover.cpp:51
+#: modules/commands/ns_recover.cpp:44
#, fuzzy, c-format
msgid "Service's hold on %s has been released."
msgstr "Nickiniz serbest bırakıldı."
-#: data/chanserv.example.conf:827 data/nickserv.example.conf:235
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
#, fuzzy
msgid "Services Operator commands"
msgstr "%s is a services operator of type %s."
-#: modules/commands/os_defcon.cpp:444 modules/commands/os_defcon.cpp:455
-#: modules/commands/os_defcon.cpp:463 modules/commands/os_defcon.cpp:471
-#: modules/commands/os_defcon.cpp:479
+#: modules/commands/os_defcon.cpp:446 modules/commands/os_defcon.cpp:454
+#: modules/commands/os_defcon.cpp:462 modules/commands/os_defcon.cpp:470
#, fuzzy
msgid "Services are in DefCon mode, please try again later."
msgstr "This service is temporarly disabled, please try again later"
@@ -8159,7 +8144,7 @@ msgstr "Servislerin mail gönderme özelliği devre dışıdır."
msgid "Services ignore list:"
msgstr " IGNORE Modify the Services ignore list"
-#: modules/commands/os_mode.cpp:33 modules/commands/os_kick.cpp:39
+#: modules/commands/os_kick.cpp:38 modules/commands/os_mode.cpp:33
#, fuzzy
msgid ""
"Services is unable to change modes. Are your servers' U:lines configured "
@@ -8173,7 +8158,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Servers found: %d"
-#: modules/commands/ns_set.cpp:263
+#: modules/commands/ns_set.cpp:258
#, fuzzy, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8183,7 +8168,7 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will no longer automatically give modes to users in %s."
msgstr "Services will no longer autoop %s in channels."
-#: modules/commands/ns_set.cpp:269
+#: modules/commands/ns_set.cpp:264
#, fuzzy, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services will no longer autoop %s in channels."
@@ -8193,12 +8178,12 @@ msgstr "Services will no longer autoop %s in channels."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services will now autoop %s in channels."
-#: modules/commands/ns_set.cpp:926
+#: modules/commands/ns_set.cpp:916
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services will now reply to %s with messages."
-#: modules/commands/ns_set.cpp:932
+#: modules/commands/ns_set.cpp:922
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services will now reply to %s with notices."
@@ -8217,7 +8202,7 @@ msgstr ""
msgid "Session limit for %s set to %d."
msgstr "%s için session limit %d olarak değiştirildi."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
msgid "Session limiting is disabled."
msgstr "Session limit koyma devre dışı."
@@ -8261,7 +8246,7 @@ msgstr " PERSIST Set the channel as permanent"
msgid "Set the channel description"
msgstr " DESC Kanal açıklamasını belirler"
-#: modules/commands/ns_set.cpp:326
+#: modules/commands/ns_set.cpp:321
#, fuzzy
msgid "Set the display of your group in Services"
msgstr " DISPLAY Grubunuzun servislerde nasıl görüneceğini ayarlar"
@@ -8271,14 +8256,14 @@ msgstr " DISPLAY Grubunuzun servislerde nasıl görüneceğini ayarlar"
msgid "Set the founder of a channel"
msgstr " FOUNDER Kanal founderını belirler"
-#: modules/commands/ns_set.cpp:779
+#: modules/commands/ns_set.cpp:772
#, fuzzy
msgid "Set the language Services will use when messaging you"
msgstr ""
" LANGUAGE Servislerin size hitap edeceÄŸi \n"
" dili belirler"
-#: modules/commands/ns_set.cpp:169
+#: modules/commands/ns_set.cpp:167
#, fuzzy
msgid "Set the nickname password"
msgstr " PASSWORD Set the nickname password"
@@ -8645,7 +8630,7 @@ msgstr ""
"Çeşitli nick özelliklerini ayarlar. özellik şunlardan biri \n"
"olabilir:"
-#: modules/commands/ns_set.cpp:234
+#: modules/commands/ns_set.cpp:229
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8664,7 +8649,7 @@ msgstr ""
"\n"
"Servis adminlerinin Kullanımıyla sınırlıdır."
-#: modules/commands/ns_set.cpp:312
+#: modules/commands/ns_set.cpp:307
#, fuzzy, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8679,7 +8664,7 @@ msgstr ""
"Set to ON to allow ChanServ to op the given nickname \n"
"automatically when joining channels."
-#: modules/commands/ns_set.cpp:1131
+#: modules/commands/ns_set.cpp:1121
#, fuzzy
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
@@ -8690,7 +8675,7 @@ msgstr ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
-#: modules/commands/ns_set.cpp:285
+#: modules/commands/ns_set.cpp:280
#, fuzzy, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8703,7 +8688,7 @@ msgstr ""
"Sets whether you will be opped automatically. Set to ON to \n"
"allow ChanServ to op you automatically when entering channels."
-#: modules/commands/cs_access.cpp:648 modules/commands/cs_access.cpp:689
+#: modules/commands/cs_access.cpp:641 modules/commands/cs_access.cpp:682
#, fuzzy, c-format
msgid ""
"Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
@@ -8770,11 +8755,11 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Signed kick option for %s is now ON."
-#: modules/commands/cs_set.cpp:1345
+#: modules/commands/cs_set.cpp:1352
msgid "Signed kicks"
msgstr "İşaretli atma"
-#: modules/commands/ms_send.cpp:59 modules/commands/ms_rsend.cpp:60
+#: modules/commands/ms_rsend.cpp:60 modules/commands/ms_send.cpp:50
#, fuzzy, c-format
msgid "Sorry, %s currently has too many memos and cannot receive more."
msgstr "%s nickinin limiti dolduÄŸundan daha fazla mesaj alamaz."
@@ -8784,44 +8769,38 @@ msgstr "%s nickinin limiti dolduÄŸundan daha fazla mesaj alamaz."
msgid "Sorry, I have not seen %s."
msgstr ""
-#: modules/commands/bs_badwords.cpp:404
-#, fuzzy
-msgid "Sorry, bad words list modification is temporarily disabled."
-msgstr "Kanalın küfür listesinde değişiklik yapma geçici olarak devre dışıdır."
-
#: modules/commands/bs_assign.cpp:30 modules/commands/bs_assign.cpp:98
#, fuzzy
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Bot özellik ayarı geçici olarak devre dışı."
-#: modules/commands/bs_assign.cpp:164 modules/commands/bs_bot.cpp:281
+#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Botta değişiklik yapma geçici olarak devre dışı."
-#: modules/commands/bs_kick.cpp:802 modules/commands/bs_kick.cpp:867
-#: modules/fantasy.cpp:42
+#: modules/fantasy.cpp:42 modules/commands/bs_kick.cpp:802
+#: modules/commands/bs_kick.cpp:867 modules/commands/bs_set.cpp:103
msgid "Sorry, bot option setting is temporarily disabled."
msgstr "Bot özellik ayarı geçici olarak devre dışı."
-#: modules/commands/bs_set.cpp:112
-#, fuzzy
-msgid "Sorry, changing bot options is temporarily disabled."
-msgstr "Bot özellik ayarı geçici olarak devre dışı."
-
-#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:239
-#: modules/commands/cs_xop.cpp:452
+#: modules/commands/cs_xop.cpp:112 modules/commands/cs_xop.cpp:235
+#: modules/commands/cs_xop.cpp:448
#, fuzzy, c-format
msgid "Sorry, channel %s list modification is temporarily disabled."
msgstr "Kanal AOP listesi degisiklikleri geçici olarak devre disidir."
-#: modules/commands/cs_flags.cpp:405 modules/commands/cs_access.cpp:547
+#: modules/commands/cs_access.cpp:540 modules/commands/cs_flags.cpp:402
msgid "Sorry, channel access list modification is temporarily disabled."
msgstr "Kanal access listesinin değiştirilmesi geçici olarak devre dışıdır."
-#: modules/commands/cs_akick.cpp:457
+#: modules/commands/cs_akick.cpp:449
msgid "Sorry, channel autokick list modification is temporarily disabled."
msgstr "Kanal Akick listesinin değiştirilmesi geçici olarak devre dışıdır."
+#: modules/commands/bs_badwords.cpp:403
+msgid "Sorry, channel bad words list modification is temporarily disabled."
+msgstr "Kanalın küfür listesinde değişiklik yapma geçici olarak devre dışıdır."
+
#: modules/commands/cs_drop.cpp:29
msgid "Sorry, channel de-registration is temporarily disabled."
msgstr "Kanal kaydının silinmesi(DROP) geçici olarak devre dışıdır."
@@ -8851,7 +8830,7 @@ msgstr "Nick kaydı silinmesi geçici olarak devre dışıdır."
msgid "Sorry, nickname grouping is temporarily disabled."
msgstr "Nick gruplama geçici olarak devre dışı."
-#: modules/commands/ns_register.cpp:125
+#: modules/commands/ns_register.cpp:123
msgid "Sorry, nickname registration is temporarily disabled."
msgstr "Nick kaydı geçici olarak devre dışıdır."
@@ -8870,13 +8849,8 @@ msgstr ""
msgid "Sorry, the maximum of %d certificate entries has been reached."
msgstr "Bir nick için sadece %d tane access girilebilir."
-#: modules/commands/ms_ignore.cpp:55
-#, fuzzy, c-format
-msgid "Sorry, the memo ignore list for %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/cs_xop.cpp:205 modules/commands/cs_flags.cpp:174
-#: modules/commands/cs_access.cpp:204
+#: modules/commands/cs_access.cpp:199 modules/commands/cs_xop.cpp:201
+#: modules/commands/cs_flags.cpp:173
#, fuzzy, c-format
msgid ""
"Sorry, you can only have %d access entries on a channel, including access "
@@ -8888,7 +8862,7 @@ msgstr "Kanalda sadece %d tane access kaydı olabilir."
msgid "Sorry, you can only have %d autokick masks on a channel."
msgstr "Bir kanalın akick listesinde en fazla %d kişi olabilir."
-#: modules/commands/bs_badwords.cpp:286
+#: modules/commands/bs_badwords.cpp:285
#, c-format
msgid "Sorry, you can only have %d bad words entries on a channel."
msgstr "Bir kanalda sadece %d tane küfür kaydı olabilir."
@@ -8955,7 +8929,7 @@ msgstr "%s için successor kaldırıldı."
#, fuzzy
msgid ""
"Super admin can not be set because it is not enabled in the configuration."
-msgstr "SuperAdmin setting not enabled in services.conf"
+msgstr "SuperAdmin setting not enabled in anope.conf"
#: modules/commands/ns_suspend.cpp:60
#, fuzzy
@@ -9171,7 +9145,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email as well as\n"
+" MAIL You will be notified of memos by email aswell as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -9243,7 +9217,7 @@ msgstr ""
"This opion is _NOT_ persistant, and should only be used when\n"
"needed, and set back to OFF when no longer needed."
-#: modules/commands/ns_identify.cpp:107
+#: modules/commands/ns_identify.cpp:96
#, fuzzy, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -9265,7 +9239,7 @@ msgid ""
"Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Kullanımı: INVITE kanaladı\n"
@@ -9282,7 +9256,7 @@ msgid ""
"given, all bans affecting you in channels you have access\n"
"in are removed.\n"
" \n"
-"By default, limited to AOPs or those with level 5 access and above\n"
+"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."
msgstr ""
"Kullanımı: UNBAN kanaladı [nick]\n"
@@ -9334,7 +9308,7 @@ msgstr " SHUTDOWN Servisler programını kayıt ederek kapatır"
msgid "Text"
msgstr ""
-#: modules/commands/cs_access.cpp:576
+#: modules/commands/cs_access.cpp:569
msgid ""
"The ACCESS ADD command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
@@ -9345,7 +9319,7 @@ msgid ""
"highest level entry in the access list."
msgstr ""
-#: modules/commands/cs_access.cpp:587
+#: modules/commands/cs_access.cpp:580
msgid ""
"The ACCESS DEL command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
@@ -9354,7 +9328,7 @@ msgid ""
"do not have access to modify that list otherwise."
msgstr ""
-#: modules/commands/cs_access.cpp:593
+#: modules/commands/cs_access.cpp:586
msgid ""
"The ACCESS LIST command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
@@ -9371,10 +9345,10 @@ msgid ""
"access list."
msgstr ""
-#: modules/commands/cs_flags.cpp:447
+#: modules/commands/cs_flags.cpp:432
msgid ""
-"The CLEAR command clears the channel access list. This requires channel "
-"founder access."
+"The CLEAR command clears the channel access list, which requires channel "
+"founder."
msgstr ""
#: modules/commands/cs_seen.cpp:174
@@ -9382,14 +9356,14 @@ msgstr ""
msgid ""
"The CLEAR command lets you clean the database by removing all entries from "
"the\n"
-"database that were added within time.\n"
+"entries from the database that were added within time.\n"
" \n"
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."
msgstr ""
-#: modules/commands/bs_badwords.cpp:438
+#: modules/commands/bs_badwords.cpp:437
#, fuzzy
msgid ""
"The DEL command removes the given word from the\n"
@@ -9404,7 +9378,7 @@ msgid ""
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
-"The CLEAR command clears all entries from the\n"
+"The CLEAR command clears all entries of the\n"
"bad words list."
msgstr ""
"Kullanımı: HOP kanaladi ADD nick\n"
@@ -9443,36 +9417,36 @@ msgstr ""
#: modules/commands/cs_entrymsg.cpp:241
msgid ""
"The ENTRYMSG ADD command adds the given message to\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:253
msgid ""
"The ENTRYMSG CLEAR command clears all entries from\n"
-"the list of messages shown to users when they join\n"
+"the list of messages to be shown to users when they join\n"
"the channel, effectively disabling entry messages."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:245
msgid ""
-"The ENTRYMSG DEL command removes the specified message from\n"
-"the list of messages shown to users when they join\n"
-"the channel. You can remove a message by specifying its number\n"
+"The ENTRYMSG DEL command removes the given message from\n"
+"the list of messages to be shown to users when they join\n"
+"the channel. You can remove the message by specifying its number\n"
"which you can get by listing the messages as explained below."
msgstr ""
#: modules/commands/cs_entrymsg.cpp:250
msgid ""
"The ENTRYMSG LIST command displays a listing of messages\n"
-"shown to users when they join the channel."
+"to be shown to users when they join the channel."
msgstr ""
-#: modules/commands/ns_set.cpp:699
+#: modules/commands/ns_set.cpp:692
msgid "The IMMED option is not available on this network."
msgstr "HEMEN seçeneği bu networkte aktif değil."
-#: modules/commands/cs_access.cpp:821
+#: modules/commands/cs_access.cpp:806
#, fuzzy, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -9520,7 +9494,7 @@ msgstr ""
"For a list of the features and functions whose levels can be\n"
"set, see HELP LEVELS DESC."
-#: modules/commands/cs_flags.cpp:442
+#: modules/commands/cs_flags.cpp:427
msgid ""
"The LIST command allows you to list existing entries on the channel access "
"list.\n"
@@ -9531,18 +9505,18 @@ msgid ""
"on the access list with the specified flags are returned."
msgstr ""
-#: modules/commands/cs_flags.cpp:435
+#: modules/commands/cs_flags.cpp:420
msgid ""
-"The MODIFY command allows you to modify the access list. If the mask is\n"
-"not already on the access list it is added, then the changes are applied.\n"
+"The MODIFY command allows you to modify the access list. If mask is\n"
+"not already on the access list is it added, then the changes are applied.\n"
"If the mask has no more flags, then the mask is removed from the access "
"list.\n"
"Additionally, you may use +* or -* to add or remove all flags, respectively. "
"You are\n"
"only able to modify the access list if you have the proper permission on the "
"channel,\n"
-"and even then you can only give other people access to the equivalent of "
-"what your access is."
+"and even then you can only give other people access to up what you already "
+"have."
msgstr ""
#: modules/commands/cs_seen.cpp:173
@@ -9550,7 +9524,7 @@ msgid ""
"The STATS command prints out statistics about stored nicks and memory usage."
msgstr ""
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:260
#, fuzzy
msgid ""
"The email parameter is optional and will set the email\n"
@@ -9564,7 +9538,6 @@ msgstr ""
"şahıslara verilmeyecektir."
#: modules/commands/cs_log.cpp:258
-#, c-format
msgid ""
"The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
@@ -9582,7 +9555,7 @@ msgid ""
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
-" %s #anope chanserv/access MESSAGE @\n"
+" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."
msgstr ""
@@ -9592,12 +9565,12 @@ msgstr ""
msgid "The %s list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/os_sxline.cpp:220
+#: modules/commands/os_sxline.cpp:214
#, fuzzy, c-format
msgid "The %s list has been cleared."
msgstr "AKILL listesi temizlendi."
-#: modules/commands/os_akill.cpp:377
+#: modules/commands/os_akill.cpp:371
msgid "The AKILL list has been cleared."
msgstr "AKILL listesi temizlendi."
@@ -9616,7 +9589,7 @@ msgstr "The E-mail address of %s will now be hidden from %s INFO displays."
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr "The E-mail address of %s will now be shown in %s INFO displays."
-#: modules/commands/cs_flags.cpp:449
+#: modules/commands/cs_flags.cpp:434
msgid "The available flags are:"
msgstr ""
@@ -9647,11 +9620,11 @@ msgstr ""
msgid "The entry message list for %s is full."
msgstr "Greet message for %s unset."
-#: modules/commands/cs_access.cpp:796
+#: modules/commands/cs_access.cpp:781
msgid "The following feature/function names are available:"
msgstr ""
-#: modules/commands/cs_access.cpp:584
+#: modules/commands/cs_access.cpp:577
msgid ""
"The given mask may also be a channel, which will use the\n"
"access list from the other channel up to the given level."
@@ -9712,12 +9685,7 @@ msgstr ""
msgid "The memo limit for %s may not be changed."
msgstr "%s nickinin mesaj limiti deÄŸiÅŸtirelemez."
-#: modules/commands/cs_mode.cpp:332
-#, fuzzy, c-format
-msgid "The mode lock list of %s is full."
-msgstr "Greet message for %s unset."
-
-#: modules/commands/ns_set.cpp:352
+#: modules/commands/ns_set.cpp:347
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr ""
@@ -9732,10 +9700,6 @@ msgstr "The Defcon Level is now at Level: %d"
msgid "The nick %s is now being changed to %s."
msgstr "The nick %s is now being changed to %s."
-#: modules/commands/bs_bot.cpp:149
-msgid "The old information is the same as the new information specified."
-msgstr ""
-
#: modules/commands/os_info.cpp:157
#, fuzzy, c-format
msgid "The oper info already exists on %s."
@@ -9759,12 +9723,12 @@ msgid "The services access status of %s will now be shown in %s INFO displays.
msgstr ""
"The services access status of %s will now be shown in %s INFO displays."
-#: modules/commands/os_session.cpp:433
+#: modules/commands/os_session.cpp:471
#, fuzzy
msgid "The session exception list is empty."
msgstr " EXCEPTION Session-limit exception listesini düzenler"
-#: modules/commands/ns_recover.cpp:121
+#: modules/commands/ns_recover.cpp:102
msgid ""
"The user with your nick has been removed. Use this command again\n"
"to release services's hold on your nick."
@@ -9836,7 +9800,7 @@ msgstr "Hiç karisik haber yok."
msgid "There is no such configuration block %s."
msgstr " RELOAD Servislerin conf dosyasını yeniden yükler"
-#: modules/commands/cs_mode.cpp:655
+#: modules/commands/cs_mode.cpp:657
#, fuzzy, c-format
msgid "There is no such mode %s."
msgstr "Hiç operatör haberi yok."
@@ -9864,7 +9828,7 @@ msgstr "Bu kanal kullanılamaz."
msgid "This channel may not be used."
msgstr "Bu kanal kullanılamaz."
-#: modules/commands/os_dns.cpp:701
+#: modules/commands/os_dns.cpp:700
msgid ""
"This command allows managing DNS zones used for controlling what servers "
"users\n"
@@ -9901,7 +9865,7 @@ msgstr ""
"CURRENT nick to be the vhost for all nicks in the same\n"
"group."
-#: modules/commands/ns_register.cpp:278
+#: modules/commands/ns_register.cpp:268
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9914,7 +9878,7 @@ msgstr ""
msgid "This command is an alias to the command %s."
msgstr ""
-#: modules/commands/ns_register.cpp:81
+#: modules/commands/ns_register.cpp:79
#, fuzzy
msgid ""
"This command is used by several commands as a way to confirm\n"
@@ -9948,8 +9912,8 @@ msgstr ""
#: modules/commands/hs_list.cpp:136
#, fuzzy
msgid ""
-"This command lists registered vhosts to the operator.\n"
-"If a key is specified, only entries whose nick or vhost match\n"
+"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"
"If a #X-Y style is used, only entries between the range of X\n"
@@ -10044,7 +10008,7 @@ msgid ""
"auto join lists."
msgstr ""
-#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
+#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -10058,7 +10022,7 @@ msgstr ""
"This command loads the module named FileName from the modules\n"
"directory."
-#: modules/commands/hs_request.cpp:345
+#: modules/commands/hs_request.cpp:339
msgid "This command retrieves the vhost requests."
msgstr ""
@@ -10110,7 +10074,7 @@ msgstr ""
"This command loads the module named FileName from the modules\n"
"directory."
-#: modules/commands/ns_register.cpp:332
+#: modules/commands/ns_register.cpp:322
msgid "This command will resend you the registration confirmation email."
msgstr ""
@@ -10126,12 +10090,12 @@ msgstr ""
msgid "This nickname has been forbidden: %s"
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:99
+#: modules/commands/ns_recover.cpp:91
#, fuzzy, c-format
msgid "This nickname has been recovered by %s."
msgstr "This nickname is currently suspended, reason: %s"
-#: modules/commands/ns_recover.cpp:77
+#: modules/commands/ns_recover.cpp:70
#, c-format
msgid ""
"This nickname has been recovered by %s. If you did not do\n"
@@ -10194,7 +10158,7 @@ msgstr ""
msgid "Topic"
msgstr "Topic kilidi"
-#: modules/commands/cs_topic.cpp:258
+#: modules/commands/cs_topic.cpp:253
#, fuzzy
msgid "Topic lock"
msgstr "Topic kilidi"
@@ -10209,7 +10173,7 @@ msgstr "Topic lock option for %s is now ON."
msgid "Topic lock option for %s is now on."
msgstr "Topic lock option for %s is now ON."
-#: modules/commands/cs_topic.cpp:256
+#: modules/commands/cs_topic.cpp:251
#, fuzzy
msgid "Topic retention"
msgstr "Topic hatırlama"
@@ -10224,7 +10188,7 @@ msgstr "Topic retention option for %s is now ON."
msgid "Topic retention option for %s is now on."
msgstr "Topic retention option for %s is now ON."
-#: modules/commands/cs_topic.cpp:265
+#: modules/commands/cs_topic.cpp:260
msgid "Topic set by"
msgstr ""
@@ -10232,17 +10196,18 @@ msgstr ""
msgid "Turn caps lock OFF!"
msgstr "Lütfen büyük harf kullanmayın!"
-#: modules/extra/stats/m_chanstats.cpp:9 modules/extra/stats/m_chanstats.cpp:63
+#: modules/extra/stats/m_chanstats.cpp:9
+#: modules/extra/stats/m_chanstats.cpp:63
#, fuzzy
msgid "Turn chanstats statistics on or off"
msgstr " SECURE Nick güvenliğini açar kapatır"
-#: modules/commands/ns_set.cpp:995
+#: modules/commands/ns_set.cpp:985
#, fuzzy
msgid "Turn nickname security on or off"
msgstr " SECURE Nick güvenliğini açar kapatır"
-#: modules/commands/ns_set.cpp:641
+#: modules/commands/ns_set.cpp:634
#, fuzzy
msgid "Turn protection on or off"
msgstr " KILL Korumayı açar kapatır"
@@ -10280,7 +10245,7 @@ msgstr ""
"gözükmeyecektir.(Buna rağmen, nickinizi bilen biri INFO \n"
"komutunu kullanarak hakkınızda bilgi alabilir.)"
-#: modules/commands/ns_set.cpp:1045 modules/commands/ns_set.cpp:1074
+#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
#, fuzzy, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -10311,7 +10276,7 @@ msgstr " SECURE Nick güvenliğini açar kapatır"
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr " SECURE Nick güvenliğini açar kapatır"
-#: modules/commands/ns_set.cpp:758
+#: modules/commands/ns_set.cpp:751
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -10342,7 +10307,7 @@ msgstr ""
"do not use this option unless necessary. Also, your\n"
"network's administrators may have disabled this option."
-#: modules/commands/ns_set.cpp:724
+#: modules/commands/ns_set.cpp:717
#, fuzzy, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -10373,7 +10338,7 @@ msgstr ""
"bu özelliği kullanmayın. Hatta network yöneticileri bu\n"
"özelliği devre dışı bırakmış olabilirler."
-#: modules/commands/bs_badwords.cpp:194 modules/commands/os_forbid.cpp:346
+#: modules/commands/os_forbid.cpp:346 modules/commands/bs_badwords.cpp:193
msgid "Type"
msgstr ""
@@ -10410,7 +10375,7 @@ msgstr ""
"on a specific option. The options will be set on the given\n"
"nickname."
-#: modules/commands/cs_set.cpp:60 modules/commands/bs_set.cpp:59
+#: modules/commands/bs_set.cpp:50 modules/commands/cs_set.cpp:60
#, fuzzy, c-format
msgid ""
"Type %s%s HELP %s option for more information on a\n"
@@ -10419,7 +10384,7 @@ msgstr ""
"Belirli bir özellik hakkında daha fazla bilgi için\n"
"/msg %s HELP özellik yazın."
-#: modules/pseudoclients/nickserv.cpp:361
+#: modules/pseudoclients/nickserv.cpp:342
#, fuzzy, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -10435,8 +10400,8 @@ msgstr ""
msgid "Un-Load a module"
msgstr " MODUNLOAD Un-Load a module"
-#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:337
-#: modules/commands/os_sxline.cpp:552
+#: modules/commands/os_akill.cpp:136 modules/commands/os_sxline.cpp:331
+#: modules/commands/os_sxline.cpp:545
#, fuzzy, c-format
msgid "Unable to find regex engine %s."
msgstr "Unable to remove module %s"
@@ -10479,7 +10444,7 @@ msgstr ""
msgid "Underlines kicker"
msgstr "Altıçizili yazıda atma : %s"
-#: modules/commands/os_dns.cpp:594
+#: modules/commands/os_dns.cpp:593
#, fuzzy
msgid "Unknown SET option."
msgstr "Unknown SASET option %s."
@@ -10499,7 +10464,7 @@ msgstr "Varolmayan özellik %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Varolmayan komut %s. yardım için \"%s%s HELP\" yazınız."
-#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
+#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:391
#, fuzzy, c-format
msgid "Unknown mode character %c ignored."
msgstr "Varolmayan mod karakteri %c yoksayıldı."
@@ -10526,8 +10491,8 @@ msgstr ""
#: modules/commands/cs_drop.cpp:74
#, fuzzy
msgid ""
-"Unregisters the specified channel. Only Services Operators\n"
-"can drop a channel of which they are not the founder of."
+"Unregisters the named channel. Only Services Operators\n"
+"can drop a channel of which they are not the founder."
msgstr ""
"Kullanımı: DROP kanaladı\n"
"\n"
@@ -10543,10 +10508,10 @@ msgstr " UNSUSPEND Unsuspend a given nick"
msgid "Unsuspends a nickname which allows it to be used again."
msgstr ""
-#: modules/commands/cs_updown.cpp:126
+#: modules/commands/cs_updown.cpp:120
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"omitted then your status is updated. If channel is omitted then\n"
+"ommited then your status is updated. If channel is ommited then\n"
"your channel status is updated on every channel you are in."
msgstr ""
@@ -10596,31 +10561,31 @@ msgstr ""
msgid "Used on"
msgstr ""
-#: data/chanserv.example.conf:821
+#: data/chanserv.example.conf:814
#, fuzzy
msgid "Used to manage channels"
msgstr "%s changed your usermodes."
-#: data/chanserv.example.conf:809
+#: data/chanserv.example.conf:802
#, fuzzy
msgid "Used to manage the list of privileged users"
msgstr " ACCESS Ayrıcalıklı kullanıcıları belirler değiştirir"
-#: data/chanserv.example.conf:815
+#: data/chanserv.example.conf:808
msgid "Used to modify the channel status of you or other users"
msgstr ""
-#: modules/commands/cs_akick.cpp:563
+#: modules/commands/cs_akick.cpp:551
#, fuzzy
msgid "User has been banned from the channel"
msgstr "%s kanalındaki banınız kaldırıldı."
-#: modules/commands/os_dns.cpp:586
+#: modules/commands/os_dns.cpp:585
#, fuzzy, c-format
msgid "User limit for %s removed."
msgstr "vhost for %s removed."
-#: modules/commands/os_dns.cpp:584
+#: modules/commands/os_dns.cpp:583
#, fuzzy, c-format
msgid "User limit for %s set to %d."
msgstr "%s nickinin mesaj limiti %d olarak ayarlandı."
@@ -10673,13 +10638,13 @@ msgstr "vhost for group %s set to %s@%s."
msgid "VIEW host"
msgstr ""
-#: modules/commands/os_akill.cpp:389 modules/commands/os_sxline.cpp:428
-#: modules/commands/os_sxline.cpp:662
+#: modules/commands/os_akill.cpp:383 modules/commands/os_sxline.cpp:421
+#: modules/commands/os_sxline.cpp:654
#, fuzzy
msgid "VIEW [mask | list | id]"
msgstr "LIST [kanaladı] [liste | NEW]"
-#: modules/commands/os_session.cpp:526
+#: modules/commands/os_session.cpp:565
msgid "VIEW [mask | list]"
msgstr ""
@@ -10692,7 +10657,7 @@ msgstr ""
msgid "Value of %s:%s changed to %s"
msgstr "%s kanalının founderı %s olarak değiştirildi."
-#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:306
+#: modules/commands/hs_list.cpp:58 modules/commands/hs_request.cpp:300
msgid "Vhost"
msgstr ""
@@ -10730,7 +10695,7 @@ msgid ""
"%s's %s command."
msgstr ""
-#: modules/commands/ms_info.cpp:204
+#: modules/commands/ms_info.cpp:187
#, fuzzy
msgid ""
"Without a parameter, displays information on the number of\n"
@@ -10819,7 +10784,7 @@ msgstr ""
"RESET parametresi önceki maksimum kullanıcı sayısını o anda\n"
"networkte bulunan kullanıcı sayısıyla değiştirir."
-#: modules/commands/bs_badwords.cpp:194
+#: modules/commands/bs_badwords.cpp:193
msgid "Word"
msgstr ""
@@ -10828,7 +10793,7 @@ msgstr ""
msgid "You are already a member of the group of %s."
msgstr "%s grubunun zaten bir üyesisiniz."
-#: modules/commands/ns_identify.cpp:87 modules/commands/os_login.cpp:35
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
msgid "You are already identified."
msgstr "You are already identified."
@@ -10893,7 +10858,7 @@ msgstr ""
msgid "You can not NOOP Services."
msgstr ""
-#: modules/commands/cs_access.cpp:672
+#: modules/commands/cs_access.cpp:665
msgid ""
"You can not disable the founder privilege because it would be impossible to "
"reenable it at a later time."
@@ -10918,13 +10883,22 @@ msgstr ""
msgid "You can not request a receipt when sending a memo to yourself."
msgstr "You can not request a receipt when sending a memo to yourself."
-#: modules/commands/ns_recover.cpp:163
+#: modules/commands/cs_flags.cpp:230
+#, fuzzy, c-format
+msgid "You can not set the %c flag."
+msgstr "You cannot use this command."
+
+#: modules/commands/bs_assign.cpp:124
+msgid "You can not unassign bots while persist is set on the channel."
+msgstr "You can not unassign bots while persist is set on the channel."
+
+#: modules/commands/ns_recover.cpp:143
#, fuzzy, c-format
msgid "You can't %s yourself!"
msgstr "Kendinizi ghost edemezsiniz!"
-#: modules/commands/cs_xop.cpp:155 modules/commands/cs_flags.cpp:109
-#: modules/commands/cs_access.cpp:154
+#: modules/commands/cs_access.cpp:153 modules/commands/cs_xop.cpp:154
+#: modules/commands/cs_flags.cpp:111
#, fuzzy
msgid "You can't add a channel to its own access list."
msgstr "Uyuşan kayıt %s kanalının access listesinde yok."
@@ -10934,16 +10908,11 @@ msgstr "Uyuşan kayıt %s kanalının access listesinde yok."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Can't logout %s because he's a Services Operator."
-#: modules/commands/ns_set.cpp:913
+#: modules/commands/ns_set.cpp:903
#, fuzzy, c-format
msgid "You cannot %s on this network."
msgstr "E-mail adresini bu networkte silemezsiniz."
-#: modules/commands/cs_flags.cpp:231
-#, fuzzy, c-format
-msgid "You cannot set the %c flag."
-msgstr "You cannot use this command."
-
#: modules/commands/ms_set.cpp:173
#, c-format
msgid "You cannot set the memo limit for %s higher than %d."
@@ -10954,12 +10923,7 @@ msgstr "%s nickinin mesaj limitini %d sayısından daha fazla yapamazsınız."
msgid "You cannot set your memo limit higher than %d."
msgstr "Mesaj limitinizi %d sayısından daha fazla yapamazsınız."
-#: modules/commands/bs_assign.cpp:124
-#, fuzzy
-msgid "You cannot unassign bots while persist is set on the channel."
-msgstr "You can not unassign bots while persist is set on the channel."
-
-#: modules/commands/ns_set.cpp:469
+#: modules/commands/ns_set.cpp:462
msgid "You cannot unset the e-mail on this network."
msgstr "E-mail adresini bu networkte silemezsiniz."
@@ -10999,12 +10963,12 @@ msgstr "Şu an 1 mesajınız var."
msgid "You currently have no memos."
msgstr "Şu an hiç mesajınız yok."
-#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
+#: modules/commands/cs_mode.cpp:541 modules/commands/cs_mode.cpp:578
#, c-format
msgid "You do not have access to set mode %c."
msgstr ""
-#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
+#: modules/commands/cs_mode.cpp:554 modules/commands/cs_mode.cpp:587
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr ""
@@ -11040,7 +11004,7 @@ msgstr "You have been invited to %s."
msgid "You have been invited to %s."
msgstr "You have been invited to %s."
-#: modules/commands/ns_recover.cpp:96 modules/protocol/ratbox.cpp:137
+#: modules/protocol/ratbox.cpp:137
#, fuzzy, c-format
msgid "You have been logged in as %s."
msgstr "Nickinizin çıkışı yapıldı."
@@ -11083,32 +11047,27 @@ msgstr ""
"Dikkat: Maksimum mesaj sayınıza ulaştınız (%d). Şimdiki mesajlarınızdan bir "
"kaçını silmezseniz yeni mesaj alamayacaksınız."
-#: modules/commands/ns_recover.cpp:117
-#, fuzzy, c-format
-msgid "You have regained control of %s."
-msgstr "You have been invited to %s."
-
#: modules/commands/ns_drop.cpp:66
#, fuzzy
msgid "You may drop any nick within your group."
msgstr " DELALL Delete the vhost for all nicks in a group"
-#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
+#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:396
#, c-format
msgid "You may not (un)lock mode %c."
msgstr ""
-#: modules/commands/ns_set.cpp:474
+#: modules/commands/ns_set.cpp:467
#, fuzzy
msgid "You may not change the e-mail of other Services Operators."
msgstr "E-mail adresini bu networkte silemezsiniz."
-#: modules/commands/ns_set.cpp:463
+#: modules/commands/ns_set.cpp:456
#, fuzzy
msgid "You may not change the email of an unconfirmed account."
msgstr "E-mail adresini bu networkte silemezsiniz."
-#: modules/commands/ns_set.cpp:193
+#: modules/commands/ns_set.cpp:191
#, fuzzy
msgid "You may not change the password of other Services Operators."
msgstr "Can't logout %s because he's a Services Operator."
@@ -11155,11 +11114,6 @@ msgstr ""
"Kanal kayıt edebilmeniz için kayıt edilmemiş bir kanala ilk girip op olmanız "
"gerekmektedir."
-#: modules/commands/cs_updown.cpp:94 modules/commands/cs_updown.cpp:192
-#, fuzzy, c-format
-msgid "You must be in %s to use this command."
-msgstr "You need to be identified to use this command."
-
#: modules/commands/cs_register.cpp:37
#, fuzzy
msgid "You must confirm your account before you can register a channel."
@@ -11167,20 +11121,6 @@ msgstr ""
"Kanal kayıt edebilmeniz için kayıt edilmemiş bir kanala ilk girip op olmanız "
"gerekmektedir."
-#: modules/commands/hs_request.cpp:101
-#, fuzzy
-msgid "You must confirm your account before you may request a vhost."
-msgstr ""
-"Kanal kayıt edebilmeniz için kayıt edilmemiş bir kanala ilk girip op olmanız "
-"gerekmektedir."
-
-#: modules/commands/ms_send.cpp:44
-#, fuzzy
-msgid "You must confirm your account before you may send a memo."
-msgstr ""
-"Kanal kayıt edebilmeniz için kayıt edilmemiş bir kanala ilk girip op olmanız "
-"gerekmektedir."
-
#: modules/commands/cs_drop.cpp:42
#, c-format
msgid ""
@@ -11188,17 +11128,17 @@ msgid ""
" %s."
msgstr ""
-#: modules/commands/ns_register.cpp:139
+#: modules/commands/ns_register.cpp:137
#, c-format
msgid "You must have been using this nick for at least %d seconds to register."
msgstr "You have to be connected longer than %d seconds to register your nick."
-#: modules/commands/cs_mode.cpp:856
+#: modules/commands/cs_mode.cpp:858
#, fuzzy, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr "You need to be identified to use this command."
-#: modules/pseudoclients/nickserv.cpp:358
+#: modules/pseudoclients/nickserv.cpp:339
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
@@ -11212,36 +11152,16 @@ msgstr ""
msgid "You need to be identified to use this command."
msgstr "You need to be identified to use this command."
-#: modules/commands/ms_info.cpp:182
-#, fuzzy
-msgid "You will be notified by message and by mail when new memos arrive."
-msgstr "Yeni mesajlar için ulaştıkları anda uyarılacaksınız."
-
-#: modules/commands/ms_info.cpp:175
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon and when they arrive, and by mail "
-"when they arrive."
-msgstr ""
-"Yeni mesajlar için bağlandığınızda ve size ulaştığında uyarılacaksınız."
-
-#: modules/commands/ms_info.cpp:177
+#: modules/commands/ms_info.cpp:173
msgid "You will be notified of new memos at logon and when they arrive."
msgstr ""
"Yeni mesajlar için bağlandığınızda ve size ulaştığında uyarılacaksınız."
-#: modules/commands/ms_info.cpp:189
-#, fuzzy
-msgid ""
-"You will be notified of new memos at logon, and by mail when they arrive."
-msgstr ""
-"Yeni mesajlar için bağlandığınızda ve size ulaştığında uyarılacaksınız."
-
-#: modules/commands/ms_info.cpp:191
+#: modules/commands/ms_info.cpp:177
msgid "You will be notified of new memos at logon."
msgstr "Yeni mesajlar için bağlandığınızda uyarılacaksınız."
-#: modules/commands/ms_info.cpp:184
+#: modules/commands/ms_info.cpp:175
msgid "You will be notified when new memos arrive."
msgstr "Yeni mesajlar için ulaştıkları anda uyarılacaksınız."
@@ -11253,7 +11173,7 @@ msgstr "Limitiniz sıfır olduğundan artık mesaj alamayacaksınız."
msgid "You will no longer be informed via email."
msgstr "You will no longer be informed via email."
-#: modules/commands/ms_info.cpp:195
+#: modules/commands/ms_info.cpp:179
msgid "You will not be notified of new memos."
msgstr "Yeni mesajlar için uyarılmayacaksınız."
@@ -11279,23 +11199,23 @@ msgid ""
"this as a possible bug"
msgstr ""
-#: modules/extra/m_ldap_authentication.cpp:102
+#: modules/extra/m_ldap_authentication.cpp:110
#: modules/extra/m_sql_authentication.cpp:47
#, fuzzy, c-format
msgid "Your account %s has been successfully created."
msgstr "%s botu silindi."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:297
#, fuzzy
msgid "Your account is already confirmed."
msgstr "You are already identified."
-#: modules/commands/ns_register.cpp:375
+#: modules/commands/ns_register.cpp:365
#, fuzzy, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "You are already identified."
-#: modules/commands/ns_set.cpp:1259
+#: modules/commands/ns_set.cpp:1249
#, fuzzy, c-format
msgid "Your email address has been changed to %s."
msgstr "E-mail address for %s changed to %s."
@@ -11305,18 +11225,18 @@ msgstr "E-mail address for %s changed to %s."
msgid "Your email address is not allowed, choose a different one."
msgstr "%s serverındaki tüm O:line lar silindi."
-#: modules/commands/ns_register.cpp:370
+#: modules/commands/ns_register.cpp:360
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-#: modules/commands/ns_register.cpp:53
+#: modules/commands/ns_register.cpp:52
#, fuzzy, c-format
msgid "Your email address of %s has been confirmed."
msgstr "%s serverındaki tüm O:line lar silindi."
-#: modules/extra/m_ldap_authentication.cpp:151
+#: modules/extra/m_ldap_authentication.cpp:171
#, fuzzy, c-format
msgid "Your email has been updated to %s"
msgstr "E-mail address for %s changed to %s."
@@ -11376,7 +11296,7 @@ msgstr "Your nick is not grouped to anything, you can't ungroup it."
msgid "Your nick isn't registered."
msgstr "Nickname %s registered."
-#: modules/pseudoclients/nickserv.cpp:254
+#: modules/pseudoclients/nickserv.cpp:236
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Nickiniz %s olarak deÄŸiÅŸtirildi."
@@ -11385,12 +11305,12 @@ msgstr "Nickiniz %s olarak deÄŸiÅŸtirildi."
msgid "Your oper block doesn't require logging in."
msgstr ""
-#: modules/commands/ns_register.cpp:315
+#: modules/commands/ns_register.cpp:305
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Your passcode has been re-sent to %s."
-#: modules/commands/ns_register.cpp:218
+#: modules/commands/ns_register.cpp:210
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr ""
@@ -11398,32 +11318,31 @@ msgstr ""
"söylemeyiniz."
#: include/language.h:77
-#, c-format
-msgid "Your password is too long. It must not exceed %u characters."
+msgid "Your password is too long. Please try again with a shorter password."
msgstr ""
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
msgstr "Your password reset request has expired."
-#: modules/commands/hs_request.cpp:171
+#: modules/commands/hs_request.cpp:165
#, fuzzy
msgid "Your vHost has been requested."
msgstr "%s botu silindi."
-#: modules/commands/hs_on.cpp:37 modules/pseudoclients/hostserv.cpp:64
-#: modules/pseudoclients/hostserv.cpp:103
+#: modules/pseudoclients/hostserv.cpp:64
+#: modules/pseudoclients/hostserv.cpp:103 modules/commands/hs_on.cpp:35
#, c-format
msgid "Your vhost of %s is now activated."
msgstr "Your vhost of %s is now activated."
-#: modules/commands/hs_on.cpp:35 modules/pseudoclients/hostserv.cpp:62
-#: modules/pseudoclients/hostserv.cpp:101
+#: modules/pseudoclients/hostserv.cpp:62
+#: modules/pseudoclients/hostserv.cpp:101 modules/commands/hs_on.cpp:33
#, c-format
msgid "Your vhost of %s@%s is now activated."
msgstr "Your vhost of %s@%s is now activated."
-#: modules/commands/hs_off.cpp:39
+#: modules/commands/hs_off.cpp:34
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Your vhost was removed and the normal cloaking restored."
@@ -11473,7 +11392,7 @@ msgstr "[Karisik Haberler - %s] %s"
msgid "[account] password"
msgstr "IDENTIFY ÅŸifreniz"
-#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:147
+#: modules/commands/cs_updown.cpp:49 modules/commands/cs_updown.cpp:141
#, fuzzy
msgid "[channel [nick]]"
msgstr "OP #channel [nick]"
@@ -11531,8 +11450,8 @@ msgstr "INFO nick"
msgid "[nickname [REVALIDATE]]"
msgstr ""
-#: modules/commands/ns_info.cpp:20 modules/commands/ns_status.cpp:20
-#: modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_status.cpp:20 modules/commands/ns_alist.cpp:25
+#: modules/commands/ns_info.cpp:20
#, fuzzy
msgid "[nickname]"
msgstr "CHECK nickname"
@@ -11554,7 +11473,7 @@ msgstr "CHANKILL [+expiry] {#channel} [reason]"
msgid "[Hostname hidden]"
msgstr ""
-#: modules/commands/cs_list.cpp:115 modules/commands/ns_list.cpp:112
+#: modules/commands/ns_list.cpp:112 modules/commands/cs_list.cpp:115
msgid "[Suspended]"
msgstr ""
@@ -11562,22 +11481,22 @@ msgstr ""
msgid "[Unconfirmed]"
msgstr ""
-#: modules/commands/hs_request.cpp:214
+#: modules/commands/hs_request.cpp:208
#, fuzzy
msgid "[auto memo] Your requested vHost has been approved."
msgstr "[auto-memo] The memo you sent to %s has been viewed."
-#: modules/commands/hs_request.cpp:268
+#: modules/commands/hs_request.cpp:262
#, fuzzy
msgid "[auto memo] Your requested vHost has been rejected."
msgstr "[auto-memo] The memo you sent to %s has been viewed."
-#: modules/commands/hs_request.cpp:266
+#: modules/commands/hs_request.cpp:260
#, c-format
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr ""
-#: modules/commands/hs_request.cpp:389
+#: modules/commands/hs_request.cpp:384
#, fuzzy, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "%s nickine gönderilen son mesaj iptal edildi."
@@ -11682,12 +11601,12 @@ msgstr ""
msgid "seconds"
msgstr "%s commands:"
-#: modules/commands/hs_request.cpp:216
+#: modules/commands/hs_request.cpp:210
#, fuzzy, c-format
msgid "vHost for %s has been activated."
msgstr "Your vhost of %s is now activated."
-#: modules/commands/hs_request.cpp:273
+#: modules/commands/hs_request.cpp:267
#, fuzzy, c-format
msgid "vHost for %s has been rejected."
msgstr "%s botu silindi."
@@ -11723,26 +11642,7 @@ msgstr "UNBAN kanaladı [name]"
msgid "{nick | channel}"
msgstr "CANCEL {nick | kanaladı}"
-#: modules/commands/ms_send.cpp:25 modules/commands/ms_rsend.cpp:25
+#: modules/commands/ms_rsend.cpp:25 modules/commands/ms_send.cpp:25
#, fuzzy
msgid "{nick | channel} memo-text"
msgstr "SEND {nick | kanaladı} mesaj"
-
-#~ msgid "Exception for %s (#%d) moved to position %d."
-#~ msgstr "%s (#%d) için exception %d pozisyonuyla değiştirildi."
-
-#~ msgid "Old info is equal to the new one."
-#~ msgstr "Eski bilgiler şimdikilerle aynı."
-
-#, fuzzy
-#~ msgid ""
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards. Whenever this command is used, a message\n"
-#~ "including the person who issued the command and the email it was used\n"
-#~ "on will be logged."
-#~ msgstr ""
-#~ "Syntax: GETEMAIL user@emailhost\n"
-#~ "Returns the matching nicks that used given email. Note that\n"
-#~ "you can not use wildcards for either user or emailhost. Whenever\n"
-#~ "this command is used, a message including the person who issued\n"
-#~ "the command and the email it was used on will be logged."
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index 02139a0e5..d48a57234 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -1,17 +1,17 @@
# If using Windows, add the MODULE_COMPILE define
if(WIN32)
add_definitions(-DMODULE_COMPILE)
-endif(WIN32)
+endif()
macro(build_modules SRC)
if(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt")
add_subdirectory("${SRC}")
- else(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt")
+ else()
file(GLOB MODULES_SRCS "${SRC}/*")
foreach(MODULE_SRC ${MODULES_SRCS})
if(IS_DIRECTORY "${MODULE_SRC}")
build_modules("${MODULE_SRC}")
- else(IS_DIRECTORY "${MODULE_SRC}")
+ else()
string(REGEX MATCH "\\.c$" ANOPE18MODULE ${MODULE_SRC})
if(ANOPE18MODULE)
message(FATAL_ERROR "Anope 1 modules are not compatible with Anope 2!\nOffending module: ${MODULE_SRC}")
@@ -22,15 +22,16 @@ macro(build_modules SRC)
file(RELATIVE_PATH FNAME ${SRC} ${MODULE_SRC})
# Convert the real source file extension to have a .so extension
- string(REGEX REPLACE "\\.cpp$" ".so" SO ${FNAME})
- # Temporary variable for the current source's include directories
- set(TEMP_INCLUDES)
- # Calculate the header file dependencies for the given source file
- calculate_depends(${MODULE_SRC} TEMP_INCLUDES)
- # If there were some extra include directories, add them to the list
- if(TEMP_INCLUDES)
- append_to_list(EXTRA_INCLUDES ${TEMP_INCLUDES})
- endif(TEMP_INCLUDES)
+ string(REGEX REPLACE "\\.cpp$" "" SO ${FNAME})
+
+ file(RELATIVE_PATH DEST "${Anope_SOURCE_DIR}/modules" ${SRC})
+ if(DEST)
+ set(TARG "anope_${DEST}.${SO}")
+ set(OUT_NAME "${DEST}_${SO}")
+ else()
+ set(TARG "anope_${SO}")
+ set(OUT_NAME "${SO}")
+ endif()
# Reset linker flags
set(TEMP_LDFLAGS)
@@ -38,133 +39,146 @@ macro(build_modules SRC)
set(TEMP_DEPENDENCIES)
# Calculate the library dependencies for the given source file
calculate_libraries(${MODULE_SRC} TEMP_LDFLAGS TEMP_DEPENDENCIES)
- # Reset has_function
- set(HAS_FUNCTION)
- # Check the function dependencies for the given source file
- check_functions(${MODULE_SRC} HAS_FUNCTION)
- # Only continue if this module has all of the required functions
- if(HAS_FUNCTION)
- # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators
- if(MSVC)
- set(WIN32_MEMORY win32_memory)
- else(MSVC)
- set(WIN32_MEMORY)
- endif(MSVC)
- # Generate the module and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
- add_library(${SO} MODULE ${MODULE_SRC})
+ # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators
+ if(MSVC)
+ set(WIN32_MEMORY win32_memory)
+ else()
+ set(WIN32_MEMORY)
+ endif()
+ # Generate the module and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
+ add_library(${TARG} SHARED ${MODULE_SRC})
+ if(WIN32)
# Windows requires this because it's weird
- if(WIN32)
- set(WIN32_NO_LIBS "/nodefaultlib:\"libcmt.lib\" /OPT:NOREF")
- else(WIN32)
- set(WIN32_NO_LIBS)
- endif(WIN32)
- set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
- add_dependencies(${SO} ${PROGRAM_NAME})
- if(GETTEXT_FOUND)
- add_dependencies(${SO} module_language)
- endif(GETTEXT_FOUND)
- target_link_libraries(${SO} ${TEMP_DEPENDENCIES})
- # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set its version
- if(WIN32)
- target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY})
- set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
- else(WIN32)
- if(APPLE)
- target_link_libraries(${SO} ${PROGRAM_NAME})
- endif(APPLE)
- endif(WIN32)
- # Set the module to be installed to the module directory under the data directory
- install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
- endif(HAS_FUNCTION)
- endif(CPP)
- endif(IS_DIRECTORY "${MODULE_SRC}")
- endforeach(MODULE_SRC ${MODULES_SRCS})
- endif(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt")
-endmacro(build_modules)
+ set(MOD_EXTRA_LDFLAGS "/nodefaultlib:\"libcmt.lib\" /OPT:NOREF")
+ elseif(APPLE)
+ # Mark undefined symbols as having to be looked up at runtime
+ set(MOD_EXTRA_LDFLAGS "-undefined dynamic_lookup")
+ endif()
+ set_target_properties(${TARG} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" OUTPUT_NAME "${OUT_NAME}" LINK_FLAGS "${TEMP_LDFLAGS} ${MOD_EXTRA_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
+ add_dependencies(${TARG} ${PROGRAM_NAME})
+ if(GETTEXT_FOUND)
+ add_dependencies(${TARG} module_language)
+ endif()
+ target_link_libraries(${TARG} ${TEMP_DEPENDENCIES})
+ # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set its version
+ if(WIN32)
+ target_link_libraries(${TARG} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY})
+ set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
+ elseif(APPLE)
+ target_link_libraries(${TARG} ${PROGRAM_NAME})
+ endif()
+ # Set the module to be installed to the module directory under the data directory
+ install(TARGETS ${TARG} DESTINATION ${LIB_DIR}/modules)
+ endif()
+ endif()
+ endforeach()
+ endif()
+endmacro()
+
+macro(build_modules_dependencies SRC)
+ file(GLOB MODULES_SRCS "${SRC}/*")
+ foreach(MODULE_SRC ${MODULES_SRCS})
+ if(NOT IS_DIRECTORY "${MODULE_SRC}")
+ string(REGEX MATCH "\\.cpp$" CPP ${MODULE_SRC})
+ if(CPP)
+ file(RELATIVE_PATH FNAME ${SRC} ${MODULE_SRC})
+ # Convert the real source file extension to have a .so extension
+ string(REGEX REPLACE "\\.cpp$" "" SO ${FNAME})
+
+ file(RELATIVE_PATH DEST "${Anope_SOURCE_DIR}/modules" ${SRC})
+ if(DEST)
+ set(TARG "anope_${DEST}.${SO}")
+ else()
+ set(TARG "anope_${SO}")
+ endif()
+
+ set(DEPS)
+ calculate_dependencies(${MODULE_SRC} DEPS)
+ foreach(DEP ${DEPS})
+ target_link_libraries(${TARG} ${DEP})
+ endforeach()
+ endif()
+ endif()
+ endforeach()
+endmacro()
macro(build_subdir)
file(GLOB_RECURSE MODULES_SUBDIR_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
- sort_list(MODULES_SUBDIR_SRCS)
+ list(SORT MODULES_SUBDIR_SRCS)
- GET_FILENAME_COMPONENT(FOLDER_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
- set(SO "${FOLDER_NAME}.so")
+ file(RELATIVE_PATH DEST "${Anope_SOURCE_DIR}/modules" ${CMAKE_CURRENT_SOURCE_DIR})
+ get_filename_component(DIR_NAME ${DEST} DIRECTORY)
+ get_filename_component(FOLDER_NAME ${DEST} NAME)
+ if(DIR_NAME)
+ set(SO "anope_${DIR_NAME}.${FOLDER_NAME}")
+ else()
+ set(SO "anope_${FOLDER_NAME}")
+ endif()
# Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though)
set_source_files_properties(${MODULES_SUBDIR_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
- set(HAS_FUNCTION TRUE)
-
+ set(DEPS)
# Iterate through the source files in the subdirectory
foreach(SRC ${MODULES_SUBDIR_SRCS})
- if(HAS_FUNCTION)
- # Temporary variable for the current source's include directories
- set(TEMP_INCLUDES)
- # Calculate the header file dependencies for the given source file
- calculate_depends(${SRC} TEMP_INCLUDES)
- # If there were some extra include directories, add them to the list
- if(TEMP_INCLUDES)
- include_directories(${TEMP_INCLUDES})
- endif(TEMP_INCLUDES)
-
- # Reset linker flags
- set(TEMP_LDFLAGS)
- # Reset extra dependencies
- set(TEMP_DEPENDENCIES)
- # Calculate the library dependencies for the given source file
- calculate_libraries(${SRC} SKIP_LIBRARIES MODULE TEMP_LDFLAGS TEMP_DEPENDENCIES)
- # Check the function dependencies for the given source file
- check_functions(${SRC} HAS_FUNCTION)
-
- # Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append
- if(TEMP_DEPENDENCIES)
- append_to_list(SUBDIR_EXTRA_DEPENDS ${TEMP_DEPDENCIES})
- endif(TEMP_DEPENDENCIES)
- endif(HAS_FUNCTION)
- endforeach(SRC ${MODULES_SUBDIR_SRCS})
-
- # Continue if library and function requirements are met
- if(HAS_FUNCTION)
- # Remove duplicates from the linker flags
- if(SUBDIR_LDFLAGS)
- remove_list_duplicates(SUBDIR_LDFLAGS)
- endif(SUBDIR_LDFLAGS)
-
- # Remove duplicates from the extra dependencies
- if(SUBDIR_EXTRA_DEPENDS)
- remove_list_duplicates(SUBDIR_EXTRA_DEPENDS)
- endif(SUBDIR_EXTRA_DEPENDS)
-
- # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators
- if(MSVC)
- set(WIN32_MEMORY win32_memory)
- else(MSVC)
- set(WIN32_MEMORY)
- endif(MSVC)
-
- # Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand
- add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS})
- set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
- add_dependencies(${SO} ${PROGRAM_NAME})
- if(GETTEXT_FOUND)
- add_dependencies(${SO} module_language)
- endif(GETTEXT_FOUND)
- target_link_libraries(${SO} ${SUBDIR_EXTRA_DEPENDS})
- # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
- if(WIN32)
- target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY})
- set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
- else(WIN32)
- if(APPLE)
- target_link_libraries(${SO} ${PROGRAM_NAME})
- endif(APPLE)
- endif(WIN32)
-
- # Set the module to be installed to the module directory under the data directory
- install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
-
- endif(HAS_FUNCTION)
-endmacro(build_subdir)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+ # Reset linker flags
+ set(TEMP_LDFLAGS)
+ # Reset extra dependencies
+ set(TEMP_DEPENDENCIES)
+ # Calculate the library dependencies for the given source file
+ calculate_libraries(${SRC} SKIP_LIBRARIES MODULE TEMP_LDFLAGS TEMP_DEPENDENCIES)
+ calculate_dependencies(${SRC} DEPS)
+
+ # Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append
+ if(TEMP_DEPENDENCIES)
+ append_to_list(SUBDIR_EXTRA_DEPENDS ${TEMP_DEPDENCIES})
+ endif()
+ endforeach()
+
+ # Remove duplicates from the linker flags
+ if(SUBDIR_LDFLAGS)
+ list(REMOVE_DUPLICATES SUBDIR_LDFLAGS)
+ endif()
+
+ # Remove duplicates from the extra dependencies
+ if(SUBDIR_EXTRA_DEPENDS)
+ list(REMOVE_DUPLICATES SUBDIR_EXTRA_DEPENDS)
+ endif()
+
+ # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators
+ if(MSVC)
+ set(WIN32_MEMORY win32_memory)
+ else()
+ set(WIN32_MEMORY)
+ endif()
+
+ if(APPLE)
+ # Mark undefined symbols as having to be looked up at runtime
+ set(MOD_EXTRA_LDFLAGS "-undefined dynamic_lookup")
+ endif(APPLE)
+
+ # Generate the module and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
+ add_library(${SO} SHARED ${MODULES_SUBDIR_SRCS})
+ set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS} ${MOD_EXTRA_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON OUTPUT_NAME "${DIR_NAME}_${FOLDER_NAME}")
+ add_dependencies(${SO} ${PROGRAM_NAME})
+ if(GETTEXT_FOUND)
+ add_dependencies(${SO} module_language)
+ endif()
+ target_link_libraries(${SO} ${SUBDIR_EXTRA_DEPENDS})
+ foreach(DEP ${DEPS})
+ target_link_libraries(${SO} ${DEP})
+ endforeach()
+ # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set its version
+ if(WIN32)
+ target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY})
+ set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
+ elseif(APPLE)
+ target_link_libraries(${SO} ${PROGRAM_NAME})
+ endif()
+
+ install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
+endmacro()
+
build_modules(${CMAKE_CURRENT_SOURCE_DIR})
+build_modules_dependencies(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/botserv/CMakeLists.txt b/modules/botserv/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/botserv/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/botserv/assign.cpp b/modules/botserv/assign.cpp
new file mode 100644
index 000000000..eb6b8da10
--- /dev/null
+++ b/modules/botserv/assign.cpp
@@ -0,0 +1,291 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/info.h"
+
+class CommandBSAssign : public Command
+{
+ public:
+ CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2)
+ {
+ this->SetDesc(_("Assigns a bot to a channel"));
+ this->SetSyntax(_("\037channel\037 \037nickname\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ ServiceBot *bi = ServiceBot::Find(nick, true);
+ if (!bi)
+ {
+ source.Reply(_("Bot \002{0}\002 does not exist."), nick);
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ if (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "ASSIGN", ci->GetName());
+ return;
+ }
+
+ if (ci->HasFieldS("BS_NOBOT"))
+ {
+ source.Reply(_("Access denied. \002{0}\002 may not have a bot assigned to it because a Services Operator has disallowed it."), ci->GetName());
+ return;
+ }
+
+ if (bi->bi->GetOperOnly() && !source.HasPriv("botserv/administration"))
+ {
+ source.Reply(_("Access denied. Bot \002{0}\002 is for operators only."), bi->nick);
+ return;
+ }
+
+ if (ci->GetBot() == bi)
+ {
+ source.Reply(_("Bot \002{0}\002 is already assigned to \002{1}\002."), ci->GetBot()->nick, ci->GetName());
+ 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{0}\002 has been assigned to \002{1}\002."), bi->nick, ci->GetName());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Assigns the bot \037nickname\037 to \037channel\037."
+ " You can then configure the bot for the channel so it fits your needs.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."
+ "\n"
+ "Example:\n"
+ " {command} #anope Botox\n"
+ " Assigns the bot Botox to #anope.\n"),
+ "ASSIGN", "command"_kw = source.command);
+ return true;
+ }
+};
+
+class CommandBSUnassign : 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<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, bot assignment is temporarily disabled."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ if (!source.HasPriv("botserv/administration") && !access.HasPriv("ASSIGN"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "ASSIGN", ci->GetName());
+ return;
+ }
+
+ if (!ci->GetBot())
+ {
+ source.Reply(_("There is no bot assigned to \002{0}\002."), ci->GetName());
+ return;
+ }
+
+ if (ci->HasFieldS("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->GetBot()->nick;
+
+ ServiceBot *bi = ci->GetBot();
+ bi->UnAssign(source.GetUser(), ci);
+ source.Reply(_("Bot \002{0}\002 has been unassigned from \002{1}\002."), bi->nick, ci->GetName());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Unassigns a bot from \037channel\037."
+ "Bot configuration is kept, so you will always be able to reassign a bot later without losing your settings.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."
+ "\n"
+ "Example:\n"
+ " {command} #anope\n"
+ " Unassigns the current bot from #anope.\n"),
+ "ASSIGN", "command"_kw = source.command);
+ return true;
+ }
+};
+
+class CommandBSSetNoBot : 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<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &value = params[1];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (value.equals_ci("ON"))
+ {
+ Log(LOG_ADMIN, source, this, ci) << "to enable nobot";
+
+ ci->SetS<bool>("BS_NOBOT", true);
+ if (ci->GetBot())
+ ci->GetBot()->UnAssign(source.GetUser(), ci);
+ source.Reply(_("No-bot mode is now \002on\002 for \002{0}\002."), ci->GetName());
+ }
+ else if (value.equals_ci("OFF"))
+ {
+ Log(LOG_ADMIN, source, this, ci) << "to disable nobot";
+
+ ci->UnsetS<bool>("BS_NOBOT");
+ source.Reply(_("No-bot mode is now \002off\002 for \002{0}\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, source.command);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("If no-bot is set on a channel, then the channel will be unabled to have a bot assigned to it."
+ " If a bot is already assigned to the channel, it is unassigned automatically when no-bot is enabled."
+ "\n"
+ "Example:\n"
+ " {command} #anope on\n"
+ " Prevents a service bot from being assigned to #anope.\n"),
+ "command"_kw = source.command);
+ return true;
+ }
+};
+
+class BSAssign : public Module
+ , public EventHook<Event::Invite>
+ , public EventHook<Event::ServiceBotEvent>
+{
+ Serialize::Field<BotInfo, bool> nobot;
+
+ CommandBSAssign commandbsassign;
+ CommandBSUnassign commandbsunassign;
+ CommandBSSetNoBot commandbssetnobot;
+
+ public:
+ BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::Invite>(this)
+ , EventHook<Event::ServiceBotEvent>(this)
+
+ , nobot(this, "BS_NOBOT")
+
+ , commandbsassign(this)
+ , commandbsunassign(this)
+ , commandbssetnobot(this)
+ {
+ }
+
+ void OnInvite(User *source, Channel *c, User *targ) override
+ {
+ ServiceBot *bi;
+ if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = ServiceBot::Find(targ->nick, true)))
+ return;
+
+ ChanServ::AccessGroup access = c->ci->AccessFor(source);
+ if (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration"))
+ {
+ targ->SendMessage(bi, _("Access denied. You do not have privilege \002ASSIGN\002 on \002{0}\002."), c->ci->GetName());
+ return;
+ }
+
+ if (nobot.HasExt(c->ci))
+ {
+ targ->SendMessage(bi, _("Access denied. \002{0}\002 may not have a bot assigned to it because a Services Operator has disallowed it."), c->ci->GetName());
+ return;
+ }
+
+ if (bi->bi->GetOperOnly() && !source->HasPriv("botserv/administration"))
+ {
+ targ->SendMessage(bi, _("Access denied. Bot \002{0}\002 is for operators only."), bi->nick);
+ return;
+ }
+
+ if (c->ci->GetBot() == bi)
+ {
+ targ->SendMessage(bi, _("Bot \002{0}\002 is already assigned to \002{1}\002."), bi->nick, c->ci->GetName());
+ return;
+ }
+
+ bi->Assign(source, c->ci);
+ targ->SendMessage(bi, _("Bot \002{0}\002 has been assigned to \002{1}\002."), bi->nick, c->ci->GetName());
+ }
+
+ void OnServiceBot(CommandSource &source, ServiceBot *bi, ChanServ::Channel *ci, InfoFormatter &info) override
+ {
+ if (nobot.HasExt(ci))
+ info.AddOption(_("No bot"));
+ }
+};
+
+MODULE_INIT(BSAssign)
diff --git a/modules/botserv/autoassign.cpp b/modules/botserv/autoassign.cpp
new file mode 100644
index 000000000..3bb6dce64
--- /dev/null
+++ b/modules/botserv/autoassign.cpp
@@ -0,0 +1,48 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class BSAutoAssign : public Module
+ , public EventHook<Event::ChanRegistered>
+{
+ public:
+ BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanRegistered>(this)
+ {
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ const Anope::string &bot = Config->GetModule(this)->Get<Anope::string>("bot");
+ if (bot.empty())
+ return;
+
+ ServiceBot *bi = ServiceBot::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/badwords.cpp b/modules/botserv/badwords.cpp
new file mode 100644
index 000000000..998ccc7f8
--- /dev/null
+++ b/modules/botserv/badwords.cpp
@@ -0,0 +1,472 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/badwords.h"
+
+class BadWordImpl : public BadWord
+{
+ friend class BadWordsType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string word;
+ BadWordType type;
+
+ public:
+ BadWordImpl(Serialize::TypeBase *type) : BadWord(type) { }
+ BadWordImpl(Serialize::TypeBase *type, Serialize::ID id) : BadWord(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *c) override;
+
+ Anope::string GetWord() override;
+ void SetWord(const Anope::string &w) override;
+
+ BadWordType GetType() override;
+ void SetType(const BadWordType &t) override;
+};
+
+class BadWordsType : public Serialize::Type<BadWordImpl>
+{
+ public:
+ Serialize::ObjectField<BadWordImpl, ChanServ::Channel *> channel;
+ Serialize::Field<BadWordImpl, Anope::string> word;
+ Serialize::Field<BadWordImpl, BadWordType> type;
+
+ BadWordsType(Module *me) : Serialize::Type<BadWordImpl>(me)
+ , channel(this, "ci", &BadWordImpl::channel, true)
+ , word(this, "word", &BadWordImpl::word)
+ , type(this, "type", &BadWordImpl::type)
+ {
+ }
+};
+
+ChanServ::Channel *BadWordImpl::GetChannel()
+{
+ return Get(&BadWordsType::channel);
+}
+
+void BadWordImpl::SetChannel(ChanServ::Channel *c)
+{
+ Set(&BadWordsType::channel, c);
+}
+
+Anope::string BadWordImpl::GetWord()
+{
+ return Get(&BadWordsType::word);
+}
+
+void BadWordImpl::SetWord(const Anope::string &w)
+{
+ Set(&BadWordsType::word, w);
+}
+
+BadWordType BadWordImpl::GetType()
+{
+ return Get(&BadWordsType::type);
+}
+
+void BadWordImpl::SetType(const BadWordType &t)
+{
+ Set(&BadWordsType::type, t);
+}
+
+struct BadWordsImpl : BadWords
+{
+ BadWordsImpl(Module *me) : BadWords(me) { }
+
+ BadWord* AddBadWord(ChanServ::Channel *ci, const Anope::string &word, BadWordType type) override
+ {
+ BadWord *bw = Serialize::New<BadWord *>();
+ bw->SetChannel(ci);
+ bw->SetWord(word);
+ bw->SetType(type);
+
+ EventManager::Get()->Dispatch(&Event::BadWordEvents::OnBadWordAdd, ci, bw);
+
+ return bw;
+ }
+
+ std::vector<BadWord *> GetBadWords(ChanServ::Channel *ci) override
+ {
+ return ci->GetRefs<BadWord *>();
+ }
+
+ BadWord* GetBadWord(ChanServ::Channel *ci, unsigned index) override
+ {
+ auto bw = GetBadWords(ci);
+ return index < bw.size() ? bw[index] : nullptr;
+ }
+
+ unsigned GetBadWordCount(ChanServ::Channel *ci) override
+ {
+ return GetBadWords(ci).size();
+ }
+
+ void EraseBadWord(ChanServ::Channel *ci, unsigned index) override
+ {
+ auto bws = GetBadWords(ci);
+ if (index >= bws.size())
+ return;
+
+ BadWord *bw = bws[index];
+ EventManager::Get()->Dispatch(&Event::BadWordEvents::OnBadWordDel, ci, bw);
+
+ delete bw;
+ }
+
+ void ClearBadWords(ChanServ::Channel *ci) override
+ {
+ for (BadWord *bw : GetBadWords(ci))
+ delete bw;
+ }
+};
+
+class CommandBSBadwords : public Command
+{
+ ServiceReference<BadWords> badwords;
+
+ void DoList(CommandSource &source, ChanServ::Channel *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());
+
+ list.AddColumn(_("Number")).AddColumn(_("Word")).AddColumn(_("Type"));
+
+ if (!badwords->GetBadWordCount(ci))
+ {
+ source.Reply(_("The bad word list of \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(word, false,
+ [&](unsigned int num)
+ {
+ if (!num || num > badwords->GetBadWordCount(ci))
+ return;
+
+ BadWord *b = badwords->GetBadWord(ci, num - 1);
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(num);
+ entry["Word"] = b->GetWord();
+ entry["Type"] = b->GetType() == BW_SINGLE ? "(SINGLE)" : (b->GetType() == BW_START ? "(START)" : (b->GetType() == BW_END ? "(END)" : ""));
+ list.AddEntry(entry);
+ },
+ [](){});
+ }
+ else
+ {
+ for (unsigned i = 0, end = badwords->GetBadWordCount(ci); i < end; ++i)
+ {
+ BadWord *b = badwords->GetBadWord(ci, i);
+
+ if (!word.empty() && !Anope::Match(b->GetWord(), word))
+ continue;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Word"] = b->GetWord();
+ entry["Type"] = b->GetType() == BW_SINGLE ? "(SINGLE)" : (b->GetType() == BW_START ? "(START)" : (b->GetType() == BW_END ? "(END)" : ""));
+ list.AddEntry(entry);
+ }
+ }
+
+ if (list.IsEmpty())
+ {
+ source.Reply(_("No matching entries on the bad word list of \002{0}\002."), ci->GetName());
+ return;
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("Bad words list for \002{0}\002:"), ci->GetName());
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of bad words list."));
+ }
+
+ void DoAdd(CommandSource &source, ChanServ::Channel *ci, const Anope::string &word)
+ {
+ size_t pos = word.rfind(' ');
+ BadWordType bwtype = BW_ANY;
+ Anope::string realword = word;
+
+ 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<unsigned>("badwordsmax");
+ if (badwords->GetBadWordCount(ci) >= badwordsmax)
+ {
+ source.Reply(_("Sorry, you can only have \002{0}\002 bad words entries on a channel."), badwordsmax);
+ return;
+ }
+
+ bool casesensitive = Config->GetModule(this->module)->Get<bool>("casesensitive");
+
+ for (BadWord *bw : badwords->GetBadWords(ci))
+ if ((casesensitive && realword.equals_cs(bw->GetWord())) || (!casesensitive && realword.equals_ci(bw->GetWord())))
+ {
+ source.Reply(_("\002{0}\002 already exists in \002{1}\002 bad words list."), bw->GetWord(), ci->GetName());
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword;
+ badwords->AddBadWord(ci, realword, bwtype);
+
+ source.Reply(_("\002{0}\002 added to \002{1}\002 bad words list."), realword, ci->GetName());
+ }
+
+ void DoDelete(CommandSource &source, ChanServ::Channel *ci, const Anope::string &word)
+ {
+ if (!badwords->GetBadWordCount(ci))
+ {
+ source.Reply(_("Bad word list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
+
+ /* 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)
+ {
+ unsigned int deleted = 0;
+
+ NumberList(word, true,
+ [&](unsigned int num)
+ {
+ if (!num || num > badwords->GetBadWordCount(ci))
+ return;
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "DEL " << badwords->GetBadWord(ci, num - 1)->GetWord();
+ ++deleted;
+ badwords->EraseBadWord(ci, num - 1);
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("No matching entries on the bad word list of \002{0}\002."), ci->GetName());
+ else if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from bad word list of \002{0}\002."), ci->GetName());
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from the bad word list of \002{1}\002."), deleted, ci->GetName());
+ });
+ }
+ else
+ {
+ unsigned i, end;
+ BadWord *bw;
+
+ for (i = 0, end = badwords->GetBadWordCount(ci); i < end; ++i)
+ {
+ bw = badwords->GetBadWord(ci, i);
+
+ if (word.equals_ci(bw->GetWord()))
+ break;
+ }
+
+ if (i == end)
+ {
+ source.Reply(_("\002{0}\002 was not found on the bad word list of \002{1}\002."), word, ci->GetName());
+ return;
+ }
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "DEL " << bw->GetWord();
+
+ source.Reply(_("\002{0}\002 deleted from \002{1}\002 bad words list."), bw->GetWord(), ci->GetName());
+
+ bw->Delete();
+ }
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "CLEAR";
+
+ badwords->ClearBadWords(ci);
+ 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<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ 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;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("BADWORDS") && (!need_args || !source.HasPriv("botserv/administration")))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "BADWORDS", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, bad words list modification is temporarily disabled."));
+ return;
+ }
+
+ if (cmd.equals_ci("ADD"))
+ this->DoAdd(source, ci, word);
+ else if (cmd.equals_ci("DEL"))
+ this->DoDelete(source, ci, word);
+ else if (cmd.equals_ci("LIST"))
+ this->DoList(source, ci, word);
+ else if (cmd.equals_ci("CLEAR"))
+ this->DoClear(source, ci);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("Adds \037word\037 to the bad words list for \037channel\037. If \002SINGLE\002 is specified then the user must say the enire word for it to be considered a match."
+ " If \002START\002 is specified then the user only must say a word that starts with \037word\037."
+ " Likewise if \002END\002 is specified then the user must only say a word that ends with \037word\037."
+ " If no argument is specified, then any word which contains \037word\037 will be considered a match.\n"
+ "\n"
+ "Examples:\n"
+ " {command} #anope ADD raw SINGLE\n"
+ " Adds the bad word \"raw\" to the bad word list of #anope."),
+ "command"_kw = source.command);
+ }
+ else if (subcommand.equals_ci("DEL"))
+ {
+ source.Reply(_("Removes \037word\037 from the bad words list for \037channel\037. If a number or list of numbers is given, those entries are deleted.\n"
+ "\n"
+ "Examples:\n"
+ " {command} #anope DEL raw\n"
+ " Removes the bad word \"raw\" from the bad word list of #anope.\n"
+ "\n"
+ " {command} #anope DEL 2-5,7-9\n"
+ " Removes bad words entries numbered 2 through 5 and 7 through 9 on #anope."),
+ "command"_kw = source.command);
+
+ }
+ else if (subcommand.equals_ci("LIST"))
+ {
+ source.Reply(_("Lists the badwords for \037channel\037."
+ " If a wildcard mask is given, only those entries matching the mask are displayed."
+ " If a list of entry numbers is given, only those entries are shown.\n"
+ "\n"
+ "Examples:\n"
+ " {command} #anope LIST\n"
+ " Lists the bad words for #anope.\n"
+ "\n"
+ " {command} #anope LIST 2-5,7-9\n"
+ " Lists bad words entries numbered 2 thorough 5 and 7 through 9 on #anope."),
+ "command"_kw = source.command);
+ }
+ else if (subcommand.equals_ci("CLEAR"))
+ {
+ source.Reply(_("Clears the bad words for \037channel\037."
+ "\n"
+ "\n"
+ "Example:\n"
+ " {command} #anope CLEAR\n"
+ " Clears the bad word list for #anope."),
+ "command"_kw = source.command);
+ }
+ else
+ {
+ source.Reply(_("Maintains the bad words list for a channel."
+ " When a word on the bad words list is said, action may be taken against the offending user.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "BADWORDS");
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("\n"
+ "For help configuring the bad word kicker use \002{msg}{service} HELP KICK BADWORDS\002.\n"//XXX
+ "\n"
+ "The \002ADD\002 command adds \037word\037 to the badwords list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037word\037 from the badwords list.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002CLEAR\002 commands show and clear the bad words list, respectively.\n"
+ "\002{msg}{service} {help} {command} LIST\002 and \002{msg}{service} {help} {command} CLEAR\002 for more information.\n"),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "command"_kw = source.command, "help"_kw = help->cname);
+ }
+ return true;
+ }
+};
+
+class BSBadwords : public Module
+{
+ CommandBSBadwords commandbsbadwords;
+ BadWordsImpl badwords;
+ BadWordsType bwtype;
+
+ public:
+ BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandbsbadwords(this)
+ , badwords(this)
+ , bwtype(this)
+ {
+ }
+};
+
+MODULE_INIT(BSBadwords)
diff --git a/modules/botserv/bot.cpp b/modules/botserv/bot.cpp
new file mode 100644
index 000000000..c93c4cf50
--- /dev/null
+++ b/modules/botserv/bot.cpp
@@ -0,0 +1,427 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/bot.h"
+
+class CommandBSBot : public Command
+{
+ void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ 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 (ServiceBot::Find(nick, true))
+ {
+ source.Reply(_("Bot \002{0}\002 already exists."), nick);
+ return;
+ }
+
+ Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
+
+ if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
+ {
+ source.Reply(_("Bot nicks may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("nicklen"));
+ return;
+ }
+
+ if (user.length() > networkinfo->Get<unsigned>("userlen"))
+ {
+ source.Reply(_("Bot idents may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("userlen"));
+ return;
+ }
+
+ if (host.length() > networkinfo->Get<unsigned>("hostlen"))
+ {
+ source.Reply(_("Bot hosts may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("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
+ */
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na)
+ {
+ source.Reply(_("\002{0}\002 is already registered!"), na->GetNick());
+ return;
+ }
+
+ User *targ = User::Find(nick, true);
+ if (targ)
+ {
+ source.Reply(_("\002{0}\002 is currently in use."), targ->nick);
+ return;
+ }
+
+ ServiceBot *bi = new ServiceBot(nick, user, host, real);
+
+ Log(LOG_ADMIN, source, this) << "ADD " << bi->GetMask() << " " << bi->realname;
+
+ source.Reply(_("\002{0}!{1}@{2}\002 (\002{3}\002) added to the bot list."), bi->nick, bi->GetIdent(), bi->host, bi->realname);
+
+ EventManager::Get()->Dispatch(&Event::BotCreate::OnBotCreate, bi);
+ }
+
+ 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] : "";
+ 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;
+ }
+
+ ServiceBot *bi = ServiceBot::Find(oldnick, true);
+ if (!bi)
+ {
+ source.Reply(_("Bot \002{0}\002 does not exist."), oldnick);
+ return;
+ }
+
+ if (bi->bi->conf)
+ {
+ source.Reply(_("Bot \002{0}\002 is not changeable because it is configured in services configuration."), bi->nick.c_str());
+ return;
+ }
+
+ Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
+
+ if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
+ {
+ source.Reply(_("Bot nicknames may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("nicklen"));
+ return;
+ }
+
+ if (user.length() > networkinfo->Get<unsigned>("userlen"))
+ {
+ source.Reply(_("Bot usernames may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("userlen"));
+ return;
+ }
+
+ if (host.length() > networkinfo->Get<unsigned>("hostlen"))
+ {
+ source.Reply(_("Bot hostnames may only be \002{0}\002 characters long."), networkinfo->Get<unsigned>("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()))
+ && (host.empty() || host.equals_cs(bi->host))
+ && (real.empty() || real.equals_cs(bi->realname)))
+ {
+ source.Reply(_("There is no difference between the current settings and the new settings."));
+ return;
+ }
+
+ if (!IRCD->IsNickValid(nick))
+ {
+ source.Reply(_("Bot nicknames may only contain valid nickname characters."));
+ return;
+ }
+
+ if (!user.empty() && !IRCD->IsIdentValid(user))
+ {
+ source.Reply(_("Bot uesrnames may only contain valid username characters."));
+ return;
+ }
+
+ if (!host.empty() && !IRCD->IsHostValid(host))
+ {
+ source.Reply(_("Bot hostnames may only contain valid hostname characters."));
+ return;
+ }
+
+ ServiceBot *newbi = ServiceBot::Find(nick, true);
+ if (newbi && bi != newbi)
+ {
+ source.Reply(_("Bot \002{0}\002 already exists."), newbi->nick);
+ return;
+ }
+
+ User *target = User::Find(nick, true);
+ if (target)
+ {
+ source.Reply(_("\002{0}\002 is currently in use."), target->nick);
+ 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
+ */
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na)
+ {
+ source.Reply(_("\002{0}\002 is already registered."), na->GetNick());
+ 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);
+ bi->bi->SetNick(nick);
+ }
+
+ if (!user.equals_cs(bi->GetIdent()))
+ {
+ bi->SetIdent(user);
+ bi->bi->SetUser(user);
+ }
+ if (!host.equals_cs(bi->host))
+ {
+ bi->host = host;
+ bi->bi->SetHost(host);
+ }
+ if (real.equals_cs(bi->realname))
+ {
+ bi->realname = real;
+ bi->bi->SetRealName(real);
+ }
+
+ if (!user.empty())
+ bi->OnKill();
+
+ source.Reply(_("Bot \002{0}\002 has been changed to \002{1}!{2}@{3}\002 (\002{4}\002)."), oldnick, bi->nick, bi->GetIdent(), bi->host, bi->realname);
+ Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
+
+ EventManager::Get()->Dispatch(&Event::BotChange::OnBotChange, bi);
+ }
+
+ void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &nick = params[1];
+
+ if (nick.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ ServiceBot *bi = ServiceBot::Find(nick, true);
+ if (!bi)
+ {
+ source.Reply(_("Bot \002{0}\002 does not exist."), nick);
+ return;
+ }
+
+ if (bi->bi->conf)
+ {
+ source.Reply(_("Bot \002{0}\002 is can not be deleted because it is configured in services configuration."), bi->nick);
+ return;
+ }
+
+ EventManager::Get()->Dispatch(&Event::BotDelete::OnBotDelete, bi);
+
+ Log(LOG_ADMIN, source, this) << "DEL " << bi->nick;
+
+ source.Reply(_("Bot \002{0}\002 has been deleted."), bi->nick);
+ delete bi;
+ }
+
+ public:
+ CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6)
+ {
+ this->SetDesc(_("Maintains network bot list"));
+ this->SetSyntax(_("\002ADD \037nicknae\037 \037username\037 \037hostname\037 \037realname\037\002"));
+ this->SetSyntax(_("\002CHANGE \037oldnickname\037 \037newnickname\037 [\037username\037 [\037hostname\037 [\037realname\037]]]\002"));
+ this->SetSyntax(_("\002DEL \037nickname\037\002"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ if (cmd.equals_ci("ADD"))
+ {
+ if (!source.HasCommand("botserv/bot/add"))
+ {
+ source.Reply(_("Access denied. You do not have access to the operator command \002{0}\002."), "botserv/bot/add");
+ return;
+ }
+
+ // ADD nick user host real - 5
+ if (params.size() < 5)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ std::vector<Anope::string> 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];
+
+ 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. You do not have access to the operator command \002{0}\002."), "botserv/bot/change");
+ return;
+ }
+
+ if (params.size() < 3)
+ {
+ this->OnSyntaxError(source, "CHANGE");
+ return;
+ }
+
+ this->DoChange(source, params);
+ }
+ else if (cmd.equals_ci("DEL"))
+ {
+ // DEL nick
+ if (!source.HasCommand("botserv/bot/del"))
+ {
+ source.Reply(_("Access denied. You do not have access to the operator command \002{0}\002."), "botserv/bot/del");
+ return;
+ }
+
+ if (params.size() < 1)
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ this->DoDel(source, params);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ source.Reply(_("\002{command} ADD\002 adds a bot with the given \037nickname\037, \037username\037, \037hostname\037 and \037realname\037."
+ " You can not create a bot with a nickname that is currently registered. If an unregistered user is currently using the nick, they will be killed.\n"
+ " Once a bot is created, users will be able to assign the bot to their channels. This command requires the opererator privilege for command \002{0}\002."
+ "\n"
+ "Example:\n"
+ " {command} ADD Botox Botox services.anope.org Botox\n"
+ " Adds a service bot with nickname \"Botox\", username \"Botox\", hostname \"services.anope.org\", and realname \"Botox\" to the bot list."),
+ "botserv/bot/add", "command"_kw = source.command);
+ else if (subcommand.equals_ci("CHANGE"))
+ source.Reply(_("\002{command} CHANGE\002 allows changing the \037nickname\037, \037username\037, \037hostname\037 and \037realname\037 of bot \037oldnickname\037."
+ " If a new username, hostname, or realname is specified, then the bot \037nickname\037 will quit and rejoin all of its channels using the new mask."
+ " Otherwise, the bot simply change nick to \037newnickname\037. All settings on the bot, such as channels and no-bot, are retained."
+ " This command requires the operator privilege for command \002{0}\002."
+ "\n"
+ "Example:\n"
+ " {command} CHANGE Botox peer connection reset.by peer\n"
+ " Renames the bot \"Botox\" to \"peer\" with the given username, hostname, and realname."),
+ "botserv/bot/change", "command"_kw = source.command);
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("\002{command} DEL\002 removes the bot \037nickname\037 from the bot list. The bot will quit from any channels it is in, and will not be replaced."
+ " This command requires the operator privilege for command \002{0}\002.\n"
+ "\n"
+ "Example:\n"
+ " {command} DEL peer\n"
+ " Removes the bot \"peer\" from the bot list."),
+ "botserv/bot/del", "command"_kw = source.command);
+ else
+ {
+ source.Reply(_("Allows Services Operators to create, modify, and delete bots that users will be able to use on their channels."));
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("\n"
+ "The \002ADD\002 command adds a bot with the given \037nickname\037, \037username\037, \037hostname\037 and \037realname\037 to the bot list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002CHANGE\002 command allows changing the \037nickname\037, \037username\037, \037hostname\037 and \037realname\037 of bot \037oldnickname\037.\n"
+ "\002{msg}{service} {help} {command} CHANGE\002 for more information.\n"
+ "\n"
+ "The \002{command} DEL\002 removes the bot \037nickname\037 from the bot list.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information."),
+ "msg"_kw = Config->StrictPrivmsg, "help"_kw = help->cname, "command"_kw = source.command);
+ }
+ return true;
+ }
+};
+
+class BSBot : public Module
+{
+ CommandBSBot commandbsbot;
+
+ public:
+ BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandbsbot(this)
+ {
+
+ }
+};
+
+MODULE_INIT(BSBot)
diff --git a/modules/botserv/botlist.cpp b/modules/botserv/botlist.cpp
new file mode 100644
index 000000000..6c12a2c59
--- /dev/null
+++ b/modules/botserv/botlist.cpp
@@ -0,0 +1,100 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandBSBotList : public Command
+{
+ public:
+ CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
+ {
+ this->SetDesc(_("Lists available bots"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ unsigned count = 0;
+ ListFormatter list(source.GetAccount());
+
+ list.AddColumn(_("Nick")).AddColumn(_("Mask"));
+
+ for (BotInfo *bi : Serialize::GetObjects<BotInfo *>())
+ {
+ if (source.HasPriv("botserv/administration") || !bi->GetOperOnly())
+ {
+ ++count;
+ ListFormatter::ListEntry entry;
+ entry["Nick"] = (bi->GetOperOnly() ? "* " : "") + bi->GetNick();
+ entry["Mask"] = bi->GetUser() + "@" + bi->GetHost();
+ list.AddEntry(entry);
+ }
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ if (!count)
+ {
+ source.Reply(_("There are no bots available"));
+ return;
+ }
+
+ source.Reply(_("Bot list:"));
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("{0} bots available."), count);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ ServiceBot *bi;
+ Anope::string name;
+ Command::FindCommandFromService("botserv/assign", bi, name);
+ if (!bi)
+ return false;
+
+ source.Reply(_("Lists all available bots. You may use the \002{msg}{service} {assign}\002 command to assign a bot to your channel."
+ "The bot names are vanity; they all proviate the same commands and features."),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = bi->nick, "assign"_kw = name);
+ if (source.HasPriv("botserv/administration"))
+ source.Reply(_("Bots prefixed by a * are reserved for Services Operators with the privilege \002{0}\002."),
+ "botserv/administration");
+ source.Reply(_("\n"
+ "Example:\n"
+ " {command} BOTLIST"),
+ "command"_kw = source.command);
+ return true;
+ }
+};
+
+class BSBotList : public Module
+{
+ CommandBSBotList commandbsbotlist;
+
+ public:
+ BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandbsbotlist(this)
+ {
+
+ }
+};
+
+MODULE_INIT(BSBotList)
diff --git a/modules/botserv/control.cpp b/modules/botserv/control.cpp
new file mode 100644
index 000000000..86b4ed829
--- /dev/null
+++ b/modules/botserv/control.cpp
@@ -0,0 +1,176 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandBSSay : public Command
+{
+ public:
+ CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2)
+ {
+ this->SetDesc(_("Makes the bot say the specified text on the specified channel"));
+ this->SetSyntax(_("\037channel\037 \037text\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &text = params[1];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SAY", ci->GetName());
+ return;
+ }
+
+ if (!ci->GetBot())
+ {
+ source.Reply(_("There is no bot assigned to \002{0}\002. One must be assigned to the channel before this command can be used."), ci->GetName());
+ ServiceBot *bi;
+ Anope::string name;
+ Command::FindCommandFromService("botserv/assign", bi, name);
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (bi && help)
+ source.Reply(_("See \002{msg}{service} {help} {command}\002 for information on assigning bots."),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = bi->nick, "help"_kw = help->cname, "command"_kw = name);
+ return;
+ }
+
+ if (!ci->c || !ci->c->FindUser(ci->GetBot()))
+ {
+ source.Reply(_("Bot \002{0}\002 is not on channel \002{1}\002."), ci->GetBot()->nick, ci->GetName());
+ return;
+ }
+
+ if (text[0] == '\001')
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ IRCD->SendPrivmsg(ci->GetBot(), ci->GetName(), "%s", text.c_str());
+ ci->GetBot()->lastmsg = Anope::CurTime;
+
+ bool override = !source.AccessFor(ci).HasPriv("SAY");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << text;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Makes the bot say the given \037text\037 on \037channel\037.\n"
+ "\n"
+ "Example:\n"
+ " {command} #anope mmm pie\n"
+ " Makes the assigned service bot say \"mmm pie\"."));
+ 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) override
+ {
+ const Anope::string &chan = params[0];
+ Anope::string message = params[1];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SAY", ci->GetName());
+ return;
+ }
+
+ if (!ci->GetBot())
+ {
+ source.Reply(_("There is no bot assigned to \002{0}\002. One must be assigned to the channel before this command can be used."), ci->GetName());
+ ServiceBot *bi;
+ Anope::string name;
+ Command::FindCommandFromService("botserv/assign", bi, name);
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (bi && help)
+ source.Reply(_("See \002{msg}{service} {help} {command}\002 for information on assigning bots."),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = bi->nick, "help"_kw = help->cname, "command"_kw = name);
+ return;
+ }
+
+ if (!ci->c || !ci->c->FindUser(ci->GetBot()))
+ {
+ source.Reply(_("Bot \002{0}\002 is not on channel \002{1}\002."), ci->GetBot()->nick, ci->GetName());
+ return;
+ }
+
+ message = message.replace_all_cs("\1", "");
+ if (message.empty())
+ return;
+
+ IRCD->SendAction(ci->GetBot(), ci->GetName(), "%s", message.c_str());
+ ci->GetBot()->lastmsg = Anope::CurTime;
+
+ bool override = !source.AccessFor(ci).HasPriv("SAY");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << message;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Makes the assigned bot do the equivalent of a \"/me\" command on \037channel\037 using the given \037text\037.\n"
+ "\n"
+ "Example:\n"
+ " {command} #anope slaps Cronus\n"
+ " Shows the assigned service bot \"slapping\" Cronus."),
+ "command"_kw = source.command);
+ return true;
+ }
+};
+
+class BSControl : public Module
+{
+ CommandBSSay commandbssay;
+ CommandBSAct commandbsact;
+
+ public:
+ BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandbssay(this), commandbsact(this)
+ {
+
+ }
+};
+
+MODULE_INIT(BSControl)
diff --git a/modules/botserv/info.cpp b/modules/botserv/info.cpp
new file mode 100644
index 000000000..94b1bbbd7
--- /dev/null
+++ b/modules/botserv/info.cpp
@@ -0,0 +1,118 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/info.h"
+
+class CommandBSInfo : public Command
+{
+ public:
+ CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
+ {
+ this->SetSyntax(_("{\037channel\037 | \037nickname\037}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &query = params[0];
+
+ ServiceBot *bi = ServiceBot::Find(query, true);
+ ChanServ::Channel *ci = ChanServ::Find(query);
+ InfoFormatter info(source.nc);
+
+ if (bi)
+ {
+ source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
+ info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
+ info[_("Real name")] = bi->realname;
+ info[_("Created")] = Anope::strftime(bi->bi->GetCreated(), source.GetAccount());
+ info[_("Options")] = bi->bi->GetOperOnly() ? _("Private") : _("None");
+ info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
+
+ EventManager::Get()->Dispatch(&Event::ServiceBotEvent::OnServiceBot, source, bi, ci, info);
+
+ std::vector<Anope::string> replies;
+ info.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ if (source.HasPriv("botserv/administration"))
+ {
+ Anope::string buf;
+ for (ChanServ::Channel *ci2 : bi->GetChannels())
+ buf += " " + ci2->GetName();
+ source.Reply(buf);
+ }
+
+ }
+ else if (ci)
+ {
+ if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "INFO", ci->GetName());
+ return;
+ }
+
+ source.Reply(_("Information for channel \002{0}\002:"), ci->GetName());
+ info[_("Bot nick")] = ci->GetBot() ? ci->GetBot()->nick : _("not assigned yet");
+
+ Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
+ Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
+
+ EventManager::Get()->Dispatch(&Event::ServiceBotEvent::OnServiceBot, source, bi, ci, info);
+
+ std::vector<Anope::string> replies;
+ info.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ else
+ source.Reply(_("\002{0}\002 is not a valid bot or registered channel."), query);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows you to see {0} information about a channel or a bot."
+ " If the parameter is a channel, then you'll get information such as enabled kickers."
+ " If the parameter is a bot nickname, you'll get information about a bot, such as creation time and number of channels it is on."),
+ source.service->nick);
+ return true;
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str());
+ }
+};
+
+class BSInfo : public Module
+{
+ CommandBSInfo commandbsinfo;
+
+ public:
+ BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandbsinfo(this)
+ {
+
+ }
+};
+
+MODULE_INIT(BSInfo)
diff --git a/modules/botserv/kick.cpp b/modules/botserv/kick.cpp
new file mode 100644
index 000000000..3d56ddd21
--- /dev/null
+++ b/modules/botserv/kick.cpp
@@ -0,0 +1,1743 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/kick.h"
+#include "modules/botserv/badwords.h"
+#include "modules/botserv/info.h"
+
+static Module *me;
+
+enum TTBType
+{
+ TTB_BOLDS,
+ TTB_COLORS,
+ TTB_REVERSES,
+ TTB_UNDERLINES,
+ TTB_BADWORDS,
+ TTB_CAPS,
+ TTB_FLOOD,
+ TTB_REPEAT,
+ TTB_ITALICS,
+ TTB_AMSGS,
+ TTB_SIZE
+};
+
+class KickerDataImpl : public KickerData
+{
+ friend class KickerDataType;
+
+ ChanServ::Channel *channel = nullptr;
+
+ bool amsgs = false,
+ badwords = false,
+ bolds = false,
+ caps = false,
+ colors = false,
+ flood = false,
+ italics = false,
+ repeat = false,
+ reverses = false,
+ underlines = false;
+
+ int16_t ttb_bolds = 0,
+ ttb_colors = 0,
+ ttb_reverses = 0,
+ ttb_underlines = 0,
+ ttb_badwords = 0,
+ ttb_caps = 0,
+ ttb_flood = 0,
+ ttb_repeat = 0,
+ ttb_italics = 0,
+ ttb_amsgs = 0;
+
+ int16_t capsmin = 0,
+ capspercent = 0,
+ floodlines = 0,
+ floodsecs = 0,
+ repeattimes = 0;
+
+ bool dontkickops = false,
+ dontkickvoices = false;
+
+ public:
+ KickerDataImpl(Serialize::TypeBase *type) : KickerData(type) { }
+ KickerDataImpl(Serialize::TypeBase *type, Serialize::ID id) : KickerData(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
+
+ bool GetAmsgs() override;
+ void SetAmsgs(const bool &) override;
+
+ bool GetBadwords() override;
+ void SetBadwords(const bool &) override;
+
+ bool GetBolds() override;
+ void SetBolds(const bool &) override;
+
+ bool GetCaps() override;
+ void SetCaps(const bool &) override;
+
+ bool GetColors() override;
+ void SetColors(const bool &) override;
+
+ bool GetFlood() override;
+ void SetFlood(const bool &) override;
+
+ bool GetItalics() override;
+ void SetItalics(const bool &) override;
+
+ bool GetRepeat() override;
+ void SetRepeat(const bool &) override;
+
+ bool GetReverses() override;
+ void SetReverses(const bool &) override;
+
+ bool GetUnderlines() override;
+ void SetUnderlines(const bool &) override;
+
+ int16_t GetTTBBolds() override;
+ void SetTTBBolds(const int16_t &) override;
+
+ int16_t GetTTBColors() override;
+ void SetTTBColors(const int16_t &) override;
+
+ int16_t GetTTBReverses() override;
+ void SetTTBReverses(const int16_t &) override;
+
+ int16_t GetTTBUnderlines() override;
+ void SetTTBUnderlines(const int16_t &) override;
+
+ int16_t GetTTBBadwords() override;
+ void SetTTBBadwords(const int16_t &) override;
+
+ int16_t GetTTBCaps() override;
+ void SetTTBCaps(const int16_t &) override;
+
+ int16_t GetTTBFlood() override;
+ void SetTTBFlood(const int16_t &) override;
+
+ int16_t GetTTBRepeat() override;
+ void SetTTBRepeat(const int16_t &) override;
+
+ int16_t GetTTBItalics() override;
+ void SetTTBItalics(const int16_t &) override;
+
+ int16_t GetTTBAmsgs() override;
+ void SetTTBAmsgs(const int16_t &) override;
+
+ int16_t GetCapsMin() override;
+ void SetCapsMin(const int16_t &) override;
+
+ int16_t GetCapsPercent() override;
+ void SetCapsPercent(const int16_t &) override;
+
+ int16_t GetFloodLines() override;
+ void SetFloodLines(const int16_t &) override;
+
+ int16_t GetFloodSecs() override;
+ void SetFloodSecs(const int16_t &) override;
+
+ int16_t GetRepeatTimes() override;
+ void SetRepeatTimes(const int16_t &) override;
+
+ bool GetDontKickOps() override;
+ void SetDontKickOps(const bool &) override;
+
+ bool GetDontKickVoices() override;
+ void SetDontKickVoices(const bool &) override;
+};
+
+class KickerDataType : public Serialize::Type<KickerDataImpl>
+{
+ public:
+ Serialize::ObjectField<KickerDataImpl, ChanServ::Channel *> channel;
+
+ Serialize::Field<KickerDataImpl, bool> amsgs,
+ badwords,
+ bolds,
+ caps,
+ colors,
+ flood,
+ italics,
+ repeat,
+ reverses,
+ underlines;
+
+ Serialize::Field<KickerDataImpl, int16_t> ttb_bolds,
+ ttb_colors,
+ ttb_reverses,
+ ttb_underlines,
+ ttb_badwords,
+ ttb_caps,
+ ttb_flood,
+ ttb_repeat,
+ ttb_italics,
+ ttb_amsgs,
+ capsmin,
+ capspercent,
+ floodlines,
+ floodsecs,
+ repeattimes;
+
+ Serialize::Field<KickerDataImpl, bool> dontkickops,
+ dontkickvoices;
+
+ KickerDataType(Module *owner) : Serialize::Type<KickerDataImpl>(owner)
+ , channel(this, "channel", &KickerDataImpl::channel, true)
+ , amsgs(this, "amsgs", &KickerDataImpl::amsgs)
+ , badwords(this, "badwords", &KickerDataImpl::badwords)
+ , bolds(this, "bolds", &KickerDataImpl::bolds)
+ , caps(this, "caps", &KickerDataImpl::caps)
+ , colors(this, "colors", &KickerDataImpl::colors)
+ , flood(this, "flood", &KickerDataImpl::flood)
+ , italics(this, "italics", &KickerDataImpl::italics)
+ , repeat(this, "repeat", &KickerDataImpl::repeat)
+ , reverses(this, "reverses", &KickerDataImpl::reverses)
+ , underlines(this, "underlines", &KickerDataImpl::underlines)
+ , ttb_bolds(this, "ttb_bolds", &KickerDataImpl::ttb_bolds)
+ , ttb_colors(this, "ttb_colors", &KickerDataImpl::ttb_colors)
+ , ttb_reverses(this, "ttb_reverses", &KickerDataImpl::ttb_reverses)
+ , ttb_underlines(this, "ttb_underlines", &KickerDataImpl::ttb_underlines)
+ , ttb_badwords(this, "ttb_badwords", &KickerDataImpl::ttb_badwords)
+ , ttb_caps(this, "ttb_caps", &KickerDataImpl::ttb_caps)
+ , ttb_flood(this, "ttb_flood", &KickerDataImpl::ttb_flood)
+ , ttb_repeat(this, "ttb_repeat", &KickerDataImpl::ttb_repeat)
+ , ttb_italics(this, "ttb_italics", &KickerDataImpl::ttb_italics)
+ , ttb_amsgs(this, "ttb_amsgs", &KickerDataImpl::ttb_amsgs)
+ , capsmin(this, "capsmin", &KickerDataImpl::capsmin)
+ , capspercent(this, "capspercent", &KickerDataImpl::capspercent)
+ , floodlines(this, "floodlines", &KickerDataImpl::floodlines)
+ , floodsecs(this, "floodsecs", &KickerDataImpl::floodsecs)
+ , repeattimes(this, "repeattimes", &KickerDataImpl::repeattimes)
+ , dontkickops(this, "dontkickops", &KickerDataImpl::dontkickops)
+ , dontkickvoices(this, "dontkickvoices", &KickerDataImpl::dontkickvoices)
+ {
+ }
+};
+
+ChanServ::Channel *KickerDataImpl::GetChannel()
+{
+ return Get(&KickerDataType::channel);
+}
+
+void KickerDataImpl::SetChannel(ChanServ::Channel *channel)
+{
+ Set(&KickerDataType::amsgs, channel);
+}
+
+bool KickerDataImpl::GetAmsgs()
+{
+ return Get(&KickerDataType::amsgs);
+}
+
+void KickerDataImpl::SetAmsgs(const bool &b)
+{
+ Set(&KickerDataType::amsgs, b);
+}
+
+bool KickerDataImpl::GetBadwords()
+{
+ return Get(&KickerDataType::badwords);
+}
+
+void KickerDataImpl::SetBadwords(const bool &b)
+{
+ Set(&KickerDataType::badwords, b);
+}
+
+bool KickerDataImpl::GetBolds()
+{
+ return Get(&KickerDataType::bolds);
+}
+
+void KickerDataImpl::SetBolds(const bool &b)
+{
+ Set(&KickerDataType::bolds, b);
+}
+
+bool KickerDataImpl::GetCaps()
+{
+ return Get(&KickerDataType::caps);
+}
+
+void KickerDataImpl::SetCaps(const bool &b)
+{
+ Set(&KickerDataType::caps, b);
+}
+
+bool KickerDataImpl::GetColors()
+{
+ return Get(&KickerDataType::colors);
+}
+
+void KickerDataImpl::SetColors(const bool &b)
+{
+ Set(&KickerDataType::colors, b);
+}
+
+bool KickerDataImpl::GetFlood()
+{
+ return Get(&KickerDataType::flood);
+}
+
+void KickerDataImpl::SetFlood(const bool &b)
+{
+ Set(&KickerDataType::flood, b);
+}
+
+bool KickerDataImpl::GetItalics()
+{
+ return Get(&KickerDataType::italics);
+}
+
+void KickerDataImpl::SetItalics(const bool &b)
+{
+ Set(&KickerDataType::italics, b);
+}
+
+bool KickerDataImpl::GetRepeat()
+{
+ return Get(&KickerDataType::repeat);
+}
+
+void KickerDataImpl::SetRepeat(const bool &b)
+{
+ Set(&KickerDataType::repeat, b);
+}
+
+bool KickerDataImpl::GetReverses()
+{
+ return Get(&KickerDataType::reverses);
+}
+
+void KickerDataImpl::SetReverses(const bool &b)
+{
+ Set(&KickerDataType::reverses, b);
+}
+
+bool KickerDataImpl::GetUnderlines()
+{
+ return Get(&KickerDataType::underlines);
+}
+
+void KickerDataImpl::SetUnderlines(const bool &b)
+{
+ Set(&KickerDataType::underlines, b);
+}
+
+int16_t KickerDataImpl::GetTTBBolds()
+{
+ return Get(&KickerDataType::ttb_bolds);
+}
+
+void KickerDataImpl::SetTTBBolds(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_bolds, i);
+}
+
+int16_t KickerDataImpl::GetTTBColors()
+{
+ return Get(&KickerDataType::ttb_colors);
+}
+
+void KickerDataImpl::SetTTBColors(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_colors, i);
+}
+
+int16_t KickerDataImpl::GetTTBReverses()
+{
+ return Get(&KickerDataType::ttb_reverses);
+}
+
+void KickerDataImpl::SetTTBReverses(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_reverses, i);
+}
+
+int16_t KickerDataImpl::GetTTBUnderlines()
+{
+ return Get(&KickerDataType::ttb_underlines);
+}
+
+void KickerDataImpl::SetTTBUnderlines(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_underlines, i);
+}
+
+int16_t KickerDataImpl::GetTTBBadwords()
+{
+ return Get(&KickerDataType::ttb_badwords);
+}
+
+void KickerDataImpl::SetTTBBadwords(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_badwords, i);
+}
+
+int16_t KickerDataImpl::GetTTBCaps()
+{
+ return Get(&KickerDataType::ttb_caps);
+}
+
+void KickerDataImpl::SetTTBCaps(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_caps, i);
+}
+
+int16_t KickerDataImpl::GetTTBFlood()
+{
+ return Get(&KickerDataType::ttb_flood);
+}
+
+void KickerDataImpl::SetTTBFlood(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_flood, i);
+}
+
+int16_t KickerDataImpl::GetTTBRepeat()
+{
+ return Get(&KickerDataType::ttb_repeat);
+}
+
+void KickerDataImpl::SetTTBRepeat(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_repeat, i);
+}
+
+int16_t KickerDataImpl::GetTTBItalics()
+{
+ return Get(&KickerDataType::ttb_italics);
+}
+
+void KickerDataImpl::SetTTBItalics(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_italics, i);
+}
+
+int16_t KickerDataImpl::GetTTBAmsgs()
+{
+ return Get(&KickerDataType::ttb_amsgs);
+}
+
+void KickerDataImpl::SetTTBAmsgs(const int16_t &i)
+{
+ Set(&KickerDataType::ttb_amsgs, i);
+}
+
+int16_t KickerDataImpl::GetCapsMin()
+{
+ return Get(&KickerDataType::capsmin);
+}
+
+void KickerDataImpl::SetCapsMin(const int16_t &i)
+{
+ Set(&KickerDataType::capsmin, i);
+}
+
+int16_t KickerDataImpl::GetCapsPercent()
+{
+ return Get(&KickerDataType::capspercent);
+}
+
+void KickerDataImpl::SetCapsPercent(const int16_t &i)
+{
+ Set(&KickerDataType::capspercent, i);
+}
+
+int16_t KickerDataImpl::GetFloodLines()
+{
+ return Get(&KickerDataType::floodlines);
+}
+
+void KickerDataImpl::SetFloodLines(const int16_t &i)
+{
+ Set(&KickerDataType::floodlines, i);
+}
+
+int16_t KickerDataImpl::GetFloodSecs()
+{
+ return Get(&KickerDataType::floodsecs);
+}
+
+void KickerDataImpl::SetFloodSecs(const int16_t &i)
+{
+ Set(&KickerDataType::floodsecs, i);
+}
+
+int16_t KickerDataImpl::GetRepeatTimes()
+{
+ return Get(&KickerDataType::repeattimes);
+}
+
+void KickerDataImpl::SetRepeatTimes(const int16_t &i)
+{
+ Set(&KickerDataType::repeattimes, i);
+}
+
+bool KickerDataImpl::GetDontKickOps()
+{
+ return Get(&KickerDataType::dontkickops);
+}
+
+void KickerDataImpl::SetDontKickOps(const bool &b)
+{
+ Set(&KickerDataType::dontkickops, b);
+}
+
+bool KickerDataImpl::GetDontKickVoices()
+{
+ return Get(&KickerDataType::dontkickvoices);
+}
+
+void KickerDataImpl::SetDontKickVoices(const bool &b)
+{
+ Set(&KickerDataType::dontkickvoices, b);
+}
+
+class CommandBSKick : public Command
+{
+ public:
+ CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 0)
+ {
+ this->SetDesc(_("Configures kickers"));
+ this->SetSyntax(_("\037option\037 \037channel\037 {\037ON|OFF\037} [\037settings\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Configures bot kickers."
+ " Use of this command requires the \002SET\002 privilege on \037channel\037.\n"
+ "\n"
+ "Available kickers:"));
+
+ Anope::string this_name = source.command;
+ for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
+ {
+ const Anope::string &c_name = it->first;
+ const CommandInfo &info = it->second;
+
+ if (c_name.find_ci(this_name + " ") == 0)
+ {
+ ServiceReference<Command> command(info.name);
+ if (command)
+ {
+ source.command = c_name;
+ command->OnServHelp(source);
+ }
+ }
+ }
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("See \002{0}{1} {2} {3} \037option\037\002 for more information on a specific option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, this_name);
+
+ return true;
+ }
+};
+
+class CommandBSKickBase : public Command
+{
+ public:
+ CommandBSKickBase(Module *creator, const Anope::string &cname, int minarg, int maxarg) : Command(creator, cname, minarg, maxarg)
+ {
+ }
+
+ virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) override anope_abstract;
+
+ virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) override anope_abstract;
+
+ protected:
+ bool CheckArguments(CommandSource &source, const std::vector<Anope::string> &params, ChanServ::Channel* &ci)
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &option = params[1];
+
+ ci = ChanServ::Find(chan);
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
+ else if (ci == NULL)
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ else if (option.empty())
+ this->OnSyntaxError(source, "");
+ else if (!option.equals_ci("ON") && !option.equals_ci("OFF"))
+ this->OnSyntaxError(source, "");
+ else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("botserv/administration"))
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ else if (!ci->GetBot())
+ source.Reply(_("There is no bot assigned to \002{0}\002."), ci->GetName());
+ else
+ return true;
+
+ return false;
+ }
+
+ bool CheckTTB(CommandSource &source, const Anope::string &ttb, int16_t &i)
+ {
+ i = 0;
+ if (ttb.empty())
+ return true;
+
+ try
+ {
+ i = convertTo<int16_t>(ttb);
+ if (i < 0)
+ throw ConvertException();
+ }
+ catch (const ConvertException &)
+ {
+ i = 0;
+ source.Reply(_("\002{0}\002 can not be taken as times to ban. Times to ban must be a positive integer."), ttb);
+ return false;
+ }
+
+ return true;
+ }
+
+ void Process(CommandSource &source, ChanServ::Channel *ci, const Anope::string &param, const Anope::string &ttb, void (KickerData::*setter)(const bool &), void (KickerData::*ttbsetter)(const int16_t &), const Anope::string &optname)
+ {
+ KickerData *kd = ci->GetRef<KickerData *>();
+
+ if (param.equals_ci("ON"))
+ {
+ int16_t i;
+ if (!CheckTTB(source, ttb, i))
+ return;
+
+ (kd->*setter)(true);
+ (kd->*ttbsetter)(i);
+
+ if (i)
+ source.Reply(_("Bot will now kick for \002{0}\002, and will place a ban after \002{1}\002 kicks for the same user."), optname, i);
+ else
+ source.Reply(_("Bot will now kick for \002{0}\002."), optname);
+
+ bool override = !source.AccessFor(ci).HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable the " << optname << " kicker";
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ bool override = !source.AccessFor(ci).HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable the " << optname << " kicker";
+
+ (kd->*setter)(false);
+ (kd->*ttbsetter)(0);
+
+ source.Reply(_("Bot won't kick for \002{0}\002 anymore."), optname);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+};
+
+class CommandBSKickAMSG : public CommandBSKickBase
+{
+ public:
+ CommandBSKickAMSG(Module *creator) : CommandBSKickBase(creator, "botserv/kick/amsg", 2, 3)
+ {
+ this->SetDesc(_("Configures AMSG kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetAmsgs, &KickerData::SetTTBAmsgs, "amsgs");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the AMSG kicker on or off on \037channel\037. When enabled, the bot will kick users who send the same message to multiple channels where {0} bots are.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."),
+ source.service->nick);
+ return true;
+ }
+};
+
+class CommandBSKickBadwords : public CommandBSKickBase
+{
+ public:
+ CommandBSKickBadwords(Module *creator) : CommandBSKickBase(creator, "botserv/kick/badwords", 2, 3)
+ {
+ this->SetDesc(_("Configures badwords kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetBadwords, &KickerData::SetTTBBadwords, "badwords");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ ServiceBot *bi;
+ Anope::string name;
+ CommandInfo *help;
+ source.Reply(_("Sets the bad words kicker on or off on \037channel\037. When enabled, the bot will kick users who say certain words on the channel."));
+ if (Command::FindCommandFromService("botserv/badwords", bi, name) && (help = bi->FindCommand("generic/help")))
+ source.Reply(_("You can define bad words for your channel using the \002{0}\002 command. See \002{1}{2} {3} {4}\002 for more information."),
+ name, Config->StrictPrivmsg, bi->nick, help->cname, name);
+ source.Reply(_("\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickBolds : public CommandBSKickBase
+{
+ public:
+ CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3)
+ {
+ this->SetDesc(_("Configures bolds kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetBolds, &KickerData::SetTTBBolds, "bolds");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the bolds kicker on or off on \037channel\037. When enabled, the bot will kick users who use \002bolds\002.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickCaps : public CommandBSKickBase
+{
+ public:
+ CommandBSKickCaps(Module *creator) : CommandBSKickBase(creator, "botserv/kick/caps", 2, 5)
+ {
+ this->SetDesc(_("Configures caps kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (!CheckArguments(source, params, ci))
+ return;
+
+ KickerData *kd = GetKickerData(ci);
+
+ if (params[1].equals_ci("ON"))
+ {
+ const Anope::string &ttb = params.size() > 2 ? params[2] : "",
+ &min = params.size() > 3 ? params[3] : "",
+ &percent = params.size() > 4 ? params[4] : "";
+
+ int16_t i;
+ if (!CheckTTB(source, ttb, i))
+ return;
+
+ kd->SetCaps(true);
+ kd->SetTTBCaps(i);
+
+ kd->SetCapsMin(10);
+ try
+ {
+ kd->SetCapsMin(convertTo<int16_t>(min));
+ }
+ catch (const ConvertException &) { }
+ if (kd->GetCapsMin() < 1)
+ kd->SetCapsMin(10);
+
+ try
+ {
+ kd->SetCapsPercent(convertTo<int16_t>(percent));
+ }
+ catch (const ConvertException &) { }
+ if (kd->GetCapsPercent() < 1 || kd->GetCapsPercent() > 100)
+ kd->SetCapsPercent(25);
+
+ if (i)
+ source.Reply(_("Bot will now kick for \002caps\002 if they constitute at least {0} characters and {1}% of the entire message, and will place a ban after {2} kicks for the same user."), kd->GetCapsMin(), kd->GetCapsPercent(), i);
+ else
+ source.Reply(_("Bot will now kick for \002caps\002 if they constitute at least {0} characters and {1}% of the entire message."), kd->GetCapsMin(), kd->GetCapsPercent());
+ }
+ else
+ {
+ kd->SetCaps(false);
+ kd->SetTTBCaps(0);
+ kd->SetCapsMin(0);
+ kd->SetCapsPercent(0);
+ source.Reply(_("Bot won't kick for \002caps\002 anymore."));
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the caps kicker on or off on \037channel\037. When enabled, the bot will kick users who talk in CAPS."
+ " The bot kicks only if there are at least \002min\002 caps and they constitute at least \002percent\002% of the total text line."
+ " (if not given, it defaults to 10 characters and 25%).\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickColors : public CommandBSKickBase
+{
+ public:
+ CommandBSKickColors(Module *creator) : CommandBSKickBase(creator, "botserv/kick/colors", 2, 3)
+ {
+ this->SetDesc(_("Configures color kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetColors, &KickerData::SetTTBColors, "colors");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the colors kicker on or off on \037channel\037. When enabled, the bot will kick users who use \00304c\00307o\00308l\00303o\00306r\00312s\017.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickFlood : public CommandBSKickBase
+{
+ public:
+ CommandBSKickFlood(Module *creator) : CommandBSKickBase(creator, "botserv/kick/flood", 2, 5)
+ {
+ this->SetDesc(_("Configures flood kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037lines\037 [\037seconds\037]]]\002"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (!CheckArguments(source, params, ci))
+ return;
+
+ KickerData *kd = GetKickerData(ci);
+
+ if (params[1].equals_ci("ON"))
+ {
+ const Anope::string &ttb = params.size() > 2 ? params[2] : "",
+ &lines = params.size() > 3 ? params[3] : "",
+ &secs = params.size() > 4 ? params[4] : "";
+
+ int16_t i;
+ if (!CheckTTB(source, ttb, i))
+ return;
+
+ kd->SetFlood(true);
+ kd->SetTTBFlood(i);
+
+ kd->SetFloodLines(6);
+ try
+ {
+ kd->SetFloodLines(convertTo<int16_t>(lines));
+ }
+ catch (const ConvertException &) { }
+ if (kd->GetFloodLines() < 2)
+ kd->SetFloodLines(6);
+
+ kd->SetFloodSecs(10);
+ try
+ {
+ kd->SetFloodSecs(convertTo<int16_t>(secs));
+ }
+ catch (const ConvertException &) { }
+ if (kd->GetFloodSecs() < 1)
+ kd->SetFloodSecs(10);
+ if (kd->GetFloodSecs() > Config->GetModule(me)->Get<time_t>("keepdata"))
+ kd->SetFloodSecs(Config->GetModule(me)->Get<time_t>("keepdata"));
+
+ if (i)
+ source.Reply(_("Bot will now kick for \002flood\002 ({0} lines in {1} seconds and will place a ban after {2} kicks for the same user."), kd->GetFloodLines(), kd->GetFloodSecs(), i);
+ else
+ source.Reply(_("Bot will now kick for \002flood\002 ({0} lines in {1} seconds)."), kd->GetFloodLines(), kd->GetFloodSecs());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ kd->SetFlood(false);
+ kd->SetFloodLines(0);
+ kd->SetFloodSecs(0);
+ source.Reply(_("Bot won't kick for \002flood\002 anymore."));
+ }
+ else
+ this->OnSyntaxError(source, params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the flood kicker on or off on \037channel\037. When enabled, the bot to kick users who are flooding the channel with at least \037lines\037 lines in \037seconds\037 seconds. If not given, it defaults to 6 lines in 10 seconds.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickItalics : public CommandBSKickBase
+{
+ public:
+ CommandBSKickItalics(Module *creator) : CommandBSKickBase(creator, "botserv/kick/italics", 2, 3)
+ {
+ this->SetDesc(_("Configures italics kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetItalics, &KickerData::SetTTBItalics, "itlaics");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the italics kicker on or off on \037channel\037. When enabled, the bot will kick users who use \035italics\035."
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickRepeat : public CommandBSKickBase
+{
+ public:
+ CommandBSKickRepeat(Module *creator) : CommandBSKickBase(creator, "botserv/kick/repeat", 2, 4)
+ {
+ this->SetDesc(_("Configures repeat kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (!CheckArguments(source, params, ci))
+ return;
+
+ KickerData *kd = GetKickerData(ci);
+
+ if (params[1].equals_ci("ON"))
+ {
+ const Anope::string &ttb = params.size() > 2 ? params[2] : "",
+ &times = params.size() > 3 ? params[3] : "";
+
+ int16_t i;
+ if (!CheckTTB(source, ttb, i))
+ return;
+
+ kd->SetRepeat(true);
+ kd->SetTTBRepeat(i);
+ kd->SetRepeatTimes(3);
+ try
+ {
+ kd->SetRepeatTimes(convertTo<int16_t>(times));
+ }
+ catch (const ConvertException &) { }
+ if (kd->GetRepeatTimes() < 1)
+ kd->SetRepeatTimes(3);
+
+ if (i)
+ {
+ if (kd->GetRepeatTimes() != 1)
+ source.Reply(_("Bot will now kick for \002repeats\002 (users that say the same thing {0} times),"
+ " and will place a ban after {1} kicks for the same user."), kd->GetRepeatTimes(), i);
+ else
+ source.Reply(_("Bot will now kick for \002repeats\002 (users that say the same thing {0} time),"
+ " and will place a ban after {1} kicks for the same user."), kd->GetRepeatTimes(), i);
+ }
+ else
+ {
+ if (kd->GetRepeatTimes() != 1)
+ source.Reply(_("Bot will now kick for \002repeats\002 (users that say the same thing {0} times)."), kd->GetRepeatTimes());
+ else
+ source.Reply(_("Bot will now kick for \002repeats\002 (users that say the same thing {0} time)."), kd->GetRepeatTimes());
+
+ }
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ kd->SetRepeat(false);
+ kd->SetTTBRepeat(0);
+ kd->SetRepeatTimes(0);
+ source.Reply(_("Bot won't kick for \002repeats\002 anymore."));
+ }
+ else
+ this->OnSyntaxError(source, params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the repeat kicker on or off. When enabled, the bot will kick users who repeat themselves \037num\037 times. If \037num\037 is not given, it defaults to 3.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickReverses : public CommandBSKickBase
+{
+ public:
+ CommandBSKickReverses(Module *creator) : CommandBSKickBase(creator, "botserv/kick/reverses", 2, 3)
+ {
+ this->SetDesc(_("Configures reverses kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetReverses, &KickerData::SetTTBReverses, "reverses");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the reverses kicker on or off. When enabled, the bot will kick users who use \026reverses\026.\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSKickUnderlines : public CommandBSKickBase
+{
+ public:
+ CommandBSKickUnderlines(Module *creator) : CommandBSKickBase(creator, "botserv/kick/underlines", 2, 3)
+ {
+ this->SetDesc(_("Configures underlines kicker"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci;
+ if (CheckArguments(source, params, ci))
+ Process(source, ci, params[1], params.size() > 2 ? params[2] : "", &KickerData::SetUnderlines, &KickerData::SetTTBUnderlines, "underlines");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the underlines kicker on or off. When enabled, the bot will kick users who use \037underlines\037\n"
+ "\n"
+ "\037ttb\037 is the number of times a user can be kicked before they get banned. Don't give ttb to disable the ban system."));
+ return true;
+ }
+};
+
+class CommandBSSetDontKickOps : public Command
+{
+ public:
+ CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2)
+ {
+ this->SetDesc(_("To protect ops against bot kicks"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, bot option setting is temporarily disabled."));
+ return;
+ }
+
+ KickerData *kd = GetKickerData(ci);
+
+ if (params[1].equals_ci("ON"))
+ {
+ bool override = !access.HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops";
+
+ kd->SetDontKickOps(true);
+ source.Reply(_("Bot \002won't kick ops\002 on channel \002{0}\002."), ci->GetName());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ bool override = !access.HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops";
+
+ kd->SetDontKickOps(false);
+ source.Reply(_("Bot \002will kick ops\002 on channel \002{0}\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, source.command);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables \002op protection\002 mode on a channel."
+ " When it is enabled, ops won't be kicked by the bot, even if they don't have the \002{0}\002 privilege.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ "NOKICK", "SET");
+ return true;
+ }
+};
+
+class CommandBSSetDontKickVoices : public Command
+{
+ public:
+ CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2)
+ {
+ this->SetDesc(_("To protect voices against bot kicks"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, bot option setting is temporarily disabled."));
+ return;
+ }
+
+ KickerData *kd = GetKickerData(ci);
+
+ if (params[1].equals_ci("ON"))
+ {
+ bool override = !access.HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices";
+
+ kd->SetDontKickVoices(true);
+ source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->GetName().c_str());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ bool override = !access.HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices";
+
+ kd->SetDontKickVoices(false);
+ source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->GetName().c_str());
+ }
+ else
+ this->OnSyntaxError(source, source.command);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables \002voice protection\002 mode on a channel."
+ " When it is enabled, ops won't be kicked by the bot, even if they don't have the \002{0}\002 privilege.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ "NOKICK", "SET");
+ return true;
+ }
+};
+
+struct BanData
+{
+ struct Data
+ {
+ Anope::string mask;
+ time_t last_use;
+ int16_t ttb[TTB_SIZE];
+
+ Data()
+ {
+ last_use = 0;
+ for (int i = 0; i < TTB_SIZE; ++i)
+ this->ttb[i] = 0;
+ }
+ };
+
+ private:
+ typedef Anope::map<Data> data_type;
+ data_type data_map;
+
+ public:
+ Data &get(const Anope::string &key)
+ {
+ return this->data_map[key];
+ }
+
+ bool empty() const
+ {
+ return this->data_map.empty();
+ }
+
+ void purge()
+ {
+ time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata");
+ for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
+ {
+ const Anope::string &user = it->first;
+ Data &bd = it->second;
+ ++it;
+
+ if (Anope::CurTime - bd.last_use > keepdata)
+ data_map.erase(user);
+ }
+ }
+};
+
+struct UserData
+{
+ UserData()
+ {
+ last_use = last_start = Anope::CurTime;
+ }
+
+ /* Data validity */
+ time_t last_use;
+
+ /* for flood kicker */
+ int16_t lines = 0;
+ time_t last_start;
+
+ /* for repeat kicker */
+ Anope::string lasttarget;
+ int16_t times = 0;
+
+ Anope::string lastline;
+};
+
+class BanDataPurger : public Timer
+{
+ public:
+ BanDataPurger(Module *o) : Timer(o, 300, Anope::CurTime, true) { }
+
+ void Tick(time_t) override
+ {
+ 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;
+
+ BanData *bd = c->GetExt<BanData>("bandata");
+ if (bd != NULL)
+ {
+ bd->purge();
+ if (bd->empty())
+ c->Shrink<BanData>("bandata");
+ }
+ }
+ }
+};
+
+class BSKick : public Module
+ , public EventHook<Event::ServiceBotEvent>
+ , public EventHook<Event::Privmsg>
+{
+ ExtensibleItem<BanData> bandata;
+ ExtensibleItem<UserData> userdata;
+
+ KickerDataType kdtype;
+
+ CommandBSKick commandbskick;
+ CommandBSKickAMSG commandbskickamsg;
+ CommandBSKickBadwords commandbskickbadwords;
+ CommandBSKickBolds commandbskickbolds;
+ CommandBSKickCaps commandbskickcaps;
+ CommandBSKickColors commandbskickcolors;
+ CommandBSKickFlood commandbskickflood;
+ CommandBSKickItalics commandbskickitalics;
+ CommandBSKickRepeat commandbskickrepeat;
+ CommandBSKickReverses commandbskickreverse;
+ CommandBSKickUnderlines commandbskickunderlines;
+
+ CommandBSSetDontKickOps commandbssetdontkickops;
+ CommandBSSetDontKickVoices commandbssetdontkickvoices;
+
+ BanDataPurger purger;
+
+ ServiceReference<BadWords> badwords;
+
+ BanData::Data &GetBanData(User *u, Channel *c)
+ {
+ BanData *bd = bandata.Require(c);
+ return bd->get(u->GetMask());
+ }
+
+ UserData *GetUserData(User *u, Channel *c)
+ {
+ ChanUserContainer *uc = c->FindUser(u);
+ if (uc == nullptr)
+ return nullptr;
+
+ return userdata.Require(uc);
+ }
+
+ void TakeAction(ChanServ::Channel *ci, User *u, int ttb, TTBType ttbtype, const char *message, ...)
+ {
+ /* Don't ban ulines or protected users */
+ if (u->IsProtected())
+ return;
+
+ BanData::Data &bd = this->GetBanData(u, ci->c);
+
+ ++bd.ttb[ttbtype];
+ if (ttb && bd.ttb[ttbtype] >= ttb)
+ {
+ bd.ttb[ttbtype] = 0;
+
+ Anope::string mask = ci->GetIdealBan(u);
+
+ ci->c->SetMode(NULL, "BAN", mask);
+ EventManager::Get()->Dispatch(&Event::BotBan::OnBotBan, u, ci, mask);
+ }
+
+ if (!ci->c->FindUser(u))
+ return;
+
+ va_list args;
+ char buf[1024];
+
+ Anope::string fmt = Language::Translate(u, message);
+ va_start(args, message);
+ vsnprintf(buf, sizeof(buf), fmt.c_str(), args);
+ va_end(args);
+
+ ci->c->Kick(ci->GetBot(), u, "%s", buf);
+ }
+
+ public:
+ BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ServiceBotEvent>(this)
+ , EventHook<Event::Privmsg>(this)
+
+ , bandata(this, "bandata")
+ , userdata(this, "userdata")
+
+ , kdtype(this)
+
+ , commandbskick(this)
+ , commandbskickamsg(this)
+ , commandbskickbadwords(this)
+ , commandbskickbolds(this)
+ , commandbskickcaps(this)
+ , commandbskickcolors(this)
+ , commandbskickflood(this)
+ , commandbskickitalics(this)
+ , commandbskickrepeat(this)
+ , commandbskickreverse(this)
+ , commandbskickunderlines(this)
+
+ , commandbssetdontkickops(this)
+ , commandbssetdontkickvoices(this)
+
+ , purger(this)
+ {
+ me = this;
+ }
+
+ void OnServiceBot(CommandSource &source, ServiceBot *bi, ChanServ::Channel *ci, InfoFormatter &info) override
+ {
+ if (!ci)
+ return;
+
+ Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
+ Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
+ KickerData *kd = ci->GetRef<KickerData *>();
+
+ if (kd && kd->GetBadwords())
+ {
+ if (kd->GetTTBBadwords())
+ info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->GetBadwords());
+ else
+ info[_("Bad words kicker")] = enabled;
+ }
+ else
+ info[_("Bad words kicker")] = disabled;
+
+ if (kd && kd->GetBolds())
+ {
+ if (kd->GetTTBBolds())
+ info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->GetTTBBolds());
+ else
+ info[_("Bolds kicker")] = enabled;
+ }
+ else
+ info[_("Bolds kicker")] = disabled;
+
+ if (kd && kd->GetCaps())
+ {
+ if (kd->GetTTBCaps())
+ info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%)"), enabled.c_str(), kd->GetTTBCaps(), kd->GetCapsMin(), kd->GetCapsPercent());
+ else
+ info[_("Caps kicker")] = Anope::printf(_("%s (minimum %d/%d%%)"), enabled.c_str(), kd->GetCapsMin(), kd->GetCapsPercent());
+ }
+ else
+ info[_("Caps kicker")] = disabled;
+
+ if (kd && kd->GetColors())
+ {
+ if (kd->GetTTBColors())
+ info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->GetTTBColors());
+ else
+ info[_("Colors kicker")] = enabled;
+ }
+ else
+ info[_("Colors kicker")] = disabled;
+
+ if (kd && kd->GetFlood())
+ {
+ if (kd->GetTTBFlood())
+ info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds)"), enabled.c_str(), kd->GetTTBFlood(), kd->GetFloodLines(), kd->GetFloodSecs());
+ else
+ info[_("Flood kicker")] = Anope::printf(_("%s (%d lines in %ds)"), enabled.c_str(), kd->GetFloodLines(), kd->GetFloodSecs());
+ }
+ else
+ info[_("Flood kicker")] = disabled;
+
+ if (kd && kd->GetRepeat())
+ {
+ if (kd->GetTTBRepeat())
+ info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), kd->GetTTBRepeat(), kd->GetRepeatTimes());
+ else
+ info[_("Repeat kicker")] = Anope::printf(_("%s (%d times)"), enabled.c_str(), kd->GetRepeatTimes());
+ }
+ else
+ info[_("Repeat kicker")] = disabled;
+
+ if (kd && kd->GetReverses())
+ {
+ if (kd->GetTTBReverses())
+ info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->GetTTBReverses());
+ else
+ info[_("Reverses kicker")] = enabled;
+ }
+ else
+ info[_("Reverses kicker")] = disabled;
+
+ if (kd && kd->GetUnderlines())
+ {
+ if (kd->GetTTBUnderlines())
+ info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->GetTTBUnderlines());
+ else
+ info[_("Underlines kicker")] = enabled;
+ }
+ else
+ info[_("Underlines kicker")] = disabled;
+
+ if (kd && kd->GetItalics())
+ {
+ if (kd->GetTTBItalics())
+ info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->GetTTBItalics());
+ else
+ info[_("Italics kicker")] = enabled;
+ }
+ else
+ info[_("Italics kicker")] = disabled;
+
+ if (kd && kd->GetAmsgs())
+ {
+ if (kd->GetTTBAmsgs())
+ info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->GetTTBAmsgs());
+ else
+ info[_("AMSG kicker")] = enabled;
+ }
+ else
+ info[_("AMSG kicker")] = disabled;
+
+ if (kd && kd->GetDontKickOps())
+ info.AddOption(_("Ops protection"));
+ if (kd && kd->GetDontKickVoices())
+ info.AddOption(_("Voices protection"));
+ }
+
+ void OnPrivmsg(User *u, Channel *c, Anope::string &msg) override
+ {
+ /* Now we can make kicker stuff. We try to order the checks
+ * from the fastest one to the slowest one, since there's
+ * no need to process other kickers if a user is kicked before
+ * the last kicker check.
+ *
+ * But FIRST we check whether the user is protected in any
+ * way.
+ */
+ ChanServ::Channel *ci = c->ci;
+ if (ci == NULL)
+ return;
+ KickerData *kd = c->ci->GetRef<KickerData *>();
+ if (kd == NULL)
+ return;
+
+ if (ci->AccessFor(u).HasPriv("NOKICK"))
+ return;
+ if (kd->GetDontKickOps() && (c->HasUserStatus(u, "HALFOP") || c->HasUserStatus(u, "OP") || c->HasUserStatus(u, "PROTECT") || c->HasUserStatus(u, "OWNER")))
+ return;
+ if (kd->GetDontKickVoices() && c->HasUserStatus(u, "VOICE"))
+ return;
+
+ Anope::string realbuf = msg;
+
+ /* If it's a /me, cut the CTCP part because the ACTION will cause
+ * problems with the caps or badwords kicker
+ */
+ if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
+ {
+ realbuf.erase(0, 8);
+ realbuf.erase(realbuf.length() - 1);
+ }
+
+ if (realbuf.empty())
+ return;
+
+ /* Bolds kicker */
+ if (kd->GetBolds() && realbuf.find(2) != Anope::string::npos)
+ {
+ TakeAction(ci, u, kd->GetTTBBolds(), TTB_BOLDS, _("Don't use bolds on this channel!"));
+ return;
+ }
+
+ /* Color kicker */
+ if (kd->GetColors() && realbuf.find(3) != Anope::string::npos)
+ {
+ TakeAction(ci, u, kd->GetTTBColors(), TTB_COLORS, _("Don't use colors on this channel!"));
+ return;
+ }
+
+ /* Reverses kicker */
+ if (kd->GetReverses() && realbuf.find(22) != Anope::string::npos)
+ {
+ TakeAction(ci, u, kd->GetTTBReverses(), TTB_REVERSES, _("Don't use reverses on this channel!"));
+ return;
+ }
+
+ /* Italics kicker */
+ if (kd->GetItalics() && realbuf.find(29) != Anope::string::npos)
+ {
+ TakeAction(ci, u, kd->GetTTBItalics(), TTB_ITALICS, _("Don't use italics on this channel!"));
+ return;
+ }
+
+ /* Underlines kicker */
+ if (kd->GetUnderlines() && realbuf.find(31) != Anope::string::npos)
+ {
+ TakeAction(ci, u, kd->GetTTBUnderlines(), TTB_UNDERLINES, _("Don't use underlines on this channel!"));
+ return;
+ }
+
+ /* Caps kicker */
+ if (kd->GetCaps() && realbuf.length() >= static_cast<unsigned>(kd->GetCapsMin()))
+ {
+ int i = 0, l = 0;
+
+ for (unsigned j = 0, end = realbuf.length(); j < end; ++j)
+ {
+ if (isupper(realbuf[j]))
+ ++i;
+ else if (islower(realbuf[j]))
+ ++l;
+ }
+
+ /* i counts uppercase chars, l counts lowercase chars. Only
+ * alphabetic chars (so islower || isupper) qualify for the
+ * percentage of caps to kick for; the rest is ignored. -GD
+ */
+
+ if ((i || l) && i >= kd->GetCapsMin() && i * 100 / (i + l) >= kd->GetCapsPercent())
+ {
+ TakeAction(ci, u, kd->GetTTBCaps(), TTB_CAPS, _("Turn caps lock OFF!"));
+ return;
+ }
+ }
+
+ /* Bad words kicker */
+ if (kd->GetBadwords())
+ {
+ bool mustkick = false;
+
+ /* Normalize the buffer */
+ Anope::string nbuf = Anope::NormalizeBuffer(realbuf);
+ bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
+
+ /* Normalize can return an empty string if this only conains control codes etc */
+ if (badwords && !nbuf.empty())
+ for (unsigned i = 0; i < badwords->GetBadWordCount(ci); ++i)
+ {
+ BadWord *bw = badwords->GetBadWord(ci, i);
+
+ if (bw->GetWord().empty())
+ continue; // Shouldn't happen
+
+ if (bw->GetWord().length() > nbuf.length())
+ continue; // This can't ever match
+
+ if (bw->GetType() == BW_ANY && ((casesensitive && nbuf.find(bw->GetWord()) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->GetWord()) != Anope::string::npos)))
+ mustkick = true;
+ else if (bw->GetType() == BW_SINGLE)
+ {
+ size_t len = bw->GetWord().length();
+
+ if ((casesensitive && bw->GetWord().equals_cs(nbuf)) || (!casesensitive && bw->GetWord().equals_ci(nbuf)))
+ mustkick = true;
+ else if (nbuf.find(' ') == len && ((casesensitive && bw->GetWord().equals_cs(nbuf.substr(0, len))) || (!casesensitive && bw->GetWord().equals_ci(nbuf.substr(0, len)))))
+ mustkick = true;
+ else
+ {
+ if (len < nbuf.length() && nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->GetWord()) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->GetWord()) == nbuf.length() - len)))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = " " + bw->GetWord() + " ";
+
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+ }
+ else if (bw->GetType() == BW_START)
+ {
+ size_t len = bw->GetWord().length();
+
+ if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->GetWord())) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->GetWord())))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = " " + bw->GetWord();
+
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+ else if (bw->GetType() == BW_END)
+ {
+ size_t len = bw->GetWord().length();
+
+ if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->GetWord())) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->GetWord())))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = bw->GetWord() + " ";
+
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+
+ if (mustkick)
+ {
+ if (Config->GetModule(me)->Get<bool>("gentlebadwordreason"))
+ TakeAction(ci, u, kd->GetTTBBadwords(), TTB_BADWORDS, _("Watch your language!"));
+ else
+ TakeAction(ci, u, kd->GetTTBBadwords(), TTB_BADWORDS, _("Don't use the word \"%s\" on this channel!"), bw->GetWord().c_str());
+
+ return;
+ }
+ } /* for */
+ } /* if badwords */
+
+ UserData *ud = GetUserData(u, c);
+
+ if (ud)
+ {
+ /* Flood kicker */
+ if (kd->GetFlood())
+ {
+ if (Anope::CurTime - ud->last_start > kd->GetFloodSecs())
+ {
+ ud->last_start = Anope::CurTime;
+ ud->lines = 0;
+ }
+
+ ++ud->lines;
+ if (ud->lines >= kd->GetFloodLines())
+ {
+ TakeAction(ci, u, kd->GetTTBFlood(), TTB_FLOOD, _("Stop flooding!"));
+ return;
+ }
+ }
+
+ /* Repeat kicker */
+ if (kd->GetRepeat())
+ {
+ if (!ud->lastline.equals_ci(realbuf))
+ ud->times = 0;
+ else
+ ++ud->times;
+
+ if (ud->times >= kd->GetRepeatTimes())
+ {
+ TakeAction(ci, u, kd->GetTTBRepeat(), TTB_REPEAT, _("Stop repeating yourself!"));
+ return;
+ }
+ }
+
+ if (ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->GetName()))
+ {
+ for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();)
+ {
+ Channel *chan = it->second->chan;
+ ++it;
+
+ if (chan->ci && kd->GetAmsgs() && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
+ {
+ TakeAction(ci, u, kd->GetTTBAmsgs(), TTB_AMSGS, _("Don't use AMSGs!"));
+ return;
+ }
+ }
+ }
+
+ ud->lasttarget = ci->GetName();
+ ud->lastline = realbuf;
+ }
+ }
+};
+
+MODULE_INIT(BSKick)
diff --git a/modules/botserv/main/CMakeLists.txt b/modules/botserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/botserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/pseudoclients/botserv.cpp b/modules/botserv/main/botserv.cpp
index ac73e257a..a297db153 100644
--- a/modules/pseudoclients/botserv.cpp
+++ b/modules/botserv/main/botserv.cpp
@@ -1,6 +1,6 @@
/* BotServ core functions
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -10,50 +10,71 @@
*/
#include "module.h"
-
-class BotServCore : public Module
+#include "modules/botserv.h"
+#include "modules/help.h"
+
+class BotServCore : public Module, public BotServ::BotServService
+ , public EventHook<Event::SetCorrectModes>
+ , public EventHook<Event::BotAssign>
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::LeaveChannel>
+ , public EventHook<Event::Help>
+ , public EventHook<Event::ChannelModeSet>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::UserKicked>
+ , public EventHook<Event::CreateBot>
{
- Reference<BotInfo> BotServ;
- ExtensibleRef<bool> persist, inhabit;
+ Reference<ServiceBot> BotServ;
+ ExtensibleRef<bool> inhabit;
public:
- BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- persist("PERSIST"), inhabit("inhabit")
+ BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , BotServ::BotServService(this)
+ , EventHook<Event::SetCorrectModes>(this)
+ , EventHook<Event::BotAssign>(this)
+ , EventHook<Event::JoinChannel>(this)
+ , EventHook<Event::LeaveChannel>(this)
+ , EventHook<Event::Help>(this)
+ , EventHook<Event::ChannelModeSet>(this)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::UserKicked>(this)
+ , EventHook<Event::CreateBot>(this)
+ , inhabit("inhabit")
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
- const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string>("client");
- BotServ = BotInfo::Find(bsnick, true);
+ const Anope::string &bsnick = conf->GetModule(this)->Get<Anope::string>("client");
+ BotServ = ServiceBot::Find(bsnick, true);
}
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
+ void OnSetCorrectModes(User *user, Channel *chan, ChanServ::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)
+ if (chan->ci && chan->ci->GetBot() == user)
{
- const Anope::string &botmodes = Config->GetModule(this)->Get<const Anope::string>("botmodes");
+ const Anope::string &botmodes = Config->GetModule(this)->Get<Anope::string>("botmodes");
for (unsigned i = 0; i < botmodes.length(); ++i)
- chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->bi->GetUID());
+ chan->SetMode(chan->ci->GetBot(), ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->GetBot()->GetUID());
}
}
- void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override
+ void OnBotAssign(User *sender, ChanServ::Channel *ci, ServiceBot *bi) override
{
if (ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers"))
{
- ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes"));
+ ChannelStatus status(Config->GetModule(this)->Get<Anope::string>("botmodes"));
bi->Join(ci->c, &status);
}
}
- void OnJoinChannel(User *user, Channel *c) anope_override
+ void OnJoinChannel(User *user, Channel *c) override
{
if (!Config || !IRCD)
return;
- BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL;
+ ServiceBot *bi = user->server == Me ? dynamic_cast<ServiceBot *>(user) : NULL;
if (bi && Config->GetModule(this)->Get<bool>("smartjoin"))
{
std::vector<Anope::string> bans = c->GetModeList("BAN");
@@ -86,7 +107,7 @@ class BotServCore : public Module
ModeManager::ProcessModes();
}
- if (user->server != Me && c->ci && c->ci->bi)
+ if (user->server != Me && c->ci && c->ci->GetBot())
{
/**
* We let the bot join even if it was an ignored user, as if we don't,
@@ -95,18 +116,18 @@ class BotServCore : public Module
* 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<unsigned>("minusers") && !c->FindUser(c->ci->bi))
+ if (c->users.size() + 1 >= Config->GetModule(this)->Get<unsigned>("minusers") && !c->FindUser(c->ci->GetBot()))
{
- ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes"));
- c->ci->bi->Join(c, &status);
+ ChannelStatus status(Config->GetModule(this)->Get<Anope::string>("botmodes"));
+ c->ci->GetBot()->Join(c, &status);
}
}
}
- void OnLeaveChannel(User *u, Channel *c) anope_override
+ 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))
+ if (c->ci && c->ci->HasFieldS("PERSIST"))
return;
/* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediately
@@ -119,12 +140,17 @@ class BotServCore : public Module
if (inhabit && inhabit->HasExt(c))
return;
- /* This is called prior to removing the user from the channnel, 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<unsigned>("minusers") && c->FindUser(c->ci->bi))
- c->ci->bi->Part(c->ci->c);
+ if (c->ci)
+ {
+ ServiceBot *bot = c->ci->GetBot();
+
+ /* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */
+ if (bot && u != bot && c->users.size() - 1 <= Config->GetModule(this)->Get<unsigned>("minusers") && c->FindUser(bot))
+ bot->Part(c);
+ }
}
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (!params.empty())
return EVENT_CONTINUE;
@@ -136,7 +162,7 @@ class BotServCore : public Module
"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<const Anope::string>("fantasycharacter", "!");
+ const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<Anope::string>("fantasycharacter", "!");
if (!fantasycharacters.empty())
source.Reply(_(" \n"
"Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str());
@@ -159,7 +185,7 @@ class BotServCore : public Module
return EVENT_CONTINUE;
}
- void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (!params.empty() || source.c || source.service != *BotServ)
return;
@@ -167,18 +193,18 @@ class BotServCore : public Module
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<unsigned>("minusers"));
- const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<const Anope::string>("fantasycharacter", "!");
+ const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<Anope::string>("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 &param) anope_override
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &source, ChannelMode *mode, const Anope::string &param) override
{
- if (source.GetUser() && !source.GetBot() && Config->GetModule(this)->Get<bool>("smartjoin") && mode->name == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
+ if (source.GetUser() && !source.GetBot() && Config->GetModule(this)->Get<bool>("smartjoin") && mode->name == "BAN" && c->ci && c->ci->GetBot() && c->FindUser(c->ci->GetBot()))
{
- BotInfo *bi = c->ci->bi;
+ ServiceBot *bi = c->ci->GetBot();
Entry ban("BAN", param);
if (ban.Matches(bi))
@@ -188,26 +214,26 @@ class BotServCore : public Module
return EVENT_CONTINUE;
}
- void OnCreateChan(ChannelInfo *ci) anope_override
+ void OnChanRegistered(ChanServ::Channel *ci) override
{
/* Set default bot flags */
- spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy"));
+ spacesepstream sep(Config->GetModule(this)->Get<Anope::string>("defaults", "greet fantasy"));
for (Anope::string token; sep.GetToken(token);)
- ci->Extend<bool>("BS_" + token.upper());
+ ci->SetS<bool>("BS_" + token.upper(), true);
}
- void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override
+ void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) override
{
- BotInfo *bi = BotInfo::Find(target->GetUID());
+ ServiceBot *bi = ServiceBot::Find(target->GetUID());
if (bi)
/* Bots get rejoined */
bi->Join(channel, &status);
}
- void OnCreateBot(BotInfo *bi) anope_override
+ void OnCreateBot(ServiceBot *bi) override
{
if (bi->botmodes.empty())
- bi->botmodes = Config->GetModule(this)->Get<const Anope::string>("botumodes");
+ bi->botmodes = Config->GetModule(this)->Get<Anope::string>("botumodes");
}
};
diff --git a/modules/commands/bs_set.cpp b/modules/botserv/set.cpp
index 9e0bac56a..47c5337d2 100644
--- a/modules/commands/bs_set.cpp
+++ b/modules/botserv/set.cpp
@@ -1,15 +1,24 @@
-/* BotServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
+#include "modules/botserv/kick.h"
class CommandBSSet : public Command
{
@@ -20,17 +29,15 @@ class CommandBSSet : public Command
this->SetSyntax(_("\037option\037 \037(channel | bot)\037 \037settings\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
this->OnSyntaxError(source, "");
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("Configures bot options.\n"
- " \n"
+ "\n"
"Available options:"));
bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
@@ -41,7 +48,7 @@ class CommandBSSet : public Command
const CommandInfo &info = it->second;
if (c_name.find_ci(this_name + " ") == 0)
{
- ServiceReference<Command> command("Command", info.name);
+ ServiceReference<Command> command(info.name);
if (command)
{
// XXX dup
@@ -56,8 +63,11 @@ class CommandBSSet : public Command
}
}
}
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("Type \002{0}{1} {2} {3} \037option\037\002 for more information on a particular option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, this_name);
return true;
}
@@ -74,7 +84,7 @@ class CommandBSSetBanExpire : public Command
public:
UnbanTimer(Module *creator, const Anope::string &ch, const Anope::string &bmask, time_t t) : Timer(creator, t), chname(ch), mask(bmask) { }
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
Channel *c = Channel::Find(chname);
if (c)
@@ -88,22 +98,22 @@ class CommandBSSetBanExpire : public Command
this->SetSyntax(_("\037channel\037 \037time\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &chan = params[0];
const Anope::string &arg = params[1];
- ChannelInfo *ci = ChannelInfo::Find(chan);
+ ChanServ::Channel *ci = ChanServ::Find(chan);
if (ci == NULL)
{
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
return;
}
- AccessGroup access = source.AccessFor(ci);
+ ChanServ::AccessGroup access = source.AccessFor(ci);
if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
return;
}
@@ -116,7 +126,7 @@ class CommandBSSetBanExpire : public Command
time_t t = Anope::DoTime(arg);
if (t == -1)
{
- source.Reply(BAD_EXPIRY_TIME);
+ source.Reply(_("Invalid expiry time \002{0}\002."), arg);
return;
}
@@ -127,25 +137,21 @@ class CommandBSSetBanExpire : public Command
return;
}
- ci->banexpire = t;
+ ci->SetBanExpire(t);
bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change banexpire to " << ci->banexpire;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change banexpire to " << arg;
- if (!ci->banexpire)
+ if (!t)
source.Reply(_("Bot bans will no longer automatically expire."));
else
- source.Reply(_("Bot bans will automatically expire after %s."), Anope::Duration(ci->banexpire, source.GetAccount()).c_str());
+ source.Reply(_("Bot bans will automatically expire after \002{0}\002."), Anope::Duration(t, source.GetAccount()));
}
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Sets the time bot bans expire in. If enabled, any bans placed by\n"
- "bots, such as flood kicker, badwords kicker, etc. will automatically\n"
- "be removed after the given time. Set to 0 to disable bans from\n"
- "automatically expiring."));
+ source.Reply(_("Sets the time bot bans expire in. If enabled, any bans placed by bots, such as by the flood kicker, badwords kicker, etc. will automatically be removed after the given time."
+ " Set to 0 to disable bans from automatically expiring."));
return true;
}
};
@@ -155,70 +161,69 @@ class CommandBSSetPrivate : public Command
public:
CommandBSSetPrivate(Module *creator, const Anope::string &sname = "botserv/set/private") : Command(creator, sname, 2, 2)
{
- this->SetDesc(_("Prevent a bot from being assigned by non IRC operators"));
+ this->SetDesc(_("Prevent a bot from being assigned by non Services Operators"));
this->SetSyntax(_("\037botname\037 {\037ON|OFF\037}"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
- BotInfo *bi = BotInfo::Find(params[0], true);
+ const Anope::string &nick = params[9];
const Anope::string &value = params[1];
if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ ServiceBot *bi = ServiceBot::Find(nick, true);
if (bi == NULL)
{
- source.Reply(BOT_DOES_NOT_EXIST, params[0].c_str());
+ source.Reply(_("Bot \002{0}\002 does not exist."), nick);
return;
}
if (value.equals_ci("ON"))
{
- bi->oper_only = true;
- source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str());
+ bi->bi->SetOperOnly(true);
+ source.Reply(_("Private mode of bot \002{0}\002 is now \002on\002."), bi->nick);
}
else if (value.equals_ci("OFF"))
{
- bi->oper_only = false;
- source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
+ bi->bi->SetOperOnly(false);
+ source.Reply(_("Private mode of bot \002{0}\002 is now \002off\002."), bi->nick);
}
else
this->OnSyntaxError(source, source.command);
}
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "This option prevents a bot from being assigned to a\n"
- "channel by users that aren't IRC Operators."));
+ source.Reply(_("This option prevents a bot from being assigned to channels by users who do not have the \002{0}\002 privilege."),
+ "botserv/administration");
return true;
}
};
class BSSet : public Module
+ , public EventHook<Event::BotBan>
{
CommandBSSet commandbsset;
CommandBSSetBanExpire commandbssetbanexpire;
CommandBSSetPrivate commandbssetprivate;
public:
- BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsset(this), commandbssetbanexpire(this),
- commandbssetprivate(this)
+ BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::BotBan>(this)
+ , commandbsset(this)
+ , commandbssetbanexpire(this)
+ , commandbssetprivate(this)
{
}
- void OnBotBan(User *u, ChannelInfo *ci, const Anope::string &mask) anope_override
+ void OnBotBan(User *u, ChanServ::Channel *ci, const Anope::string &mask) override
{
- if (!ci->banexpire)
+ if (!ci->GetBanExpire())
return;
- new CommandBSSetBanExpire::UnbanTimer(this, ci->name, mask, ci->banexpire);
+ new CommandBSSetBanExpire::UnbanTimer(this, ci->GetName(), mask, ci->GetBanExpire());
}
};
diff --git a/modules/bs_autoassign.cpp b/modules/bs_autoassign.cpp
deleted file mode 100644
index 0462e649d..000000000
--- a/modules/bs_autoassign.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- */
-
-#include "module.h"
-
-class BSAutoAssign : public Module
-{
- public:
- BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
- {
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- const Anope::string &bot = Config->GetModule(this)->Get<const Anope::string>("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/chanserv/CMakeLists.txt b/modules/chanserv/CMakeLists.txt
new file mode 100644
index 000000000..9a236d6d0
--- /dev/null
+++ b/modules/chanserv/CMakeLists.txt
@@ -0,0 +1,2 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
+build_modules_dependencies(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/chanserv/access.cpp b/modules/chanserv/access.cpp
new file mode 100644
index 000000000..5c9650577
--- /dev/null
+++ b/modules/chanserv/access.cpp
@@ -0,0 +1,922 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/* Dependencies: anope_chanserv.main */
+
+#include "module.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/access.h"
+#include "modules/chanserv/main/chanaccess.h"
+#include "main/chanaccesstype.h"
+
+class AccessChanAccessImpl : public AccessChanAccess
+{
+ friend class AccessChanAccessType;
+
+ int level = 0;
+
+ public:
+ static constexpr const char *NAME = "accesschanaccess";
+
+ using AccessChanAccess::AccessChanAccess;
+
+ int GetLevel();
+ void SetLevel(const int &);
+
+ bool HasPriv(const Anope::string &name) override
+ {
+ return this->GetChannel()->GetLevel(name) != ChanServ::ACCESS_INVALID && this->GetLevel() >= this->GetChannel()->GetLevel(name);
+ }
+
+ Anope::string AccessSerialize() override
+ {
+ return stringify(this->GetLevel());
+ }
+
+ void AccessUnserialize(const Anope::string &data) override
+ {
+ try
+ {
+ this->SetLevel(convertTo<int>(data));
+ }
+ catch (const ConvertException &)
+ {
+ }
+ }
+
+ bool operator>(ChanServ::ChanAccess &other) override
+ {
+ if (this->GetSerializableType() != other.GetSerializableType())
+ return ChanServ::ChanAccess::operator>(other);
+ else
+ return this->GetLevel() > anope_dynamic_static_cast<AccessChanAccess *>(&other)->GetLevel();
+ }
+
+ bool operator<(ChanServ::ChanAccess &other) override
+ {
+ if (this->GetSerializableType() != other.GetSerializableType())
+ return ChanAccess::operator<(other);
+ else
+ return this->GetLevel() < anope_dynamic_static_cast<AccessChanAccess *>(&other)->GetLevel();
+ }
+};
+
+class AccessChanAccessType : public ChanAccessType<AccessChanAccessImpl>
+{
+ public:
+ Serialize::Field<AccessChanAccessImpl, int> level;
+
+ AccessChanAccessType(Module *me) : ChanAccessType<AccessChanAccessImpl>(me)
+ , level(this, "level", &AccessChanAccessImpl::level)
+ {
+ Serialize::SetParent(AccessChanAccess::NAME, ChanServ::ChanAccess::NAME);
+ }
+};
+
+int AccessChanAccessImpl::GetLevel()
+{
+ return Get(&AccessChanAccessType::level);
+}
+
+void AccessChanAccessImpl::SetLevel(const int &i)
+{
+ Object::Set(&AccessChanAccessType::level, i);
+}
+
+class CommandCSAccess : public Command
+{
+ void DoAdd(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ Anope::string mask = params[2];
+ ChanServ::Privilege *p = NULL;
+ int level = ChanServ::ACCESS_INVALID;
+
+ try
+ {
+ level = convertTo<int>(params[3]);
+ }
+ catch (const ConvertException &)
+ {
+ p = ChanServ::service ? ChanServ::service->FindPrivilege(params[3]) : nullptr;
+ if (p != NULL && p->level)
+ level = p->level;
+ }
+
+ if (!level)
+ {
+ source.Reply(_("Access level must be non-zero."));
+ return;
+ }
+
+ if (level <= ChanServ::ACCESS_INVALID || level >= ChanServ::ACCESS_FOUNDER)
+ {
+ source.Reply(_("Access level must be between \002{0}\002 and \002{1}\002 inclusive."), ChanServ::ACCESS_INVALID + 1, ChanServ::ACCESS_FOUNDER - 1);
+ return;
+ }
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+ ChanServ::ChanAccess *highest = u_access.Highest();
+
+ AccessChanAccess *access = Serialize::New<AccessChanAccess *>();
+ access->SetChannel(ci);
+ access->SetLevel(level);
+
+ bool override = false;
+
+ if ((!highest || *highest <= *access) && !u_access.founder)
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ {
+ override = true;
+ }
+ else
+ {
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to add someone at level \002{1}\002."), ci->GetName(), level);
+ access->Delete();
+ return;
+ }
+ }
+
+ access->Delete();
+
+ NickServ::Nick *na = NickServ::FindNick(mask);
+
+ if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
+ {
+ source.Reply(_("Masks and unregistered users may not be on access lists."));
+ return;
+ }
+
+ if (mask.find_first_of("!*@") == Anope::string::npos && !na)
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
+ return;
+ }
+ }
+
+ if (na)
+ mask = na->GetNick();
+
+ for (unsigned i = ci->GetAccessCount(); i > 0; --i)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(i - 1);
+ if (mask.equals_ci(access->Mask()))
+ {
+ /* Don't allow lowering from a level >= u_level */
+ if ((!highest || *access >= *highest) && !u_access.founder && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->GetName(), access->Mask());
+ return;
+ }
+ delete access;
+ break;
+ }
+ }
+
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
+ {
+ source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
+ return;
+ }
+
+ access = Serialize::New<AccessChanAccess *>();
+ if (na)
+ access->SetObj(na->GetAccount());
+ access->SetChannel(ci);
+ access->SetMask(mask);
+ access->SetCreator(source.GetNick());
+ access->SetLevel(level);
+ access->SetLastSeen(0);
+ access->SetCreated(Anope::CurTime);
+
+ EventManager::Get()->Dispatch(&Event::AccessAdd::OnAccessAdd, ci, source, access);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level;
+ if (p != NULL)
+ source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 with privilege \002{2}\002 (level \002{3}\002)."), access->Mask(), ci->GetName(), p->name, level);
+ else
+ source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 at level \002{2}\002."), access->Mask(), ci->GetName(), level);
+ }
+
+ void DoDel(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ Anope::string mask = params[2];
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("The access list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickServ::FindNick(mask))
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
+ return;
+ }
+ }
+
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ bool override = !source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/access/modify");
+ Anope::string nicks;
+ bool denied = false;
+ unsigned int deleted = 0;
+
+ NumberList(mask, true,
+ [&](unsigned int num)
+ {
+ if (!num || num > ci->GetAccessCount())
+ return;
+
+ ChanServ::ChanAccess *access = ci->GetAccess(num - 1);
+
+ ChanServ::AccessGroup ag = source.AccessFor(ci);
+ ChanServ::ChanAccess *u_highest = ag.Highest();
+
+ if ((!u_highest || *u_highest <= *access) && !ag.founder && !override && access->GetObj() != source.nc)
+ {
+ denied = true;
+ return;
+ }
+
+ ++deleted;
+ if (!nicks.empty())
+ nicks += ", " + access->Mask();
+ else
+ nicks = access->Mask();
+
+ EventManager::Get()->Dispatch(&Event::AccessDel::OnAccessDel, ci, source, access);
+ delete access;
+ },
+ [&]()
+ {
+ if (denied && !deleted)
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to remove any access entries matching \002{1}\002."));
+ else if (!deleted)
+ source.Reply(_("There are no entries matching \002{0}\002 on the access list of \002{1}\002."), mask, ci->GetName());
+ else
+ {
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << nicks;
+
+ if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from the access list of \002{0}\002."), ci->GetName());
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from the access list of \002{1}\002."), deleted, ci->GetName());
+ }
+ });
+ }
+ else
+ {
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+ ChanServ::ChanAccess *highest = u_access.Highest();
+
+ for (unsigned i = ci->GetAccessCount(); i > 0; --i)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(i - 1);
+ if (mask.equals_ci(access->Mask()))
+ {
+ if (access->GetObj() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify"))
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to remove the access of \002{1}\002."), ci->GetName(), access->Mask());
+ else
+ {
+ source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), access->Mask(), ci->GetName());
+ bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->Mask().equals_ci(source.nc->GetDisplay());
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask();
+
+ EventManager::Get()->Dispatch(&Event::AccessDel::OnAccessDel, ci, source, access);
+ delete access;
+ }
+ return;
+ }
+ }
+
+ source.Reply(_("\002{0}\002 was not found on the access list of \002{1}\002."), mask, ci->GetName());
+ }
+ }
+
+ void ProcessList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params, ListFormatter &list)
+ {
+ const Anope::string &nick = params.size() > 2 ? params[2] : "";
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("The access list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(nick, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > ci->GetAccessCount())
+ return;
+
+ ChanServ::ChanAccess *access = ci->GetAccess(number - 1);
+
+ Anope::string timebuf;
+ if (ci->c)
+ for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
+ {
+ if (access->Matches(cit->second->user, cit->second->user->Account()))
+ timebuf = "Now";
+ }
+ if (timebuf.empty())
+ {
+ if (access->GetLastSeen() == 0)
+ timebuf = "Never";
+ else
+ timebuf = Anope::strftime(access->GetLastSeen(), NULL, true);
+ }
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ entry["Level"] = access->AccessSerialize();
+ entry["Mask"] = access->Mask();
+ entry["By"] = access->GetCreator();
+ entry["Last seen"] = timebuf;
+ list.AddEntry(entry);
+ },
+ [&](){});
+ }
+ else
+ {
+ for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(i);
+
+ if (!nick.empty() && !Anope::Match(access->Mask(), nick))
+ continue;
+
+ Anope::string timebuf;
+ if (ci->c)
+ for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
+ {
+ if (access->Matches(cit->second->user, cit->second->user->Account()))
+ timebuf = "Now";
+ }
+ if (timebuf.empty())
+ {
+ if (access->GetLastSeen() == 0)
+ timebuf = "Never";
+ else
+ timebuf = Anope::strftime(access->GetLastSeen(), NULL, true);
+ }
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Level"] = access->AccessSerialize();
+ entry["Mask"] = access->Mask();
+ entry["By"] = access->GetCreator();
+ entry["Last seen"] = timebuf;
+ list.AddEntry(entry);
+ }
+ }
+
+ if (list.IsEmpty())
+ {
+ source.Reply(_("No matching entries on the access list of \002{0}\002."), ci->GetName());
+ return;
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("Access list for \002{0}\002:"), ci->GetName());
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of access list."));
+ }
+
+ void DoList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("The access list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask"));
+ this->ProcessList(source, ci, params, list);
+ }
+
+ void DoView(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("The access list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Last seen"));
+ this->ProcessList(source, ci, params, list);
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ EventManager::Get()->Dispatch(&Event::AccessClear::OnAccessClear, ci, source);
+
+ ci->ClearAccess();
+
+ source.Reply(_("The access list of \002{0}\002 has been cleared."), ci->GetName());
+
+ bool override = !source.IsFounder(ci);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
+ }
+
+ public:
+ 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"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &cmd = params[1];
+ const Anope::string &nick = params.size() > 2 ? params[2] : "";
+ const Anope::string &s = params.size() > 3 ? params[3] : "";
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
+ bool is_clear = cmd.equals_ci("CLEAR");
+ bool is_del = cmd.equals_ci("DEL");
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+
+ bool has_access = false;
+ if (source.HasPriv("chanserv/access/modify"))
+ has_access = true;
+ else if (is_list && source.HasPriv("chanserv/access/list"))
+ has_access = true;
+ else if (is_list && access.HasPriv("ACCESS_LIST"))
+ has_access = true;
+ else if (access.HasPriv("ACCESS_CHANGE"))
+ has_access = true;
+ else if (is_del)
+ {
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na && na->GetAccount() == source.GetAccount())
+ has_access = true;
+ }
+
+ /* If LIST, we don't *require* any parameters, but we can take any.
+ * If DEL, we require a nick and no level.
+ * Else (ADD), we require a level (which implies a nick). */
+ if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
+ {
+ this->OnSyntaxError(source, cmd);
+ return;
+ }
+
+ if (!has_access)
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), is_list ? "ACCESS_LIST" : "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly && !is_list)
+ {
+ source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
+ return;
+ }
+
+ if (cmd.equals_ci("ADD"))
+ this->DoAdd(source, ci, params);
+ else if (cmd.equals_ci("DEL"))
+ this->DoDel(source, ci, params);
+ else if (cmd.equals_ci("LIST"))
+ this->DoList(source, ci, params);
+ else if (cmd.equals_ci("VIEW"))
+ this->DoView(source, ci, params);
+ else if (cmd.equals_ci("CLEAR"))
+ this->DoClear(source, ci);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("The \002{0} ADD\002 adds \037mask\037 to the access list of \037channel\037 at level \037level\037."
+ " If \037mask\037 is already present on the access list, the access level for it is changed to \037level\037."
+ " The \037level\037 may be a numerical level between \002{1}\002 and \002{2}\002 or the name of a privilege (eg. \002{3}\002)."
+ " The privilege set granted to a given user is the union of the privileges of access entries that match the user."
+ " Use of this command requires the \002{4}\002 privilege on \037channel\037."),
+ source.command, ChanServ::ACCESS_INVALID + 1, ChanServ::ACCESS_FOUNDER - 1, "AUTOOP", "ACCESS_CHANGE");
+
+ if (!Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
+ source.Reply(_("The given \037mask\037 may also be a channel, which will use the access list from the other channel up to the given \037level\037."));
+
+ //XXX show def levels
+
+ source.Reply(_("\n"
+ "Examples:\n"
+ " {command} #anope ADD Adam 9001\n"
+ " Adds \"Adam\" to the access list of \"#anope\" at level \"9001\".\n"
+ "\n"
+ " {command} #anope ADD *!*@anope.org AUTOOP\n"
+ " Adds the host mask \"*!*@anope.org\" to the access list of \"#anope\" with the privilege \"AUTOOP\"."));
+ }
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes \037mask\037 from the access list of \037channel\037."
+ " If a list of entry numbers is given, those entries are deleted."
+ " You may remove yourself from an access list, even if you do not have access to modify that list otherwise."
+ " Use of this command requires the \002{1}\002 privilege on \037channel\037.\n"
+ "\n"
+ "Example:\n"
+ " {command} #anope del DukePyrolator\n"
+ " Removes the access of \"DukePyrolator\" from \"#anope\"."),
+ source.command, "ACCESS_CHANGE");
+ else if (subcommand.equals_ci("LIST") || subcommand.equals_ci("VIEW"))
+ source.Reply(_("The \002{0} LIST\002 and \002{0} VIEW\002 command displays the access list of \037channel\037."
+ " If a wildcard mask is given, only those entries matching the mask are displayed."
+ " If a list of entry numbers is given, only those entries are shown."
+ " \002VIEW\002 is similar to \002LIST\002 but also shows who created the access entry, and when the access entry was last used."
+ " Use of these commands requires the \002{1}\002 privilege on \037channel\037.\n"
+ "\n"
+ "Example:\n"
+ " {0} #anope LIST 2-5,7-9\n"
+ " Lists access entries numbered 2 through 5 and 7 through 9 on #anope."),
+ source.command, "ACCESS_LIST");
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("The \002{0} CLEAR\002 command clears the access list of \037channel\037."
+ " Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ source.command, "FOUNDER");
+
+ else
+ {
+ source.Reply(_("Maintains the access list for \037channel\037. The access list specifies which users are granted which privileges to the channel."
+ " The access system uses numerical levels to represent different sets of privileges. Users who are identified but do not match any entries on"
+ " the access list has a level of 0. Unregistered or unidentified users who do not match any entries have a user level of 0."));
+ ServiceBot *bi;
+ Anope::string name;
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (Command::FindCommandFromService("chanserv/levels", bi, name) && help)
+ source.Reply(_("\n"
+ "Access levels can be configured via the \002{levels}\002 command. See \002{msg}{service} {help} {levels}\002 for more information."),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = bi->nick, "help"_kw = help->cname, "levels"_kw = name);
+
+ if (help)
+ source.Reply(_("\n"
+ "The \002ADD\002 command adds \037mask\037 to the access list at level \037level\037.\n"
+ "Use of this command requires the \002{change}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the access list.\n"
+ "Use of this command requires the \002{change}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002VIEW\002 commands both show the access list for \037channel\037, but \002VIEW\002 also shows who created the access entry, and when the user was last seen.\n"
+ "Use of these commands requires the \002{list}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} [LIST | VIEW]\002 for more information.\n"
+ "\n"
+ "The \002CLEAR\002 command clears the access list."
+ "Use of this command requires the \002{founder}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information."),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "command"_kw = source.command,
+ "help"_kw = help->cname, "change"_kw = "ACCESS_CHANGE", "list"_kw = "ACCESS_LIST", "founder"_kw = "FOUNDER");
+ }
+
+ return true;
+ }
+};
+
+class CommandCSLevels : public Command
+{
+ void DoSet(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &what = params[2];
+ const Anope::string &lev = params[3];
+
+ int level;
+
+ if (lev.equals_ci("FOUNDER"))
+ level = ChanServ::ACCESS_FOUNDER;
+ else
+ {
+ try
+ {
+ level = convertTo<int>(lev);
+ }
+ catch (const ConvertException &)
+ {
+ this->OnSyntaxError(source, "SET");
+ return;
+ }
+ }
+
+ if (level <= ChanServ::ACCESS_INVALID || level > ChanServ::ACCESS_FOUNDER)
+ source.Reply(_("Level must be between \002{0}\002 and \002{1}\002 inclusive."), ChanServ::ACCESS_INVALID + 1, ChanServ::ACCESS_FOUNDER - 1);
+ else
+ {
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(what) : nullptr;
+ if (p == NULL)
+ {
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("There is no such privilege \002{0}\002. See \002{0}{1} {2} {3}\002 for a list of valid settings."),
+ what, Config->StrictPrivmsg, source.service->nick, help->cname, source.command);
+ }
+ else
+ {
+ bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << p->name << " to level " << level;
+
+ ci->SetLevel(p->name, level);
+ EventManager::Get()->Dispatch(&Event::LevelChange::OnLevelChange, source, ci, p->name, level);
+
+ if (level == ChanServ::ACCESS_FOUNDER)
+ source.Reply(_("Level for privilege \002{0}\002 on channel \002{1}\002 changed to \002founder only\002."), p->name, ci->GetName());
+ else
+ source.Reply(_("Level for privilege \002{0}\002 on channel \002{1}\002 changed to \002{3}\002."), p->name, ci->GetName(), level);
+ }
+ }
+ }
+
+ void DoDisable(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &what = params[2];
+
+ /* Don't allow disabling of the founder level. It would be hard to change it back if you don't have access to use this command */
+ if (what.equals_ci("FOUNDER"))
+ {
+ source.Reply(_("You can not disable the founder privilege because it would be impossible to reenable it at a later time."));
+ return;
+ }
+
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(what) : nullptr;
+ if (p != NULL)
+ {
+ bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable " << p->name;
+
+ ci->SetLevel(p->name, ChanServ::ACCESS_INVALID);
+ EventManager::Get()->Dispatch(&Event::LevelChange::OnLevelChange, source, ci, p->name, ChanServ::ACCESS_INVALID);
+
+ source.Reply(_("Privileged \002{0}\002 disabled on channel \002{1}\002."), p->name, ci->GetName());
+ return;
+ }
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("There is no such privilege \002{0}\002. See \002{0}{1} {2} {3}\002 for a list of valid settings."),
+ what, Config->StrictPrivmsg, source.service->nick, help->cname, source.command);
+ }
+
+ void DoList(CommandSource &source, ChanServ::Channel *ci)
+ {
+ if (!ChanServ::service)
+ return;
+
+ source.Reply(_("Access level settings for channel \002{0}\002"), ci->GetName());
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Name")).AddColumn(_("Level"));
+
+ const std::vector<ChanServ::Privilege> &privs = ChanServ::service->GetPrivileges();
+
+ for (unsigned i = 0; i < privs.size(); ++i)
+ {
+ const ChanServ::Privilege &p = privs[i];
+ int16_t j = ci->GetLevel(p.name);
+
+ ListFormatter::ListEntry entry;
+ entry["Name"] = p.name;
+
+ if (j == ChanServ::ACCESS_INVALID)
+ entry["Level"] = Language::Translate(source.GetAccount(), _("(disabled)"));
+ else if (j == ChanServ::ACCESS_FOUNDER)
+ entry["Level"] = Language::Translate(source.GetAccount(), _("(founder only)"));
+ else
+ entry["Level"] = stringify(j);
+
+ list.AddEntry(entry);
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ void DoReset(CommandSource &source, ChanServ::Channel *ci)
+ {
+ bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to reset all levels";
+
+ ci->ClearLevels();
+ EventManager::Get()->Dispatch(&Event::LevelChange::OnLevelChange, source, ci, "ALL", 0);
+
+ source.Reply(_("Levels for \002{0}\002 reset to defaults."), ci->GetName());
+ }
+
+ public:
+ CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4)
+ {
+ this->SetDesc(_("Redefine the meanings of access levels"));
+ this->SetSyntax(_("\037channel\037 SET \037privilege\037 \037level\037"));
+ this->SetSyntax(_("\037channel\037 {DIS | DISABLE} \037privilege\037"));
+ this->SetSyntax(_("\037channel\037 LIST"));
+ this->SetSyntax(_("\037channel\037 RESET"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &cmd = params[1];
+ const Anope::string &what = params.size() > 2 ? params[2] : "";
+ const Anope::string &s = params.size() > 3 ? params[3] : "";
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ bool has_access = false;
+ if (source.HasPriv("chanserv/access/modify"))
+ has_access = true;
+ else if (cmd.equals_ci("LIST") && source.HasPriv("chanserv/access/list"))
+ has_access = true;
+ else if (source.AccessFor(ci).HasPriv("FOUNDER"))
+ has_access = true;
+
+ /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
+ * one; else, we want none.
+ */
+ if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
+ {
+ this->OnSyntaxError(source, cmd);
+ return;
+ }
+
+ if (!has_access)
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly && !cmd.equals_ci("LIST"))
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if (cmd.equals_ci("SET"))
+ this->DoSet(source, ci, params);
+ else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
+ this->DoDisable(source, ci, params);
+ else if (cmd.equals_ci("LIST"))
+ this->DoList(source, ci);
+ else if (cmd.equals_ci("RESET"))
+ this->DoReset(source, ci);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("DESC"))
+ {
+ source.Reply(_("The following privileges are available:"));
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Name")).AddColumn(_("Description"));
+
+ if (ChanServ::service)
+ {
+ const std::vector<ChanServ::Privilege> &privs = ChanServ::service->GetPrivileges();
+ for (unsigned i = 0; i < privs.size(); ++i)
+ {
+ const ChanServ::Privilege &p = privs[i];
+ ListFormatter::ListEntry entry;
+ entry["Name"] = p.name;
+ entry["Description"] = Language::Translate(source.nc, p.desc.c_str());
+ list.AddEntry(entry);
+ }
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ else
+ {
+ ServiceBot *bi;
+ Anope::string name;
+ if (!Command::FindCommandFromService("chanserv/access", bi, name) || bi != source.service)
+ return false;
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (!help)
+ return false;
+
+ source.Reply(_("The \002{0}\002 command allows fine control over the meaning of numeric access levels used in the \002{1}\001 command.\n"
+ "\n"
+ "\002{0} SET\002 allows changing which \037privilege\037 is included in a given \037level\37.\n"
+ "\n"
+ "\002{0} DISABLE\002 disables a privilege and prevents anyone from be granted it, even channel founders."
+ " The \002{2}\002 privilege can not be disabled.\n"
+ "\n"
+ "\002{0} LIST\002 shows the current level for each privilege.\n"
+ "\n"
+ "\002{0} RESET\002 resets the levels to the default levels for newly registered channels.\n"
+ "\n"
+ "For the list of privileges and their descriptions, see \002{3} {4} DESC\002."),
+ source.command, name, "FOUNDER", help->cname, source.command);
+ }
+ return true;
+ }
+};
+
+class CSAccess : public Module
+ , public EventHook<Event::GroupCheckPriv>
+{
+ CommandCSAccess commandcsaccess;
+ CommandCSLevels commandcslevels;
+ AccessChanAccessType accesschanaccesstype;
+
+ public:
+ CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::GroupCheckPriv>(this)
+ , commandcsaccess(this)
+ , commandcslevels(this)
+ , accesschanaccesstype(this)
+ {
+ this->SetPermanent(true);
+
+ }
+
+ EventReturn OnGroupCheckPriv(const ChanServ::AccessGroup *group, const Anope::string &priv) override
+ {
+ if (group->ci == NULL)
+ return EVENT_CONTINUE;
+ /* Special case. Allows a level of -1 to match anyone, and a level of 0 to match anyone identified. */
+ int16_t level = group->ci->GetLevel(priv);
+ if (level == -1)
+ return EVENT_ALLOW;
+ else if (level == 0 && group->nc)
+ return EVENT_ALLOW;
+ return EVENT_CONTINUE;
+ }
+};
+
+template<> void ModuleInfo<CSAccess>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
+MODULE_INIT(CSAccess)
diff --git a/modules/chanserv/akick.cpp b/modules/chanserv/akick.cpp
new file mode 100644
index 000000000..71ea85e73
--- /dev/null
+++ b/modules/chanserv/akick.cpp
@@ -0,0 +1,735 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/akick.h"
+
+class AutoKickImpl : public AutoKick
+{
+ friend class AutoKickType;
+
+ ChanServ::Channel *channel = nullptr;
+ NickServ::Account *account = nullptr;
+ Anope::string mask, reason, creator;
+ time_t addtime = 0, last_time = 0;
+
+ public:
+ AutoKickImpl(Serialize::TypeBase *type) : AutoKick(type) { }
+ AutoKickImpl(Serialize::TypeBase *type, Serialize::ID id) : AutoKick(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *ci) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &mask) override;
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *nc) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &r) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &c) override;
+
+ time_t GetAddTime() override;
+ void SetAddTime(const time_t &t) override;
+
+ time_t GetLastUsed() override;
+ void SetLastUsed(const time_t &t) override;
+};
+
+class AutoKickType : public Serialize::Type<AutoKickImpl>
+{
+ public:
+ Serialize::ObjectField<AutoKickImpl, ChanServ::Channel *> ci;
+
+ Serialize::Field<AutoKickImpl, Anope::string> mask;
+ Serialize::ObjectField<AutoKickImpl, NickServ::Account *> nc;
+
+ Serialize::Field<AutoKickImpl, Anope::string> reason;
+ Serialize::Field<AutoKickImpl, Anope::string> creator;
+ Serialize::Field<AutoKickImpl, time_t> addtime;
+ Serialize::Field<AutoKickImpl, time_t> last_time;
+
+ AutoKickType(Module *me)
+ : Serialize::Type<AutoKickImpl>(me)
+ , ci(this, "ci", &AutoKickImpl::channel, true)
+ , mask(this, "mask", &AutoKickImpl::mask)
+ , nc(this, "nc", &AutoKickImpl::account, true)
+ , reason(this, "reason", &AutoKickImpl::reason)
+ , creator(this, "creator", &AutoKickImpl::creator)
+ , addtime(this, "addtime", &AutoKickImpl::addtime)
+ , last_time(this, "last_time", &AutoKickImpl::last_time)
+ {
+ }
+};
+
+ChanServ::Channel *AutoKickImpl::GetChannel()
+{
+ return Get(&AutoKickType::ci);
+}
+
+void AutoKickImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Set(&AutoKickType::ci, ci);
+}
+
+Anope::string AutoKickImpl::GetMask()
+{
+ return Get(&AutoKickType::mask);
+}
+
+void AutoKickImpl::SetMask(const Anope::string &mask)
+{
+ Set(&AutoKickType::mask, mask);
+}
+
+NickServ::Account *AutoKickImpl::GetAccount()
+{
+ return Get(&AutoKickType::nc);
+}
+
+void AutoKickImpl::SetAccount(NickServ::Account *nc)
+{
+ Set(&AutoKickType::nc, nc);
+}
+
+Anope::string AutoKickImpl::GetReason()
+{
+ return Get(&AutoKickType::reason);
+}
+
+void AutoKickImpl::SetReason(const Anope::string &r)
+{
+ Set(&AutoKickType::reason, r);
+}
+
+Anope::string AutoKickImpl::GetCreator()
+{
+ return Get(&AutoKickType::creator);
+}
+
+void AutoKickImpl::SetCreator(const Anope::string &c)
+{
+ Set(&AutoKickType::creator, c);
+}
+
+time_t AutoKickImpl::GetAddTime()
+{
+ return Get(&AutoKickType::addtime);
+}
+
+void AutoKickImpl::SetAddTime(const time_t &t)
+{
+ Set(&AutoKickType::addtime, t);
+}
+
+time_t AutoKickImpl::GetLastUsed()
+{
+ return Get(&AutoKickType::last_time);
+}
+
+void AutoKickImpl::SetLastUsed(const time_t &t)
+{
+ Set(&AutoKickType::last_time, t);
+}
+
+class CommandCSAKick : public Command
+{
+ void DoAdd(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ Anope::string mask = params[2];
+ Anope::string reason = params.size() > 3 ? params[3] : "";
+ NickServ::Nick *na = NickServ::FindNick(mask);
+ NickServ::Account *nc = NULL;
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
+
+ if (IRCD->IsExtbanValid(mask))
+ ; /* If this is an extban don't try to complete the mask */
+ else if (IRCD->IsChannelValid(mask))
+ {
+ /* Also don't try to complete the mask if this is a channel */
+
+ if (mask.equals_ci(ci->GetName()) && ci->HasFieldS("PEACE"))
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+ }
+ else if (!na)
+ {
+ /* If the mask contains a realname the reason must be prepended with a : */
+ if (mask.find('#') != Anope::string::npos)
+ {
+ size_t r = reason.find(':');
+ if (r != Anope::string::npos)
+ {
+ mask += " " + reason.substr(0, r);
+ mask.trim();
+ reason = reason.substr(r + 1);
+ reason.trim();
+ }
+ else
+ {
+ mask = mask + " " + reason;
+ reason.clear();
+ }
+ }
+
+ Entry e("", mask);
+
+ mask = (e.nick.empty() ? "*" : e.nick) + "!"
+ + (e.user.empty() ? "*" : e.user) + "@"
+ + (e.host.empty() ? "*" : e.host);
+ if (!e.real.empty())
+ mask += "#" + e.real;
+ }
+ else
+ nc = na->GetAccount();
+
+ /* Check excepts BEFORE we get this far */
+ if (ci->c)
+ {
+ std::vector<Anope::string> modes = ci->c->GetModeList("EXCEPT");
+ for (unsigned int i = 0; i < modes.size(); ++i)
+ {
+ if (Anope::Match(modes[i], mask))
+ {
+ source.Reply(_("\002{0}\002 matches an except on \002{1}\002 and cannot be banned until the except has been removed."), mask, ci->GetName());
+ return;
+ }
+ }
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("AKICK");
+ /* Opers overriding get to bypass PEACE */
+ if (override)
+ ;
+ /* These peace checks are only for masks */
+ else if (IRCD->IsChannelValid(mask))
+ ;
+ /* Check whether target nick has equal/higher access
+ * or whether the mask matches a user with higher/equal access - Viper */
+ else if (ci->HasFieldS("PEACE") && nc)
+ {
+ ChanServ::AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
+ if (nc == ci->GetFounder() || nc_access >= u_access)
+ {
+ source.Reply(_("Access denied. You can not auto kick \002{0}\002 because they have more privileges than you on \002{1}\002 and \002{2}\002 is enabled."), nc->GetDisplay(), ci->GetName(), "PEACE");
+ return;
+ }
+ }
+ else if (ci->HasFieldS("PEACE"))
+ {
+#warning "peace"
+#if 0
+ /* Match against all currently online users with equal or
+ * higher access. - Viper */
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u2 = it->second;
+
+ ChanServ::AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
+ Entry entry_mask("", mask);
+
+ if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
+ {
+ source.Reply(ACCESS_DENIED);
+ return;
+ }
+ }
+
+ /* Match against the lastusermask of all nickalias's with equal
+ * or higher access. - Viper */
+ for (nickalias_map::const_iterator it = NickServ::NickList->begin(), it_end = NickServ::NickList->end(); it != it_end; ++it)
+ {
+ na = it->second;
+
+ ChanServ::AccessGroup nc_access = ci->AccessFor(na->GetAccount()), u_access = source.AccessFor(ci);
+ if (na->GetAccount() && (na->GetAccount() == ci->GetFounder() || nc_access >= u_access))
+ {
+ Anope::string buf = na->GetNick() + "!" + na->GetLastUsermask();
+ if (Anope::Match(buf, mask))
+ {
+ source.Reply(ACCESS_DENIED);
+ return;
+ }
+ }
+ }
+#endif
+ }
+
+ for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
+ {
+ AutoKick *ak = ci->GetAkick(j);
+ if (ak->GetAccount() ? ak->GetAccount() == nc : mask.equals_ci(ak->GetMask()))
+ {
+ source.Reply(_("\002{0}\002 already exists on \002{1}\002 autokick list."), ak->GetAccount() ? ak->GetAccount()->GetDisplay() : ak->GetMask(), ci->GetName());
+ return;
+ }
+ }
+
+ if (ci->GetAkickCount() >= Config->GetModule(this->GetOwner())->Get<unsigned>("autokickmax"))
+ {
+ source.Reply(_("Sorry, you can only have \002{0}\002 autokick masks on a channel."), Config->GetModule(this->GetOwner())->Get<unsigned>("autokickmax"));
+ return;
+ }
+
+ AutoKick *ak;
+ if (nc)
+ ak = ci->AddAkick(source.GetNick(), nc, reason);
+ else
+ ak = ci->AddAkick(source.GetNick(), mask, reason);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
+
+ EventManager::Get()->Dispatch(&Event::Akick::OnAkickAdd, source, ci, ak);
+
+ source.Reply(_("\002{0}\002 added to \002{1}\002 autokick list."), mask, ci->GetName());
+
+ this->DoEnforce(source, ci);
+ }
+
+ void DoDel(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &mask = params[2];
+ bool override = !source.AccessFor(ci).HasPriv("AKICK");
+
+ if (!ci->GetAkickCount())
+ {
+ source.Reply(_("The autokick list of \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ /* Special case: is it a number/list? Only do search if it isn't. */
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ unsigned int deleted = 0;
+
+ NumberList(mask, true,
+ [&](unsigned int number)
+ {
+ if (!number || number > ci->GetAkickCount())
+ return;
+
+ AutoKick *ak = ci->GetAkick(number - 1);
+
+ EventManager::Get()->Dispatch(&Event::Akick::OnAkickDel, source, ci, ak);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << (ak->GetAccount() ? ak->GetAccount()->GetDisplay() : ak->GetMask());
+
+ ++deleted;
+ delete ak;
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("There are no entries matching \002{0}\002 on the auto kick list of \002{1}\002."),
+ mask, ci->GetName());
+ else if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from the autokick list of \002{0}\002."), ci->GetName());
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from \002{1}\002 autokick list."), deleted, ci->GetName());
+ });
+ }
+ else
+ {
+ NickServ::Nick *na = NickServ::FindNick(mask);
+ NickServ::Account *nc = na ? na->GetAccount() : nullptr;
+
+ unsigned int i, end;
+ for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
+ {
+ AutoKick *ak = ci->GetAkick(i);
+
+ if (ak->GetAccount() ? ak->GetAccount() == nc : mask.equals_ci(ak->GetMask()))
+ break;
+ }
+
+ if (i == ci->GetAkickCount())
+ {
+ source.Reply(_("\002{0}\002 was not found on the auto kick list of \002{1}\002."), mask, ci->GetName());
+ return;
+ }
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
+
+ EventManager::Get()->Dispatch(&Event::Akick::OnAkickDel, source, ci, ci->GetAkick(i));
+
+ delete ci->GetAkick(i);
+
+ source.Reply(_("\002{0}\002 deleted from the auto kick list of \002{1}\002."), mask, ci->GetName());
+ }
+ }
+
+ void ProcessList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params, ListFormatter &list)
+ {
+ const Anope::string &mask = params.size() > 2 ? params[2] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(mask, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > ci->GetAkickCount())
+ return;
+
+ AutoKick *ak = ci->GetAkick(number - 1);
+
+ Anope::string timebuf, lastused;
+ if (ak->GetAddTime())
+ timebuf = Anope::strftime(ak->GetAddTime(), NULL, true);
+ else
+ timebuf = _("<unknown>");
+ if (ak->GetLastUsed())
+ lastused = Anope::strftime(ak->GetLastUsed(), NULL, true);
+ else
+ lastused = _("<unknown>");
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ if (ak->GetAccount())
+ entry["Mask"] = ak->GetAccount()->GetDisplay();
+ else
+ entry["Mask"] = ak->GetMask();
+ entry["Creator"] = ak->GetCreator();
+ entry["Created"] = timebuf;
+ entry["Last used"] = ak->GetLastUsed();
+ entry["Reason"] = ak->GetReason();
+ list.AddEntry(entry);
+ },
+ []{});
+ }
+ else
+ {
+ for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
+ {
+ AutoKick *ak = ci->GetAkick(i);
+
+ if (!mask.empty())
+ {
+ if (!ak->GetAccount() && !Anope::Match(ak->GetMask(), mask))
+ continue;
+ if (ak->GetAccount() && !Anope::Match(ak->GetAccount()->GetDisplay(), mask))
+ continue;
+ }
+
+ Anope::string timebuf, lastused;
+ if (ak->GetAddTime())
+ timebuf = Anope::strftime(ak->GetAddTime(), NULL, true);
+ else
+ timebuf = _("<unknown>");
+ if (ak->GetLastUsed())
+ lastused = Anope::strftime(ak->GetLastUsed(), NULL, true);
+ else
+ lastused = _("<unknown>");
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ if (ak->GetAccount())
+ entry["Mask"] = ak->GetAccount()->GetDisplay();
+ else
+ entry["Mask"] = ak->GetMask();
+ entry["Creator"] = ak->GetCreator();
+ entry["Created"] = timebuf;
+ entry["Last used"] = lastused;
+ entry["Reason"] = ak->GetReason();
+ list.AddEntry(entry);
+ }
+ }
+
+ if (list.IsEmpty())
+ {
+ source.Reply(_("There are no entries matching \002{0}\002 on the autokick list of \002{1}\002."), mask, ci->GetName());
+ return;
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("Autokick list for \002{0}\002:"), ci->GetName());
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of autokick list."));
+ }
+
+ void DoList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (!ci->GetAkickCount())
+ {
+ source.Reply(_("The autokick list of \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
+ this->ProcessList(source, ci, params, list);
+ }
+
+ void DoView(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (!ci->GetAkickCount())
+ {
+ source.Reply(_("The autokick list of \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Last used")).AddColumn(_("Reason"));
+ this->ProcessList(source, ci, params, list);
+ }
+
+ void DoEnforce(CommandSource &source, ChanServ::Channel *ci)
+ {
+ Channel *c = ci->c;
+ int count = 0;
+
+ if (!c)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ return;
+ }
+
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
+ {
+ ChanUserContainer *uc = it->second;
+ ++it;
+
+ if (c->CheckKick(uc->user))
+ ++count;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("AKICK");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
+
+ source.Reply(_("Autokick enforce for \002{0}\002 complete; \002{1}\002 users were affected."), ci->GetName(), count);
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ bool override = !source.AccessFor(ci).HasPriv("AKICK");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the akick list";
+
+ ci->ClearAkick();
+ source.Reply(_("The autokick list of \002{0}\002 has been cleared."), ci->GetName());
+ }
+
+ public:
+ 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(_("\037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
+ this->SetSyntax(_("\037channel\037 ENFORCE"));
+ this->SetSyntax(_("\037channel\037 CLEAR"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &cmd = params[1];
+ const Anope::string &mask = params.size() > 2 ? params[2] : "";
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
+
+ if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
+ {
+ this->OnSyntaxError(source, cmd);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify") && (!is_list || source.HasPriv("chanserv/access/list")))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "AKICK", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL") || cmd.equals_ci("CLEAR")))
+ {
+ source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
+ return;
+ }
+
+ if (cmd.equals_ci("ADD"))
+ this->DoAdd(source, ci, params);
+ else if (cmd.equals_ci("DEL"))
+ this->DoDel(source, ci, params);
+ else if (cmd.equals_ci("LIST"))
+ this->DoList(source, ci, params);
+ else if (cmd.equals_ci("VIEW"))
+ this->DoView(source, ci, params);
+ else if (cmd.equals_ci("ENFORCE"))
+ this->DoEnforce(source, ci);
+ else if (cmd.equals_ci("CLEAR"))
+ this->DoClear(source, ci);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ source.Reply(_("The \002{0} ADD\002 command adds \037mask\037 to the auto kick list list of \037channel\037."
+ " If \037reason\037 is given, it is used when the user is kicked."
+ " If \037mask\037 is an account, then all users using the account will be affected.\n"
+ "\n"
+ "Examples:\n"
+ " {command} #anope ADD Cronus noob!\n"
+ " Adds the account \"Cronus\" to the auto kick list of \"#anope\" with the reason \"noob!\".\n"
+ "\n"
+ " {command} #anope ADD Guest*!*@*\n"
+ " Adds the mask \"Guest*!*@*\" to the auto kick list of \"#anope\"."),
+ source.command);
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes \037mask\037 from the auto kick list."
+ " It does not, however, remove any bans placed by an auto kick; those must be removed manually.\n"
+ "\n"
+ "Example:\n"
+ " {command} #anope DEL Cronus!\n"
+ " Removes the auto kick for \"Cronus\" from the auto kick list of \"#anope\".\n"),
+ source.command);
+ else if (subcommand.equals_ci("LIST") || subcommand.equals_ci("VIEW"))
+ source.Reply(_("The \002{0} LIST\002 and \002{0} VIEW\002 command displays the auto kick list of \037channel\037."
+ " If a wildcard mask is given, only those entries matching the mask are displayed."
+ " If a list of entry numbers is given, only those entries are shown."
+ " \002VIEW\002 is similar to \002LIST\002 but also shows who created the auto kick entry, when it was created, and when it was last used."
+ "\n"
+ "Example:\n"
+ " \002{0} #anope LIST 2-5,7-9\002\n"
+ " Lists auto kick entries numbered 2 through 5 and 7 through 9 on #anope."),
+ source.command);
+ else if (subcommand.equals_ci("ENFORCE"))
+ source.Reply(_("The \002{0} ENFORCE\002 command enforces the auto kick list by forcibly removing users who match an entry on the auto kick list."
+ "This can be useful if someone does not authenticate or change their host mask until after joining.\n"
+ "\n"
+ "Example:\n"
+ " \002{0} #anope ENFORCE\002\n"
+ " Enforces the auto kick list of #anope."),
+ source.command);
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("The \002{0} CLEAR\002 command clears the auto kick list of \037channel\37. As with the \002DEL\002 command, existing bans placed by auto kick will not be removed.\n"
+ "\n"
+ "Example:\n"
+ " \002{0} #anope CLEAR\002\n"
+ " Clears the auto kick list of #anope."),
+ source.command);
+ else
+ {
+ source.Reply(_("Maintains the auto kick list for \037channel\037."
+ " If a user matching an entry on the auto kick list joins the channel, {0} will place a ban on the user and kick them.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ source.service->nick, "AKICK");
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("\n"
+ "The \002ADD\002 command adds \037nick\037 or \037mask\037 to the auto kick list of \037channel\037.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the auto kick list of \037channel\037.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002VIEW\002 commands both display the auto kick list of \037channel\037, but \002VIEW\002 also displays who created the auto kick entry, when it was created, and when it was last used.\n"
+ "\002{msg}{service} {help} {command} [LIST | VIEW]\002 for more information.\n"
+ "\n"
+ "The \002ENFORCE\002 command enforces the auto kick list by forcibly removing users who match an entry on the auto kick list.\n"
+ "\002{msg}{service} {help} {command} ENFORCE\002 for more information.\n"
+ ""
+ "The \002CLEAR\002 clears the auto kick list of \037channel\037."
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information.\n"),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "help"_kw = help->cname, "command"_kw = source.command);
+ }
+
+ return true;
+ }
+};
+
+class CSAKick : public Module
+ , public EventHook<Event::CheckKick>
+{
+ CommandCSAKick commandcsakick;
+ AutoKickType akick_type;
+
+ public:
+ CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::CheckKick>(this)
+ , commandcsakick(this)
+ , akick_type(this)
+ {
+ }
+
+ EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
+ {
+ if (!c->ci || c->MatchesList(u, "EXCEPT"))
+ return EVENT_CONTINUE;
+
+ for (unsigned j = 0, end = c->ci->GetAkickCount(); j < end; ++j)
+ {
+ AutoKick *ak = c->ci->GetAkick(j);
+ bool kick = false;
+
+ if (ak->GetAccount())
+ kick = ak->GetAccount() == u->Account();
+ else if (IRCD->IsChannelValid(ak->GetMask()))
+ {
+ Channel *chan = Channel::Find(ak->GetMask());
+ kick = chan != NULL && chan->FindUser(u);
+ }
+ else
+ kick = Entry("BAN", ak->GetMask()).Matches(u);
+
+ if (kick)
+ {
+ Log(LOG_DEBUG_2) << u->nick << " matched akick " << (ak->GetAccount() ? ak->GetAccount()->GetDisplay() : ak->GetMask());
+ ak->SetLastUsed(Anope::CurTime);
+ if (!ak->GetAccount() && ak->GetMask().find('#') == Anope::string::npos)
+ mask = ak->GetMask();
+ reason = ak->GetReason();
+ if (reason.empty())
+ {
+ reason = Language::Translate(u, Config->GetModule(this)->Get<Anope::string>("autokickreason"));
+ reason = reason.replace_all_cs("%n", u->nick);
+ reason = reason.replace_all_cs("%c", c->name);
+ }
+ if (reason.empty())
+ reason = Language::Translate(u, _("User has been banned from the channel"));
+ return EVENT_STOP;
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(CSAKick)
diff --git a/modules/chanserv/ban.cpp b/modules/chanserv/ban.cpp
new file mode 100644
index 000000000..c8d9023e3
--- /dev/null
+++ b/modules/chanserv/ban.cpp
@@ -0,0 +1,275 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+static Module *me;
+
+class TempBan : public Timer
+{
+ private:
+ Anope::string channel;
+ Anope::string mask;
+ Anope::string mode;
+
+ public:
+ TempBan(time_t seconds, Channel *c, const Anope::string &banmask, const Anope::string &mod) : Timer(me, seconds), channel(c->name), mask(banmask), mode(mod) { }
+
+ void Tick(time_t ctime) override
+ {
+ Channel *c = Channel::Find(this->channel);
+ if (c)
+ c->RemoveMode(NULL, mode, this->mask);
+ }
+};
+
+class CommandCSBan : public Command
+{
+ public:
+ CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 4)
+ {
+ this->SetDesc(_("Bans a given nick or mask on a channel"));
+ this->SetSyntax(_("\037channel\037 [+\037expiry\037] {\037nick\037 | \037mask\037} [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ Configuration::Block *block = Config->GetCommand(source);
+ const Anope::string &mode = block->Get<Anope::string>("mode", "BAN");
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ Channel *c = ci->c;
+ if (c == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ return;
+ }
+
+ if (IRCD->GetMaxListFor(c) && c->HasMode(mode) >= IRCD->GetMaxListFor(c))
+ {
+ source.Reply(_("The %s list for %s is full."), mode.lower().c_str(), c->name.c_str());
+ return;
+ }
+
+ Anope::string expiry, target, reason;
+ time_t ban_time;
+ if (params[1][0] == '+')
+ {
+ ban_time = Anope::DoTime(params[1]);
+ if (ban_time == -1)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), params[1]);
+ return;
+ }
+ if (params.size() < 3)
+ {
+ this->SendSyntax(source);
+ return;
+ }
+ target = params[2];
+ reason = "Requested";
+ if (params.size() > 3)
+ reason = params[3];
+ }
+ else
+ {
+ ban_time = 0;
+ target = params[1];
+ reason = "Requested";
+ if (params.size() > 2)
+ reason = params[2];
+ if (params.size() > 3)
+ reason += " " + params[3];
+ }
+
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
+
+ Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
+ signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
+
+ User *u = source.GetUser();
+ User *u2 = User::Find(target, true);
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+
+ if (!u_access.HasPriv("BAN") && !source.HasPriv("chanserv/kick"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "BAN", ci->GetName());
+ return;
+ }
+
+ if (u2)
+ {
+ ChanServ::AccessGroup u2_access = ci->AccessFor(u2);
+
+ if (u != u2 && ci->HasFieldS("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
+ {
+ source.Reply(_("Access denied. \002{0}\002 has the same or more privileges than you on \002{1}\002."), u2->nick, ci->GetName());
+ return;
+ }
+
+ /*
+ * Don't ban/kick the user on channels where he is excepted
+ * to prevent services <-> server wars.
+ */
+ if (c->MatchesList(u2, "EXCEPT"))
+ {
+ source.Reply(_("\002{0}\002 matches an except on \002{1}\002 and can not be banned until the except has been removed."), u2->nick, ci->GetName());
+ return;
+ }
+
+ if (u2->IsProtected())
+ {
+ source.Reply(_("Access denied. \002{0}\002 is protected and can not be kicked."), u2->nick);
+ return;
+ }
+
+ Anope::string mask = ci->GetIdealBan(u2);
+
+ bool override = !u_access.HasPriv("BAN") || (u != u2 && ci->HasFieldS("PEACE") && u2_access >= u_access);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
+
+ if (!c->HasMode(mode, mask))
+ {
+ c->SetMode(NULL, mode, mask);
+ if (ban_time)
+ {
+ new TempBan(ban_time, c, mask, mode);
+ source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), mask, Anope::Duration(ban_time, source.GetAccount()));
+ }
+ }
+
+ /* We still allow host banning while not allowing to kick */
+ if (!c->FindUser(u2))
+ return;
+
+ if (block->Get<bool>("kick", "yes"))
+ {
+ if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK")))
+ {
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
+ }
+ else
+ c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
+ }
+ }
+ else
+ {
+ bool founder = u_access.HasPriv("FOUNDER");
+ bool override = !founder && !u_access.HasPriv("BAN");
+
+ Anope::string mask = IRCD->NormalizeMask(target);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
+
+ if (!c->HasMode(mode, mask))
+ {
+ c->SetMode(NULL, mode, mask);
+ if (ban_time)
+ {
+ new TempBan(ban_time, c, mask, mode);
+ source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), mask, Anope::Duration(ban_time, source.GetAccount()));
+ }
+ }
+
+ int matched = 0, kicked = 0;
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
+ {
+ ChanUserContainer *uc = it->second;
+ ++it;
+
+ Entry e(mode, mask);
+ if (e.Matches(uc->user))
+ {
+ ++matched;
+
+ ChanServ::AccessGroup u2_access = ci->AccessFor(uc->user);
+
+ if (matched > 1 && !founder)
+ continue;
+ if (u != uc->user && ci->HasFieldS("PEACE") && u2_access >= u_access)
+ continue;
+ else if (ci->c->MatchesList(uc->user, "EXCEPT"))
+ continue;
+ else if (uc->user->IsProtected())
+ continue;
+
+ if (block->Get<bool>("kick", "yes"))
+ {
+ ++kicked;
+
+ if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
+ {
+ reason += " (Matches " + mask + ")";
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
+ }
+ else
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
+ }
+ }
+ }
+
+ if (matched)
+ source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name);
+ else
+ source.Reply(_("No users on \002{0}\002 match \002{1}\002."), c->name, mask);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Bans a given \037nick\037 or \037mask\037 on \002channel\002. An optional expiry may be given to cause services to remove the ban after a set amount of time.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037.\n"
+ "\n"
+ "Examples:\n"
+ " {command} #anope Jobe\n"
+ " Bans the user \"Jobe\" from \"#anope\".\n"
+ "\n"
+ " {command} #anope Guest!*@*\n"
+ " Bans the mask \"Guest!*@*\" on \"#anope\"."),
+ "BAN");
+ return true;
+ }
+};
+
+class CSBan : public Module
+{
+ CommandCSBan commandcsban;
+
+ public:
+ CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsban(this)
+ {
+ me = this;
+ }
+};
+
+MODULE_INIT(CSBan)
diff --git a/modules/chanserv/clone.cpp b/modules/chanserv/clone.cpp
new file mode 100644
index 000000000..8483b0af3
--- /dev/null
+++ b/modules/chanserv/clone.cpp
@@ -0,0 +1,235 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/botserv/badwords.h"
+#include "modules/chanserv/akick.h"
+
+class CommandCSClone : public Command
+{
+ ServiceReference<BadWords> badwords;
+
+#warning "levels hasnt been merged"
+#if 0
+ void CopyLevels(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
+ {
+ const Anope::map<int16_t> &cilevels = ci->GetLevelEntries();
+
+ for (Anope::map<int16_t>::const_iterator it = cilevels.begin(); it != cilevels.end(); ++it)
+ {
+ target_ci->SetLevel(it->first, it->second);
+ }
+
+ source.Reply(_("All level entries from \002%s\002 have been cloned into \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
+ }
+#endif
+
+public:
+ 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 [\037what\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &channel = params[0];
+ const Anope::string &target = params[1];
+ Anope::string what = params.size() > 2 ? params[2] : "";
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ User *u = source.GetUser();
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ bool override = false;
+
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
+ return;
+ }
+
+ ChanServ::Channel *target_ci = ChanServ::Find(target);
+ if (!target_ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), target);
+ return;
+ }
+
+ if (ci == target_ci)
+ {
+ source.Reply(_("Cannot clone channel \002{0}\002 to itself!"), ci->GetName());
+ return;
+ }
+
+ if (!source.IsFounder(ci) || !source.IsFounder(target_ci))
+ {
+ if (!source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have the privilege \002{0}\002 on \002{1}\002 and \002{2}\002."), "FOUNDER", ci->GetName(), target_ci->GetName());
+ return;
+ }
+ else
+ override = true;
+ }
+
+ if (what.equals_ci("ALL"))
+ what.clear();
+
+ if (what.empty())
+ {
+ target_ci->Delete();
+ target_ci = Serialize::New<ChanServ::Channel *>();
+ target_ci->SetName(target);
+ target_ci->SetTimeRegistered(Anope::CurTime);
+ ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
+ map[target_ci->GetName()] = target_ci;
+ target_ci->c = Channel::Find(target_ci->GetName());
+
+ if (ci->GetBot())
+ ci->GetBot()->Assign(u, target_ci);
+ else
+ target_ci->SetBot(nullptr);
+
+ if (target_ci->c)
+ {
+ target_ci->c->ci = target_ci;
+
+ target_ci->c->CheckModes();
+
+ target_ci->c->SetCorrectModes(u, true);
+ }
+
+ if (target_ci->c && !target_ci->c->topic.empty())
+ {
+ target_ci->SetLastTopic(target_ci->GetLastTopic());
+ target_ci->SetLastTopicSetter(target_ci->c->topic_setter);
+ target_ci->SetLastTopicTime(target_ci->c->topic_time);
+ }
+ else
+ {
+ target_ci->SetLastTopicSetter(source.service->nick);
+ }
+
+ EventManager::Get()->Dispatch(&Event::ChanRegistered::OnChanRegistered, target_ci);
+
+ source.Reply(_("All settings from \002{0}\002 have been cloned to \002{0}\002."), channel, target);
+ }
+ else if (what.equals_ci("ACCESS"))
+ {
+ std::set<Anope::string> masks;
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ unsigned count = 0;
+
+ for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
+ masks.insert(target_ci->GetAccess(i)->Mask());
+
+ for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ ChanServ::ChanAccess *taccess = ci->GetAccess(i);
+
+ if (access_max && target_ci->GetAccessCount() >= access_max)
+ break;
+
+ if (masks.count(taccess->Mask()))
+ continue;
+ masks.insert(taccess->Mask());
+
+ ChanServ::ChanAccess *newaccess = anope_dynamic_static_cast<ChanServ::ChanAccess *>(taccess->GetSerializableType()->Create());
+ newaccess->SetChannel(taccess->GetChannel());
+ newaccess->SetMask(taccess->GetMask());
+ newaccess->SetMask(taccess->GetMask());
+ newaccess->SetCreator(taccess->GetCreator());
+ newaccess->SetLastSeen(taccess->GetLastSeen());
+ newaccess->SetCreated(taccess->GetCreated());
+ newaccess->AccessUnserialize(taccess->AccessSerialize());
+
+ ++count;
+ }
+
+ source.Reply(_("\002{0}\002 access entries from \002{1}\002 have been cloned to \002{2}\002."), count, channel, target);
+ }
+ else if (what.equals_ci("AKICK"))
+ {
+ target_ci->ClearAkick();
+ for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
+ {
+ AutoKick *ak = ci->GetAkick(i);
+ if (ak->GetAccount())
+ target_ci->AddAkick(ak->GetCreator(), ak->GetAccount(), ak->GetReason(), ak->GetAddTime(), ak->GetLastUsed());
+ else
+ target_ci->AddAkick(ak->GetCreator(), ak->GetMask(), ak->GetReason(), ak->GetAddTime(), ak->GetLastUsed());
+ }
+
+ source.Reply(_("All auto kick entries from \002{0}\002 have been cloned to \002{1}\002."), channel, target);
+ }
+ else if (what.equals_ci("BADWORDS"))
+ {
+ if (!badwords)
+ {
+ source.Reply(_("All badword entries from \002{0}\002 have been cloned to \002{1}\002."), channel, target); // BotServ doesn't exist/badwords isn't loaded
+ return;
+ }
+
+ badwords->ClearBadWords(target_ci);
+
+ for (unsigned i = 0; i < badwords->GetBadWordCount(ci); ++i)
+ {
+ BadWord *bw = badwords->GetBadWord(ci, i);
+ badwords->AddBadWord(target_ci, bw->GetWord(), bw->GetType());
+ }
+
+ source.Reply(_("All badword entries from \002{0}\002 have been cloned to \002{1}\002."), channel, target);
+ }
+ else
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->GetName();
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Copies all settings, access, akicks, etc. from \037channel\037 to the \037target\037 channel."
+ " If \037what\037 is \002ACCESS\002, \002AKICK\002, or \002BADWORDS\002 then only the respective settings are cloned.\n"
+ "\n"
+ "You must be the founder of \037channel\037 and \037target\037."));
+ return true;
+ }
+};
+
+class CSClone : public Module
+{
+ CommandCSClone commandcsclone;
+
+ public:
+ CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsclone(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSClone)
diff --git a/modules/chanserv/drop.cpp b/modules/chanserv/drop.cpp
new file mode 100644
index 000000000..1bc880ae9
--- /dev/null
+++ b/modules/chanserv/drop.cpp
@@ -0,0 +1,105 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/drop.h"
+
+class CommandCSDrop : public Command
+{
+ public:
+ CommandCSDrop(Module *creator) : Command(creator, "chanserv/drop", 1, 2)
+ {
+ this->SetDesc(_("Cancel the registration of a channel"));
+ this->SetSyntax(_("\037channel\037 \037channel\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Sorry, channel de-registration is temporarily disabled."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (params.size() < 2 || !chan.equals_ci(params[1]))
+ {
+ source.Reply(_("You must enter the channel name twice as a confirmation that you wish to drop \002{0}\002."), ci->GetName());
+ return;
+ }
+
+ if ((ci->HasFieldS("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChanDrop::OnChanDrop, source, ci);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ bool override = (ci->HasFieldS("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"));
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "none") << ")";
+
+ Reference<Channel> c = ci->c;
+ ci->Delete();
+
+ source.Reply(_("Channel \002{0}\002 has been dropped."), chan);
+
+ if (c)
+ c->CheckModes();
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Unregisters \037channel\037. All channel settings will be deleted. As a precaution, you must give the \037channel\037 name twice.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "FOUNDER");
+
+ if (source.HasCommand("chanserv/drop"))
+ source.Reply(_("\n"
+ "As a Services Operator with the command \002{0}\002, you may drop any channel."),
+ "chanserv/drop");
+
+ return true;
+ }
+};
+
+class CSDrop : public Module
+{
+ CommandCSDrop commandcsdrop;
+
+ public:
+ CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsdrop(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSDrop)
diff --git a/modules/commands/cs_enforce.cpp b/modules/chanserv/enforce.cpp
index b9f700284..5a57d3cc2 100644
--- a/modules/commands/cs_enforce.cpp
+++ b/modules/chanserv/enforce.cpp
@@ -1,14 +1,20 @@
-/* ChanServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Original Coder: GeniusDex <geniusdex@anope.org>
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Please read COPYING and README for further details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Send any bug reports to the Anope Coder, as he will be able
- * to deal with it best.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -16,7 +22,7 @@
class CommandCSEnforce : public Command
{
private:
- void DoSecureOps(CommandSource &source, ChannelInfo *ci)
+ void DoSecureOps(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce secureops";
@@ -26,8 +32,8 @@ class CommandCSEnforce : public Command
* part of the code. This way we can enforce SECUREOPS even
* if it's off.
*/
- bool hadsecureops = ci->HasExt("SECUREOPS");
- ci->Extend<bool>("SECUREOPS");
+ bool hadsecureops = ci->HasFieldS("SECUREOPS");
+ ci->SetS<bool>("SECUREOPS", true);
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
@@ -37,12 +43,12 @@ class CommandCSEnforce : public Command
}
if (!hadsecureops)
- ci->Shrink<bool>("SECUREOPS");
+ ci->UnsetS<bool>("SECUREOPS");
- source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
+ source.Reply(_("\002Secureops\002 enforced on \002{0}\002."), ci->GetName());
}
- void DoRestricted(CommandSource &source, ChannelInfo *ci)
+ void DoRestricted(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce restricted";
@@ -61,7 +67,7 @@ class CommandCSEnforce : public Command
}
for (unsigned i = 0; i < users.size(); ++i)
- {
+ {
User *user = users[i];
Anope::string mask = ci->GetIdealBan(user);
@@ -70,10 +76,10 @@ class CommandCSEnforce : public Command
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
- source.Reply(_("Restricted enforced on %s."), ci->name.c_str());
+ source.Reply(_("\002Restricted\002 enforced on \002{0}\002."), ci->GetName());
}
- void DoRegOnly(CommandSource &source, ChannelInfo *ci)
+ void DoRegOnly(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce registered only";
@@ -102,10 +108,10 @@ class CommandCSEnforce : public Command
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
- source.Reply(_("Registered only enforced on %s."), ci->name.c_str());
+ source.Reply(_("\002Registered only\002 enforced on \002{0}\002."), ci->GetName());
}
- void DoSSLOnly(CommandSource &source, ChannelInfo *ci)
+ void DoSSLOnly(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce SSL only";
@@ -119,7 +125,7 @@ class CommandCSEnforce : public Command
if (user->IsProtected())
continue;
- if (!user->HasMode("SSL") && !user->HasExt("ssl"))
+ if (!user->HasMode("SSL") && !user->HasExtOK("ssl"))
users.push_back(user);
}
@@ -134,10 +140,10 @@ class CommandCSEnforce : public Command
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
- source.Reply(_("SSL only enforced on %s."), ci->name.c_str());
+ source.Reply(_("\002SSL only\002 enforced on %s."), ci->GetName().c_str());
}
- void DoBans(CommandSource &source, ChannelInfo *ci)
+ void DoBans(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce bans";
@@ -158,15 +164,15 @@ class CommandCSEnforce : public Command
for (unsigned i = 0; i < users.size(); ++i)
{
User *user = users[i];
-
+
Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
- source.Reply(_("Bans enforced on %s."), ci->name.c_str());
+ source.Reply(_("\002Bans\002 enforced on %s."), ci->GetName().c_str());
}
- void DoLimit(CommandSource &source, ChannelInfo *ci)
+ void DoLimit(CommandSource &source, ChanServ::Channel *ci)
{
bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce limit";
@@ -174,7 +180,7 @@ class CommandCSEnforce : public Command
Anope::string l_str;
if (!ci->c->GetParam("LIMIT", l_str))
{
- source.Reply(_("No limit is set on %s."), ci->name.c_str());
+ source.Reply(_("There is no limit is set on \002{0}\002."), ci->GetName());
return;
}
@@ -187,7 +193,7 @@ class CommandCSEnforce : public Command
}
catch (const ConvertException &)
{
- source.Reply(_("The limit on %s is not valid."), ci->name.c_str());
+ source.Reply(_("The limit on \002{0}\002 is not valid."), ci->GetName());
return;
}
@@ -213,12 +219,12 @@ class CommandCSEnforce : public Command
for (unsigned i = 0; i < users.size(); ++i)
{
User *user = users[i];
-
+
Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
ci->c->Kick(NULL, user, "%s", reason.c_str());
}
- source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size());
+ source.Reply(_("LIMIT enforced on \002{0}\002, \002{1]\002 users removed."), ci->GetName(), users.size());
}
public:
@@ -228,19 +234,31 @@ class CommandCSEnforce : public Command
this->SetSyntax(_("\037channel\037 \037what\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &what = params.size() > 1 ? params[1] : "";
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
if (!ci)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else if (what.equals_ci("SECUREOPS"))
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+
+ if (!ci->c)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002.", "AKICK", ci->GetName());
+ return;
+ }
+
+ if (what.equals_ci("SECUREOPS"))
this->DoSecureOps(source, ci);
else if (what.equals_ci("RESTRICTED"))
this->DoRestricted(source, ci);
@@ -256,23 +274,26 @@ class CommandCSEnforce : public Command
this->OnSyntaxError(source, "");
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n"
- "option indicates what channel to enforce the modes and options\n"
- "on. The \037what\037 option indicates what modes and options to\n"
- "enforce, and can be any of \002SECUREOPS\002, \002RESTRICTED\002, \002REGONLY\002, \002SSLONLY\002,\n"
- "\002BANS\002, or \002LIMIT\002.\n"
- " \n"
- "Use \002SECUREOPS\002 to enforce the SECUREOPS option, even if it is not\n"
- "enabled. Use \002RESTRICTED\002 to enfore the RESTRICTED option, also\n"
- "if it's not enabled. Use \002REGONLY\002 to kick all unregistered users\n"
- "from the channel. Use \002SSLONLY\002 to kick all users not using a secure\n"
- "connection from the channel. \002BANS\002 will enforce bans on the channel by\n"
- "kicking users affected by them, and \002LIMIT\002 will kick users until the\n"
- "user count drops below the channel limit, if one is set."));
+ source.Reply(_("Enforce various channel modes and set options on \037channel\037."
+ "\n"
+ "The \002SECUREOPS\002 option enforces SECUREOPS, even if it is not enabled.\n"
+ "See \002/msg ChanServ HELP SET SECUREOPS\002 for information about SECUREOPS.\n" //XXX
+ "\n"
+ "The \002RESTRICTED\002 option enforces RESTRICTED, even if it is not enabled.\n"
+ "See \002/msg ChanServ HELP SET RESTRICTED\002 for information about RESTRICTED.\n" //XXX
+ "\n"
+ "The \002REGONLY\002 option removes all unregistered users.\n"
+ "\n"
+ "The \002SSLONLY\002 option removes all users not using a secure connection.\n"
+ "\n"
+ "The \002BANS\002 option enforces bans on the channel by removing users affected by then.\n"
+ "\n"
+ "The \002LIMIT\002 option will remove users until the user count drops below the channel limit, if one is set.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege."),
+ "AKICK");
return true;
}
};
@@ -282,8 +303,8 @@ class CSEnforce : public Module
CommandCSEnforce commandcsenforce;
public:
- CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsenforce(this)
+ CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsenforce(this)
{
}
diff --git a/modules/chanserv/entrymsg.cpp b/modules/chanserv/entrymsg.cpp
new file mode 100644
index 000000000..b607ba399
--- /dev/null
+++ b/modules/chanserv/entrymsg.cpp
@@ -0,0 +1,285 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/entrymsg.h"
+
+class EntryMsgImpl : public EntryMsg
+{
+ friend class EntryMsgType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string creator, message;
+ time_t when = 0;
+
+ public:
+ EntryMsgImpl(Serialize::TypeBase *type) : EntryMsg(type) { }
+ EntryMsgImpl(Serialize::TypeBase *type, Serialize::ID id) : EntryMsg(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *ci) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &c) override;
+
+ Anope::string GetMessage() override;
+ void SetMessage(const Anope::string &m) override;
+
+ time_t GetWhen() override;
+ void SetWhen(const time_t &t) override;
+};
+
+class EntryMsgType : public Serialize::Type<EntryMsgImpl>
+{
+ public:
+ Serialize::ObjectField<EntryMsgImpl, ChanServ::Channel *> chan;
+ Serialize::Field<EntryMsgImpl, Anope::string> creator, message;
+ Serialize::Field<EntryMsgImpl, time_t> when;
+
+ EntryMsgType(Module *me) : Serialize::Type<EntryMsgImpl>(me)
+ , chan(this, "chan", &EntryMsgImpl::channel, true)
+ , creator(this, "creator", &EntryMsgImpl::creator)
+ , message(this, "message", &EntryMsgImpl::message)
+ , when(this, "when", &EntryMsgImpl::when)
+ {
+ }
+};
+
+ChanServ::Channel *EntryMsgImpl::GetChannel()
+{
+ return Get(&EntryMsgType::chan);
+}
+
+void EntryMsgImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Set(&EntryMsgType::chan, ci);
+}
+
+Anope::string EntryMsgImpl::GetCreator()
+{
+ return Get(&EntryMsgType::creator);
+}
+
+void EntryMsgImpl::SetCreator(const Anope::string &c)
+{
+ Set(&EntryMsgType::creator, c);
+}
+
+Anope::string EntryMsgImpl::GetMessage()
+{
+ return Get(&EntryMsgType::message);
+}
+
+void EntryMsgImpl::SetMessage(const Anope::string &m)
+{
+ Set(&EntryMsgType::message, m);
+}
+
+time_t EntryMsgImpl::GetWhen()
+{
+ return Get(&EntryMsgType::when);
+}
+
+void EntryMsgImpl::SetWhen(const time_t &t)
+{
+ Set(&EntryMsgType::when, t);
+}
+
+class CommandEntryMessage : public Command
+{
+ private:
+ void DoList(CommandSource &source, ChanServ::Channel *ci)
+ {
+ std::vector<EntryMsg *> messages = ci->GetRefs<EntryMsg *>();
+
+ if (messages.empty())
+ {
+ source.Reply(_("Entry message list for \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ source.Reply(_("Entry message list for \002{0}\002:"), ci->GetName());
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Message"));
+ for (unsigned i = 0; i < messages.size(); ++i)
+ {
+ EntryMsg *msg = messages[i];
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Creator"] = msg->GetCreator();
+ entry["Created"] = Anope::strftime(msg->GetWhen(), NULL, true);
+ entry["Message"] = msg->GetMessage();
+ list.AddEntry(entry);
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of entry message list."));
+ }
+
+ void DoAdd(CommandSource &source, ChanServ::Channel *ci, const Anope::string &message)
+ {
+ std::vector<EntryMsg *> messages = ci->GetRefs<EntryMsg *>();
+
+ if (messages.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("maxentries"))
+ {
+ source.Reply(_("The entry message list for \002{0}\002 is full."), ci->GetName());
+ return;
+ }
+
+ EntryMsg *msg = Serialize::New<EntryMsg *>();
+ msg->SetChannel(ci);
+ msg->SetCreator(source.GetNick());
+ msg->SetMessage(message);
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
+ source.Reply(_("Entry message added to \002{0}\002"), ci->GetName());
+ }
+
+ void DoDel(CommandSource &source, ChanServ::Channel *ci, const Anope::string &message)
+ {
+ std::vector<EntryMsg *> messages = ci->GetRefs<EntryMsg *>();
+
+ if (!message.is_pos_number_only())
+ source.Reply(("Entry message \002{0}\002 not found on channel \002{1}\002."), message, ci->GetName());
+ else if (messages.empty())
+ source.Reply(_("Entry message list for \002{0}\002 is empty."), ci->GetName());
+ else
+ {
+ try
+ {
+ unsigned i = convertTo<unsigned>(message);
+ if (i > 0 && i <= messages.size())
+ {
+ messages[i - 1]->Delete();
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
+ source.Reply(_("Entry message \002{0}\002 for \002{1]\002 deleted."), i, ci->GetName());
+ }
+ else
+ throw ConvertException();
+ }
+ catch (const ConvertException &)
+ {
+ source.Reply(_("Entry message \002{0}\002 not found on channel \002{1}\002."), message, ci->GetName());
+ }
+ }
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ for (EntryMsg *e : ci->GetRefs<EntryMsg *>())
+ delete e;
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
+ source.Reply(_("Entry messages for \002{0}\002 have been cleared."), ci->GetName());
+ }
+
+ public:
+ CommandEntryMessage(Module *creator) : Command(creator, "chanserv/entrymsg", 2, 3)
+ {
+ this->SetDesc(_("Manage the channel's entry messages"));
+ this->SetSyntax(_("\037channel\037 ADD \037message\037"));
+ this->SetSyntax(_("\037channel\037 DEL \037num\037"));
+ this->SetSyntax(_("\037channel\037 LIST"));
+ this->SetSyntax(_("\037channel\037 CLEAR"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (Anope::ReadOnly && !params[1].equals_ci("LIST"))
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ if (params[1].equals_ci("LIST"))
+ this->DoList(source, ci);
+ else if (params[1].equals_ci("CLEAR"))
+ this->DoClear(source, ci);
+ else if (params.size() < 3)
+ this->OnSyntaxError(source, "");
+ else if (params[1].equals_ci("ADD"))
+ this->DoAdd(source, ci, params[2]);
+ else if (params[1].equals_ci("DEL"))
+ this->DoDel(source, ci, params[2]);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Controls what messages will be sent to users when they join \037channel\037.\n"
+ "\n"
+ "The \002{0} ADD\002 command adds the given message to the list of messages to be shown to users when they join the channel.\n"
+ "\n"
+ "The \002{0} DEL\002 command removes the given message from the entry message list.\n"
+ " You can remove the message by specifying its number which you can get by listing the messages as explained below.\n"
+ "\n"
+ "The \002{0} LIST\002 command displays the list of messages on the entry message list.\n"
+ "\n"
+ "The \002{0} CLEAR\002 command clears the entry message list.\n"
+ "\n"
+ "Use of this command requires the \002SET\002 privilege on \037channel\037."),
+ source.command);
+ return true;
+ }
+};
+
+class CSEntryMessage : public Module
+ , public EventHook<Event::JoinChannel>
+{
+ CommandEntryMessage commandentrymsg;
+ EntryMsgType entrymsg_type;
+
+ public:
+ CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::JoinChannel>(this)
+ , commandentrymsg(this)
+ , entrymsg_type(this)
+ {
+ }
+
+ void OnJoinChannel(User *u, Channel *c) override
+ {
+ if (u && c && c->ci && u->server->IsSynced())
+ for (EntryMsg *msg : c->ci->GetRefs<EntryMsg *>())
+ u->SendMessage(c->ci->WhoSends(), "[{0}] {1}", c->ci->GetName(), msg->GetMessage());
+ }
+};
+
+MODULE_INIT(CSEntryMessage)
diff --git a/modules/chanserv/flags.cpp b/modules/chanserv/flags.cpp
new file mode 100644
index 000000000..5f3212481
--- /dev/null
+++ b/modules/chanserv/flags.cpp
@@ -0,0 +1,541 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/* Dependencies: anope_chanserv.main */
+
+#include "module.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/access.h"
+#include "modules/chanserv/main/chanaccess.h"
+#include "main/chanaccesstype.h"
+
+static std::map<Anope::string, char> defaultFlags;
+
+class FlagsChanAccessImpl : public FlagsChanAccess
+{
+ friend class FlagsChanAccessType;
+
+ Anope::string flags;
+
+ public:
+ using FlagsChanAccess::FlagsChanAccess;
+
+ const Anope::string &GetFlags() override;
+ void SetFlags(const Anope::string &) override;
+
+ bool HasPriv(const Anope::string &priv) override
+ {
+ std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
+ return it != defaultFlags.end() && GetFlags().find(it->second) != Anope::string::npos;
+ }
+
+ Anope::string AccessSerialize() override
+ {
+ return GetFlags();
+ }
+
+ void AccessUnserialize(const Anope::string &data) override
+ {
+ SetFlags(data);
+ }
+
+ static Anope::string DetermineFlags(ChanServ::ChanAccess *access)
+ {
+ if (access->GetSerializableType()->GetName() != NAME)
+ return access->AccessSerialize();
+
+ std::set<char> buffer;
+
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ if (access->HasPriv(it->first))
+ buffer.insert(it->second);
+
+ if (buffer.empty())
+ return "(none)";
+ else
+ return Anope::string(buffer.begin(), buffer.end());
+ }
+};
+
+class FlagsChanAccessType : public ChanAccessType<FlagsChanAccessImpl>
+{
+ public:
+ Serialize::Field<FlagsChanAccessImpl, Anope::string> flags;
+
+ FlagsChanAccessType(Module *me) : ChanAccessType<FlagsChanAccessImpl>(me)
+ , flags(this, "flags", &FlagsChanAccessImpl::flags)
+ {
+ Serialize::SetParent(FlagsChanAccess::NAME, ChanServ::ChanAccess::NAME);
+ }
+};
+
+const Anope::string &FlagsChanAccessImpl::GetFlags()
+{
+ return Get(&FlagsChanAccessType::flags);
+}
+
+void FlagsChanAccessImpl::SetFlags(const Anope::string &i)
+{
+ Object::Set(&FlagsChanAccessType::flags, i);
+}
+
+class CommandCSFlags : public Command
+{
+ void DoModify(CommandSource &source, ChanServ::Channel *ci, Anope::string mask, const Anope::string &flags)
+ {
+ if (flags.empty())
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+ ChanServ::ChanAccess *highest = u_access.Highest();
+
+ NickServ::Nick *na = nullptr;
+ ChanServ::Channel *targ_ci = nullptr;
+
+ if (IRCD->IsChannelValid(mask))
+ {
+ if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
+ {
+ source.Reply(_("Channels may not be on access lists."));
+ return;
+ }
+
+ targ_ci = ChanServ::Find(mask);
+ if (targ_ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), mask);
+ return;
+ }
+ else if (ci == targ_ci)
+ {
+ source.Reply(_("You can't add a channel to its own access list."));
+ return;
+ }
+
+ mask = targ_ci->GetName();
+ }
+ else
+ {
+ na = NickServ::FindNick(mask);
+ if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
+ {
+ source.Reply(_("Masks and unregistered users may not be on access lists."));
+ return;
+ }
+ else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
+ return;
+ }
+ }
+
+ if (na)
+ mask = na->GetNick();
+ }
+
+ ChanServ::ChanAccess *current = NULL;
+ unsigned current_idx;
+ std::set<char> current_flags;
+ bool override = false;
+ for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(current_idx - 1);
+ if ((na && na->GetAccount() == access->GetAccount()) || mask.equals_ci(access->Mask()))
+ {
+ // Flags allows removing others that have the same access as you,
+ // but no other access system does.
+ if (highest && highest->GetSerializableType()->GetName() != "FlagsChanAccess" && !u_access.founder)
+ // operator<= on the non-me entry!
+ if (*highest <= *access)
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ override = true;
+ else
+ {
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to modify the access of \002{1}\002."), ci->GetName(), access->Mask());
+ return;
+ }
+ }
+
+ current = access;
+ Anope::string cur_flags = FlagsChanAccessImpl::DetermineFlags(access);
+ for (unsigned j = cur_flags.length(); j > 0; --j)
+ current_flags.insert(cur_flags[j - 1]);
+ break;
+ }
+ }
+
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
+ {
+ source.Reply(_("Sorry, you can only have \002{0}\002 access entries on a channel, including access entries from other channels."), access_max);
+ return;
+ }
+
+ ChanServ::Privilege *p = NULL;
+ bool add = true;
+ for (size_t i = 0; i < flags.length(); ++i)
+ {
+ char f = flags[i];
+ switch (f)
+ {
+ case '+':
+ add = true;
+ break;
+ case '-':
+ add = false;
+ break;
+ case '*':
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ {
+ bool has = current_flags.count(it->second);
+ // If we are adding a flag they already have or removing one they don't have, don't bother
+ if (add == has)
+ continue;
+
+ if (!u_access.HasPriv(it->first) && !u_access.founder)
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ override = true;
+ else
+ continue;
+ }
+
+ if (add)
+ current_flags.insert(it->second);
+ else
+ current_flags.erase(it->second);
+ }
+ break;
+ default:
+ p = ChanServ::service ? ChanServ::service->FindPrivilege(flags.substr(i)) : nullptr;
+ if (p != NULL && defaultFlags[p->name])
+ {
+ f = defaultFlags[p->name];
+ i = flags.length();
+ }
+
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ {
+ if (f != it->second)
+ continue;
+ else if (!u_access.HasPriv(it->first) && !u_access.founder)
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ override = true;
+ else
+ {
+ source.Reply(_("You can not set the \002{0}\002 flag."), f);
+ break;
+ }
+ }
+ if (add)
+ current_flags.insert(f);
+ else
+ current_flags.erase(f);
+ break;
+ }
+ }
+ }
+ if (current_flags.empty())
+ {
+ if (current != NULL)
+ {
+ EventManager::Get()->Dispatch(&Event::AccessDel::OnAccessDel, ci, source, current);
+ delete current;
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
+ source.Reply(_("\002{0}\002 removed from the access list of \002{1}\002."), mask, ci->GetName());
+ }
+ else
+ {
+ source.Reply(_("\002{0}\002 not found on the access list of \002{1}\002."), mask, ci->GetName());
+ }
+ return;
+ }
+
+ FlagsChanAccess *access = Serialize::New<FlagsChanAccess *>();
+ if (na)
+ access->SetObj(na->GetAccount());
+ else if (targ_ci)
+ access->SetObj(targ_ci);
+ access->SetChannel(ci);
+ access->SetMask(mask);
+ access->SetCreator(source.GetNick());
+ access->SetLastSeen(current ? current->GetLastSeen() : 0);
+ access->SetCreated(Anope::CurTime);
+ access->SetFlags(Anope::string(current_flags.begin(), current_flags.end()));
+
+ if (current != NULL)
+ delete current;
+
+ EventManager::Get()->Dispatch(&Event::AccessAdd::OnAccessAdd, ci, source, access);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to modify " << mask << "'s flags to " << access->AccessSerialize();
+ if (p != NULL)
+ {
+ if (add)
+ source.Reply(_("Privilege \002{0}\002 added to \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->Mask(), ci->GetName(), access->AccessSerialize());
+ else
+ source.Reply(_("Privilege \002{0}\002 removed from \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->Mask(), ci->GetName(), access->AccessSerialize());
+ }
+ else
+ source.Reply(_("Flags for \002{0}\002 on \002{1}\002 set to +\002{2}\002"), access->Mask(), ci->GetName(), access->AccessSerialize());
+ }
+
+ void DoList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &arg = params.size() > 2 ? params[2] : "";
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("The access list of \002{0}\002 is empty."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Flags")).AddColumn(_("Creator")).AddColumn(_("Created"));
+
+ unsigned count = 0;
+ for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(i);
+ const Anope::string &flags = FlagsChanAccessImpl::DetermineFlags(access);
+
+ if (!arg.empty())
+ {
+ if (arg[0] == '+')
+ {
+ bool pass = true;
+ for (size_t j = 1; j < arg.length(); ++j)
+ if (flags.find(arg[j]) == Anope::string::npos)
+ pass = false;
+ if (pass == false)
+ continue;
+ }
+ else if (!Anope::Match(access->Mask(), arg))
+ continue;
+ }
+
+ ListFormatter::ListEntry entry;
+ ++count;
+ entry["Number"] = stringify(i + 1);
+ entry["Mask"] = access->Mask();
+ entry["Flags"] = flags;
+ entry["Creator"] = access->GetCreator();
+ entry["Created"] = Anope::strftime(access->GetCreated(), source.nc, true);
+ list.AddEntry(entry);
+ }
+
+ if (list.IsEmpty())
+ source.Reply(_("No matching entries on the access list of \002{0}\002."), ci->GetName());
+ else
+ {
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("Flags list for \002{0}\002:"), ci->GetName());
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ if (count == ci->GetAccessCount())
+ source.Reply(_("End of access list."));
+ else
+ source.Reply(_("End of access list - \002{0}/{1}\002 entries shown."), count, ci->GetAccessCount());
+ }
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ ci->ClearAccess();
+
+ EventManager::Get()->Dispatch(&Event::AccessClear::OnAccessClear, ci, source);
+
+ source.Reply(_("The access list of \002{0}\002 has been cleared."), ci->GetName());
+
+ bool override = !source.IsFounder(ci);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
+ }
+
+ public:
+ CommandCSFlags(Module *creator) : Command(creator, "chanserv/flags", 1, 4)
+ {
+ this->SetDesc(_("Modify the list of privileged users"));
+ this->SetSyntax(_("\037channel\037 [MODIFY] \037mask\037 \037changes\037"));
+ this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | +\037flags\037]"));
+ this->SetSyntax(_("\037channel\037 CLEAR"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &cmd = params.size() > 1 ? params[1] : "";
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ bool is_list = cmd.empty() || cmd.equals_ci("LIST");
+ bool has_access = false;
+ if (source.HasPriv("chanserv/access/modify"))
+ has_access = true;
+ else if (is_list && source.HasPriv("chanserv/access/list"))
+ has_access = true;
+ else if (is_list && source.AccessFor(ci).HasPriv("ACCESS_LIST"))
+ has_access = true;
+ else if (source.AccessFor(ci).HasPriv("ACCESS_CHANGE"))
+ has_access = true;
+
+ if (!has_access)
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), is_list ? "ACCESS_LIST" : "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly && !is_list)
+ {
+ source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
+ return;
+ }
+
+ if (is_list)
+ this->DoList(source, ci, params);
+ else if (cmd.equals_ci("CLEAR"))
+ this->DoClear(source, ci);
+ else
+ {
+ Anope::string mask, flags;
+ if (cmd.equals_ci("MODIFY"))
+ {
+ mask = params.size() > 2 ? params[2] : "";
+ flags = params.size() > 3 ? params[3] : "";
+ }
+ else
+ {
+ mask = cmd;
+ flags = params.size() > 2 ? params[2] : "";
+ }
+
+ this->DoModify(source, ci, mask, flags);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("{0} allow granularly granting privileges on channels to users by assigning them flags, which map to one or more privileges.\n"
+ "\n"
+ "The \002MODIFY\002 command allows you to modify the access list."
+ " If \037mask\037 is not already on the access list is it added, then the \037changes\037 are applied."
+ " If the mask has no more flags, then the mask is removed from the access list."
+ " Additionally, you may use +* or -* to add or remove all flags, respectively."
+ " You are only able to modify the access list if you have the \002{1}\002 privilege on the channel, and can only give privileges to up what you have."),
+ source.command, "ACCESS_CHANGE");
+ source.Reply(" ");
+ source.Reply(_("The \002LIST\002 command allows you to list existing entries on the channel access list."
+ " If \037mask\037 is given, the \037mask\037 is wildcard matched against all existing entries on the access list, and only those entries are returned."
+ " If a set of flags is given, only those on the access list with the specified flags are returned."));
+ source.Reply(" ");
+ source.Reply(_("The \002CLEAR\002 command clears the channel access list, which requires being the founder of \037channel\037."));
+ source.Reply(" ");
+ source.Reply(_("\n"
+ "Examples:\n"
+ " {command} #anope MODIFY Attila +fHhu-i\n"
+ " Modifies the flags of \"Attila\" on the access list of \"#anope\" to \"+fHhu-i\".\n"
+ "\n"
+ " {command} #anope MODIFY *!*@anope.org +*\n"
+ " Modifies the flags of the host mask \"*!*@anope.org\" on the access list of \"#anope\" to have all flags."));
+ source.Reply(" ");
+ source.Reply(_("The available flags are:"));
+
+ typedef std::multimap<char, Anope::string, ci::less> reverse_map;
+ reverse_map reverse;
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ reverse.insert(std::make_pair(it->second, it->first));
+
+ for (reverse_map::iterator it = reverse.begin(), it_end = reverse.end(); it != it_end; ++it)
+ {
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(it->second) : nullptr;
+ if (p == NULL)
+ continue;
+ source.Reply(" %c - %s", it->first, Language::Translate(source.nc, p->desc.c_str()));
+ }
+
+ return true;
+ }
+};
+
+class CSFlags : public Module
+{
+ CommandCSFlags commandcsflags;
+ FlagsChanAccessType flagsaccesstype;
+
+ public:
+ CSFlags(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsflags(this)
+ , flagsaccesstype(this)
+ {
+ this->SetPermanent(true);
+
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ defaultFlags.clear();
+
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
+ {
+ Configuration::Block *priv = conf->GetBlock("privilege", i);
+
+ const Anope::string &pname = priv->Get<Anope::string>("name");
+
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(pname) : nullptr;
+ if (p == NULL)
+ continue;
+
+ const Anope::string &value = priv->Get<Anope::string>("flag");
+ if (value.empty())
+ continue;
+
+ defaultFlags[p->name] = value[0];
+ }
+ }
+};
+
+template<> void ModuleInfo<CSFlags>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
+MODULE_INIT(CSFlags)
diff --git a/modules/chanserv/getkey.cpp b/modules/chanserv/getkey.cpp
new file mode 100644
index 000000000..cbcc66720
--- /dev/null
+++ b/modules/chanserv/getkey.cpp
@@ -0,0 +1,83 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandCSGetKey : public Command
+{
+ public:
+ CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
+ {
+ this->SetDesc(_("Returns the key of the given channel"));
+ this->SetSyntax(_("\037channel\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("GETKEY") && !source.HasCommand("chanserv/getkey"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "GETKEY", ci->GetName());
+ return;
+ }
+
+ Anope::string key;
+ if (!ci->c || !ci->c->GetParam("KEY", key))
+ {
+ source.Reply(_("Channel \002{0}\002 does not have a key."), ci->GetName());
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("GETKEY");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
+
+ source.Reply(_("Key for channel \002{0}\002 is \002{1}\002."), ci->GetName(), key);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Returns the key of \037channel\037.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "GETKEY");
+ return true;
+ }
+};
+
+class CSGetKey : public Module
+{
+ CommandCSGetKey commandcsgetkey;
+
+ public:
+ CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsgetkey(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSGetKey)
diff --git a/modules/chanserv/info.cpp b/modules/chanserv/info.cpp
new file mode 100644
index 000000000..43807fb4b
--- /dev/null
+++ b/modules/chanserv/info.cpp
@@ -0,0 +1,101 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/info.h"
+
+class CommandCSInfo : public Command
+{
+ public:
+ CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
+ {
+ this->SetDesc(_("Lists information about the specified registered channel"));
+ this->SetSyntax(_("\037channel\037"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ NickServ::Account *nc = source.nc;
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ bool has_auspex = source.HasPriv("chanserv/auspex");
+ bool show_all = false;
+
+ /* Should we show all fields? Only for sadmins and identified users */
+ if (source.AccessFor(ci).HasPriv("INFO") || has_auspex)
+ show_all = true;
+
+ InfoFormatter info(nc);
+
+ source.Reply(_("Information for channel \002{0}\002:"), ci->GetName());
+ if (ci->GetFounder())
+ info[_("Founder")] = ci->GetFounder()->GetDisplay();
+
+ if (show_all && ci->GetSuccessor())
+ info[_("Successor")] = ci->GetSuccessor()->GetDisplay();
+
+ if (!ci->GetDesc().empty())
+ info[_("Description")] = ci->GetDesc();
+
+ info[_("Registered")] = Anope::strftime(ci->GetTimeRegistered(), source.GetAccount());
+ info[_("Last used")] = Anope::strftime(ci->GetLastUsed(), source.GetAccount());
+
+ if (show_all)
+ {
+ info[_("Ban type")] = stringify(ci->GetBanType());
+ }
+
+ EventManager::Get()->Dispatch(&Event::ChanInfo::OnChanInfo, source, ci, info, show_all);
+
+ std::vector<Anope::string> replies;
+ info.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Shows information about \037channel\037, including its founder, description, time of registration, and last time used."
+ " If the user issuing the command has \002{0}\002 privilege on \037channel\037, then the successor, last topic set, settings and expiration time will also be displayed when applicable."));
+ return true;
+ }
+};
+
+class CSInfo : public Module
+{
+ CommandCSInfo commandcsinfo;
+
+ public:
+ CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsinfo(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSInfo)
diff --git a/modules/chanserv/invite.cpp b/modules/chanserv/invite.cpp
new file mode 100644
index 000000000..b6d0f19c9
--- /dev/null
+++ b/modules/chanserv/invite.cpp
@@ -0,0 +1,117 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandCSInvite : public Command
+{
+ public:
+ CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
+ {
+ this->SetDesc(_("Invites you or an optionally specified nick into a channel"));
+ this->SetSyntax(_("\037channel\037 [\037nick\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ User *u = source.GetUser();
+ Channel *c = Channel::Find(chan);
+
+ if (!c)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), chan);
+ return;
+ }
+
+ ChanServ::Channel *ci = c->ci;
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), c->name);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("INVITE") && !source.HasCommand("chanserv/invite"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "INVITE", ci->GetName());
+ return;
+ }
+
+ User *u2;
+ if (params.size() == 1)
+ u2 = u;
+ else
+ u2 = User::Find(params[1], true);
+
+ if (!u2)
+ {
+ source.Reply(_("\002{0}\002 isn't currently online."), params.size() > 1 ? params[1] : source.GetNick());
+ return;
+ }
+
+ if (c->FindUser(u2))
+ {
+ if (u2 == u)
+ source.Reply(_("You are already in \002{0}\002!"), c->name);
+ else
+ source.Reply(_("\002{0}\002 is already in \002{1}\002!"), u2->nick, c->name);
+
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("INVITE");
+
+ IRCD->SendInvite(ci->WhoSends(), c, u2);
+ if (u2 != u)
+ {
+ source.Reply(_("\002{0}\002 has been invited to \002{1}\002."), u2->nick, c->name);
+ u2->SendMessage(ci->WhoSends(), _("You have been invited to \002{0}\002 by \002{1}\002."), c->name, source.GetNick());
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
+ }
+ else
+ {
+ u2->SendMessage(ci->WhoSends(), _("You have been invited to \002{0}\002."), c->name);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Causes \002{0}\002 to invite you or an optionally specified \037nick\037 to \037channel\037.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ source.service->nick, "INVITE");
+ return true;
+ }
+};
+
+class CSInvite : public Module
+{
+ CommandCSInvite commandcsinvite;
+
+ public:
+ CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsinvite(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSInvite)
diff --git a/modules/chanserv/kick.cpp b/modules/chanserv/kick.cpp
new file mode 100644
index 000000000..b78357d3e
--- /dev/null
+++ b/modules/chanserv/kick.cpp
@@ -0,0 +1,160 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandCSKick : public Command
+{
+ public:
+ CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
+ {
+ this->SetDesc(_("Kicks a specified nick from a channel"));
+ this->SetSyntax(_("\037channel\037 \037user\037 [\037reason\037]"));
+ this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &target = params[1];
+ Anope::string reason = params.size() > 2 ? params[2] : "Requested";
+
+ User *u = source.GetUser();
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
+ Channel *c = Channel::Find(params[0]);
+ User *u2 = User::Find(target, true);
+
+ if (!c)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), chan);
+ return;
+ }
+
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), c->name);
+ return;
+ }
+
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+
+ Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
+ signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
+
+ if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "KICK", ci->GetName());
+ return;
+ }
+
+ if (u2)
+ {
+ ChanServ::AccessGroup u2_access = ci->AccessFor(u2);
+ if (u != u2 && ci->HasFieldS("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
+ source.Reply(_("Access denied. \002{0}\002 has the same or more privileges than you on \002{1}\002."), u2->nick, ci->GetName());
+ else if (u2->IsProtected())
+ source.Reply(_("Access denied. \002{0}\002 is protected and can not be kicked."), u2->nick);
+ else if (!c->FindUser(u2))
+ source.Reply(_("User \002{0}\002 is not on channel \002{1}\002."), u2->nick, c->name);
+ else
+ {
+ bool override = !u_access.HasPriv("KICK") || (u != u2 && ci->HasFieldS("PEACE") && u2_access >= u_access);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
+
+ if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
+ {
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
+ }
+ else
+ c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
+ }
+ }
+ else if (u_access.HasPriv("FOUNDER"))
+ {
+ Anope::string mask = IRCD->NormalizeMask(target);
+
+ Log(LOG_COMMAND, source, this, ci) << "for " << mask;
+
+ int matched = 0, kicked = 0;
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
+ {
+ ChanUserContainer *uc = it->second;
+ ++it;
+
+ Entry e("", mask);
+ if (e.Matches(uc->user))
+ {
+ ++matched;
+
+ ChanServ::AccessGroup u2_access = ci->AccessFor(uc->user);
+ if (u != uc->user && ci->HasFieldS("PEACE") && u2_access >= u_access)
+ continue;
+ else if (uc->user->IsProtected())
+ continue;
+
+ ++kicked;
+
+ if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
+ {
+ reason += " (Matches " + mask + ")";
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
+ }
+ else
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
+ }
+ }
+
+ if (matched)
+ source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name);
+ else
+ source.Reply(_("No users on\002{0}\002 match \002{1}\002."), c->name, mask);
+ }
+ else
+ source.Reply(_("\002{0}\002 isn't currently in use."), target);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Kicks \037user\037 from a \037channel\037. Users with the \002{0}\002 privilege on \037channel\037 may give a \037mask\037, which kicks all users who match the wildcard mask.\n"
+ " \n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ "FOUNDER", "KICK");
+ return true;
+ }
+};
+
+class CSKick : public Module
+{
+ CommandCSKick commandcskick;
+
+ public:
+ CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcskick(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSKick)
diff --git a/modules/chanserv/list.cpp b/modules/chanserv/list.cpp
new file mode 100644
index 000000000..75ffdb67c
--- /dev/null
+++ b/modules/chanserv/list.cpp
@@ -0,0 +1,274 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/info.h"
+#include "modules/chanserv/set.h"
+#include "modules/chanserv/mode.h"
+
+class CommandCSList : public Command
+{
+ ServiceReference<ModeLocks> mlocks;
+
+ public:
+ CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
+ {
+ this->SetDesc(_("Lists all registered channels matching the given pattern"));
+ this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ Anope::string pattern = params[0];
+ unsigned nchans;
+ bool is_servadmin = source.HasCommand("chanserv/list");
+ int count = 0, from = 0, to = 0;
+ bool suspended = false, channoexpire = false;
+
+ if (pattern[0] == '#')
+ {
+ Anope::string n1, n2;
+ sepstream(pattern.substr(1), '-').GetToken(n1, 0);
+ sepstream(pattern, '-').GetToken(n2, 1);
+
+ try
+ {
+ from = convertTo<int>(n1);
+ to = convertTo<int>(n2);
+ }
+ catch (const ConvertException &)
+ {
+ source.Reply(_("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002."));
+ source.Reply(_("To search for channels starting with #, search for the channel name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
+ return;
+ }
+
+ pattern = "*";
+ }
+
+ nchans = 0;
+
+ if (is_servadmin && params.size() > 1)
+ {
+ Anope::string keyword;
+ spacesepstream keywords(params[1]);
+ while (keywords.GetToken(keyword))
+ {
+ if (keyword.equals_ci("SUSPENDED"))
+ suspended = true;
+ if (keyword.equals_ci("NOEXPIRE"))
+ channoexpire = true;
+ }
+ }
+
+ Anope::string spattern = "#" + pattern;
+ unsigned listmax = Config->GetModule(this->GetOwner())->Get<unsigned>("listmax", "50");
+
+ source.Reply(_("List of entries matching \002{0}\002:"), pattern);
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Name")).AddColumn(_("Description"));
+
+ // XXX wtf
+ Anope::map<ChanServ::Channel *> ordered_map;
+ if (ChanServ::service)
+ for (auto& it : ChanServ::service->GetChannels())
+ ordered_map[it.first] = it.second;
+
+ for (Anope::map<ChanServ::Channel *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
+ {
+ ChanServ::Channel *ci = it->second;
+
+ if (!is_servadmin)
+ {
+ if (ci->HasFieldS("CS_PRIVATE") || ci->HasFieldS("CS_SUSPENDED"))
+ continue;
+ if (ci->c && ci->c->HasMode("SECRET"))
+ continue;
+
+ if (mlocks)
+ {
+ ModeLock *secret = mlocks->GetMLock(ci, "SECRET");
+ if (secret && secret->GetSet())
+ continue;
+ }
+ }
+
+ if (suspended && !ci->HasFieldS("CS_SUSPENDED"))
+ continue;
+
+ if (channoexpire && !ci->HasFieldS("CS_NO_EXPIRE"))
+ continue;
+
+ if (pattern.equals_ci(ci->GetName()) || ci->GetName().equals_ci(spattern) || Anope::Match(ci->GetName(), pattern, false, true) || Anope::Match(ci->GetName(), spattern, false, true) || Anope::Match(ci->GetDesc(), pattern, false, true) || Anope::Match(ci->GetLastTopic(), pattern, false, true))
+ {
+ if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
+ {
+ bool isnoexpire = false;
+ if (is_servadmin && (ci->HasFieldS("CS_NO_EXPIRE")))
+ isnoexpire = true;
+
+ ListFormatter::ListEntry entry;
+ entry["Name"] = (isnoexpire ? "!" : "") + ci->GetName();
+ if (ci->HasFieldS("CS_SUSPENDED"))
+ entry["Description"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
+ else
+ entry["Description"] = ci->GetDesc();
+ list.AddEntry(entry);
+ }
+ ++count;
+ }
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of list - \002{0}/{1}\002 matches shown."), nchans > listmax ? listmax : nchans, nchans);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Lists all registered channels matching the given pattern."
+ " Channels with the \002PRIVATE\002 option set will only be displayed to Services Operators with the proper access."
+ " Channels with the \002NOEXPIRE\002 option set will have a \002!\002 prefixed to the channel for Services Operators to see."
+ "\n"
+ "Note that a preceding '#' specifies a range, channel names are to be written without '#'.\n"
+ "\n"
+ "If the SUSPENDED or NOEXPIRE options are given, only channels which, respectively, are SUSPENDED or have the NOEXPIRE flag set will be displayed."
+ " If multiple options are given, all channels matching at least one option will be displayed."
+ " Note that these options are limited to \037Services Operators\037.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ " {0} *anope*\n"
+ " Lists all registered channels with \002anope\002 in their names (case insensitive).\n"
+ "\n"
+ " {0} * NOEXPIRE\n"
+ " Lists all registered channels which have been set to not expire.\n"
+ "\n"
+ " {0} #51-100\n"
+ " Lists all registered channels within the given range (51-100)."));
+
+ if (!Config->GetBlock("options")->Get<Anope::string>("regexengine").empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<Anope::string>("regexengine"));
+ }
+
+ return true;
+ }
+};
+
+class CommandCSSetPrivate : public Command
+{
+ public:
+ CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Hide channel from the LIST command"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, params[1]);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (params[1].equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
+ ci->SetS<bool>("CS_PRIVATE", true);
+ source.Reply(_("Private option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
+ ci->UnsetS<bool>("CS_PRIVATE");
+ source.Reply(_("Private option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "PRIVATE");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Enables or disables the \002private\002 option for a channel."));
+
+ ServiceBot *bi;
+ Anope::string cmd;
+ if (Command::FindCommandFromService("chanserv/list", bi, cmd))
+ source.Reply(_("When \002private\002 is set, the channel will not appear in the \002{0}\002 command of \002{1}\002."), cmd, bi->nick);
+ return true;
+ }
+};
+
+class CSList : public Module
+ , public EventHook<Event::ChanInfo>
+{
+ CommandCSList commandcslist;
+ CommandCSSetPrivate commandcssetprivate;
+
+ Serialize::Field<ChanServ::Channel, bool> priv;
+
+ public:
+ CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanInfo>(this)
+ , commandcslist(this)
+ , commandcssetprivate(this)
+ , priv(this, "CS_PRIVATE")
+ {
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override
+ {
+ if (!show_all)
+ return;
+
+ if (priv.HasExt(ci))
+ info.AddOption(_("Private"));
+ }
+};
+
+MODULE_INIT(CSList)
diff --git a/modules/chanserv/log.cpp b/modules/chanserv/log.cpp
new file mode 100644
index 000000000..b20427bc0
--- /dev/null
+++ b/modules/chanserv/log.cpp
@@ -0,0 +1,466 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/log.h"
+#include "modules/memoserv.h"
+
+class LogSettingImpl : public LogSetting
+{
+ friend class LogSettingType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string service_name, command_service, command_name, method, extra, creator;
+ time_t created = 0;
+
+ public:
+ LogSettingImpl(Serialize::TypeBase *type) : LogSetting(type) { }
+ LogSettingImpl(Serialize::TypeBase *type, Serialize::ID id) : LogSetting(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
+
+ Anope::string GetServiceName() override;
+ void SetServiceName(const Anope::string &) override;
+
+ Anope::string GetCommandService() override;
+ void SetCommandService(const Anope::string &) override;
+
+ Anope::string GetCommandName() override;
+ void SetCommandName(const Anope::string &) override;
+
+ Anope::string GetMethod() override;
+ virtual void SetMethod(const Anope::string &) override;
+
+ Anope::string GetExtra() override;
+ void SetExtra(const Anope::string &) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &) override;
+};
+
+class LogSettingType : public Serialize::Type<LogSettingImpl>
+{
+ public:
+ Serialize::ObjectField<LogSettingImpl, ChanServ::Channel *> ci;
+ Serialize::Field<LogSettingImpl, Anope::string> service_name, command_service, command_name, method, extra, creator;
+ Serialize::Field<LogSettingImpl, time_t> created;
+
+ LogSettingType(Module *me) : Serialize::Type<LogSettingImpl>(me)
+ , ci(this, "ci", &LogSettingImpl::channel, true)
+ , service_name(this, "service_name", &LogSettingImpl::service_name)
+ , command_service(this, "command_service", &LogSettingImpl::command_service)
+ , command_name(this, "command_name", &LogSettingImpl::command_name)
+ , method(this, "method", &LogSettingImpl::method)
+ , extra(this, "extra", &LogSettingImpl::extra)
+ , creator(this, "creator", &LogSettingImpl::creator)
+ , created(this, "created", &LogSettingImpl::created)
+ {
+ }
+};
+
+ChanServ::Channel *LogSettingImpl::GetChannel()
+{
+ return Get(&LogSettingType::ci);
+}
+
+void LogSettingImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Set(&LogSettingType::ci, ci);
+}
+
+Anope::string LogSettingImpl::GetServiceName()
+{
+ return Get(&LogSettingType::service_name);
+}
+
+void LogSettingImpl::SetServiceName(const Anope::string &s)
+{
+ Set(&LogSettingType::service_name, s);
+}
+
+Anope::string LogSettingImpl::GetCommandService()
+{
+ return Get(&LogSettingType::command_service);
+}
+
+void LogSettingImpl::SetCommandService(const Anope::string &s)
+{
+ Set(&LogSettingType::command_service, s);
+}
+
+Anope::string LogSettingImpl::GetCommandName()
+{
+ return Get(&LogSettingType::command_name);
+}
+
+void LogSettingImpl::SetCommandName(const Anope::string &s)
+{
+ Set(&LogSettingType::command_name, s);
+}
+
+Anope::string LogSettingImpl::GetMethod()
+{
+ return Get(&LogSettingType::method);
+}
+
+void LogSettingImpl::SetMethod(const Anope::string &m)
+{
+ Set(&LogSettingType::method, m);
+}
+
+Anope::string LogSettingImpl::GetExtra()
+{
+ return Get(&LogSettingType::extra);
+}
+
+void LogSettingImpl::SetExtra(const Anope::string &e)
+{
+ Set(&LogSettingType::extra, e);
+}
+
+Anope::string LogSettingImpl::GetCreator()
+{
+ return Get(&LogSettingType::creator);
+}
+
+void LogSettingImpl::SetCreator(const Anope::string &creator)
+{
+ Set(&LogSettingType::extra, creator);
+}
+
+time_t LogSettingImpl::GetCreated()
+{
+ return Get(&LogSettingType::created);
+}
+
+void LogSettingImpl::SetCreated(const time_t &t)
+{
+ Set(&LogSettingType::created, t);
+}
+
+class CommandCSLog : public Command
+{
+public:
+ CommandCSLog(Module *creator) : Command(creator, "chanserv/log", 1, 4)
+ {
+ this->SetDesc(_("Configures channel logging settings"));
+ this->SetSyntax(_("\037channel\037"));
+ this->SetSyntax(_("\037channel\037 \037command\037 \037method\037 [\037status\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &channel = params[0];
+
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (params.size() == 1)
+ {
+ std::vector<LogSetting *> ls = ci->GetRefs<LogSetting *>();
+ if (ls.empty())
+ {
+ source.Reply(_("There currently are no logging configurations for \002{0}\002."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Service")).AddColumn(_("Command")).AddColumn(_("Method")).AddColumn("");
+
+ for (unsigned i = 0; i < ls.size(); ++i)
+ {
+ LogSetting *log = ls[i];
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Service"] = log->GetCommandService();
+ entry["Command"] = !log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName();
+ entry["Method"] = log->GetMethod();
+ entry[""] = log->GetExtra();
+ list.AddEntry(entry);
+ }
+
+ source.Reply(_("Log list for \002{0}\002:"), ci->GetName());
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ else if (params.size() > 2)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &command = params[1];
+ const Anope::string &method = params[2];
+ const Anope::string &extra = params.size() > 3 ? params[3] : "";
+
+ size_t sl = command.find('/');
+ if (sl == Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 is not a valid command."), command);
+ return;
+ }
+
+ Anope::string service = command.substr(0, sl),
+ command_name = command.substr(sl + 1);
+ ServiceBot *bi = ServiceBot::Find(service, true);
+
+ Anope::string service_name;
+
+ /* Allow either a command name or a service name. */
+ if (bi && bi->commands.count(command_name))
+ {
+ /* Get service name from command */
+ service_name = bi->commands[command_name].name;
+ }
+ else if (ServiceReference<Command>(command.lower()))
+ {
+ /* This is the service name, don't use any specific command */
+ service_name = command;
+ bi = NULL;
+ command_name.clear();
+ }
+ else
+ {
+ source.Reply(_("\002{0}\002 is not a valid command."), command);
+ return;
+ }
+
+ if (!method.equals_ci("MESSAGE") && !method.equals_ci("NOTICE") && !method.equals_ci("MEMO"))
+ {
+ source.Reply(_("\002%s\002 is not a valid logging method."));
+ return;
+ }
+
+ for (unsigned i = 0; i < extra.length(); ++i)
+ if (ModeManager::GetStatusChar(extra[i]) == 0)
+ {
+ source.Reply(_("\002%c\002 is an unknown status mode."), extra[i]);
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("SET");
+
+ std::vector<LogSetting *> ls = ci->GetRefs<LogSetting *>();
+ for (unsigned i = ls.size(); i > 0; --i)
+ {
+ LogSetting *log = ls[i - 1];
+
+ if (log->GetServiceName() == service_name && log->GetMethod().equals_ci(method) && command_name.equals_ci(log->GetCommandName()))
+ {
+ if (log->GetExtra() == extra)
+ {
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
+ source.Reply(_("Logging for command \002{0}\002 on \002{1}\002 with log method \002{2}{3}{4}\002 has been removed."), !log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName(), !log->GetCommandService().empty() ? log->GetCommandService() : "any service", method, extra.empty() ? "" : " ", extra);
+ delete log;
+ }
+ else
+ {
+ log->SetExtra(extra);
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change logging for " << command << " to method " << method << (extra == "" ? "" : " ") << extra;
+ source.Reply(_("Logging changed for command \002{0}\002 on \002{1}\002, now using log method \002{2}{3}{4]\002."), !log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName(), !log->GetCommandService().empty() ? log->GetCommandService() : "any service", method, extra.empty() ? "" : " ", extra);
+ }
+ return;
+ }
+ }
+
+ LogSetting *log = Serialize::New<LogSetting *>();
+ log->SetChannel(ci);
+ log->SetServiceName(service_name);
+ if (bi)
+ log->SetCommandService(bi->nick);
+ log->SetCommandName(command_name);
+ log->SetMethod(method);
+ log->SetExtra(extra);
+ log->SetCreated(Anope::CurTime);
+ log->SetCreator(source.GetNick());
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to log " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
+
+ source.Reply(_("Logging is now active for command \002{0}\002 on \002{1}\002, using log method \002{2}{3}{4}\002."), !command_name.empty() ? command_name : service_name, bi ? bi->nick : "any service", method, extra.empty() ? "" : " ", extra);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("The {0} command allows users to configure logging settings for \037channel\037."
+ " If no parameters are given this command lists the current logging methods in place on \037channel\037."
+ " Otherwise, \037command\037 must be a command name, and \037method\037 must be one of the following logging methods:\n"
+ "\n"
+ " MESSAGE [status], NOTICE [status], MEMO\n"
+ "\n"
+ "Which are used to message, notice, and memo the channel respectively."
+ " With MESSAGE or NOTICE you must have a service bot assigned to and joined to your channel."
+ " Status may be a channel status such as @ or +.\n"
+ "\n"
+ "To remove a logging method use the same syntax as you would to add it.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."
+ "\n"
+ "Example:\n"
+ " {command} #anope chanserv/access MESSAGE @\n"
+ " Would message any channel operators of \"#anope\" whenever someone used the \"ACCESS\" command on ChanServ for \"#anope\"."),
+ source.command, "SET");
+ return true;
+ }
+};
+
+class CSLog : public Module
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::Log>
+{
+ CommandCSLog commandcslog;
+ LogSettingType logtype;
+ ServiceReference<MemoServ::MemoServService> memoserv;
+
+ struct LogDefault
+ {
+ Anope::string service, command, method;
+ };
+
+ std::vector<LogDefault> defaults;
+
+ public:
+ CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::Log>(this)
+ , commandcslog(this)
+ , logtype(this)
+ {
+
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ defaults.clear();
+
+ for (int i = 0; i < block->CountBlock("default"); ++i)
+ {
+ Configuration::Block *def = block->GetBlock("default", i);
+
+ LogDefault ld;
+
+ ld.service = def->Get<Anope::string>("service");
+ ld.command = def->Get<Anope::string>("command");
+ ld.method = def->Get<Anope::string>("method");
+
+ defaults.push_back(ld);
+ }
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ if (defaults.empty())
+ return;
+
+ for (unsigned i = 0; i < defaults.size(); ++i)
+ {
+ LogDefault &d = defaults[i];
+
+ LogSetting *log = Serialize::New<LogSetting *>();
+ log->SetChannel(ci);
+
+ if (!d.service.empty())
+ {
+ log->SetServiceName(d.service.lower() + "/" + d.command.lower());
+ log->SetCommandService(d.service);
+ log->SetCommandName(d.command);
+ }
+ else
+ log->SetServiceName(d.command);
+
+ spacesepstream sep(d.method);
+ Anope::string method, extra;
+ sep.GetToken(method);
+ extra = sep.GetRemaining();
+
+ log->SetMethod(method);
+ log->SetExtra(extra);
+ log->SetCreated(Anope::CurTime);
+ log->SetCreator(ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "(default)");
+ }
+ }
+
+ void OnLog(::Log *l) override
+ {
+ if (l->type != LOG_COMMAND || l->u == NULL || l->c == NULL || l->ci == NULL || !Me || !Me->IsSynced())
+ return;
+
+ std::vector<LogSetting *> ls = l->ci->GetRefs<LogSetting *>();
+ for (unsigned i = 0; i < ls.size(); ++i)
+ {
+ LogSetting *log = ls[i];
+
+ /* wrong command */
+ if (log->GetServiceName() != l->c->GetName())
+ continue;
+
+ /* if a command name is given check the service and the command */
+ if (!log->GetCommandName().empty())
+ {
+ /* wrong service (only check if not a fantasy command, though) */
+ if (!l->source->c && log->GetCommandService() != l->source->service->nick)
+ continue;
+
+ if (!log->GetCommandName().equals_ci(l->source->command))
+ continue;
+ }
+
+ Anope::string buffer = l->u->nick + " used " + l->source->command.upper() + " " + l->buf.str();
+
+ if (log->GetMethod().equals_ci("MEMO") && memoserv && l->ci->WhoSends() != NULL)
+ memoserv->Send(l->ci->WhoSends()->nick, l->ci->GetName(), buffer, true);
+ else if (l->source->c)
+ /* Sending a channel message or notice in response to a fantasy command */;
+ else if (log->GetMethod().equals_ci("MESSAGE") && l->ci->c)
+ {
+ IRCD->SendPrivmsg(l->ci->WhoSends(), log->GetExtra() + l->ci->c->name, "%s", buffer.c_str());
+#warning "fix idletimes"
+ //l->ci->WhoSends()->lastmsg = Anope::CurTime;
+ }
+ else if (log->GetMethod().equals_ci("NOTICE") && l->ci->c)
+ IRCD->SendNotice(l->ci->WhoSends(), log->GetExtra() + l->ci->c->name, "%s", buffer.c_str());
+ }
+ }
+};
+
+MODULE_INIT(CSLog)
diff --git a/modules/chanserv/main/CMakeLists.txt b/modules/chanserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/chanserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/chanserv/main/chanaccess.cpp b/modules/chanserv/main/chanaccess.cpp
new file mode 100644
index 000000000..bf05cdf8b
--- /dev/null
+++ b/modules/chanserv/main/chanaccess.cpp
@@ -0,0 +1,120 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/main/chanaccess.h"
+#include "chanaccesstype.h"
+
+ChanServ::Channel *ChanAccessImpl::GetChannel()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::ci);
+}
+
+void ChanAccessImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::ci, ci);
+}
+
+Anope::string ChanAccessImpl::GetCreator()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::creator);
+}
+
+void ChanAccessImpl::SetCreator(const Anope::string &c)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::creator, c);
+}
+
+time_t ChanAccessImpl::GetLastSeen()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::last_seen);
+}
+
+void ChanAccessImpl::SetLastSeen(const time_t &t)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::last_seen, t);
+}
+
+time_t ChanAccessImpl::GetCreated()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::created);
+}
+
+void ChanAccessImpl::SetCreated(const time_t &t)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::created, t);
+}
+
+Anope::string ChanAccessImpl::GetMask()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::mask);
+}
+
+void ChanAccessImpl::SetMask(const Anope::string &n)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::mask, n);
+}
+
+Serialize::Object *ChanAccessImpl::GetObj()
+{
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::obj);
+}
+
+void ChanAccessImpl::SetObj(Serialize::Object *o)
+{
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::obj, o);
+}
+
+Anope::string ChanAccessImpl::Mask()
+{
+ if (NickServ::Account *acc = GetAccount())
+ return acc->GetDisplay();
+
+ return GetMask();
+}
+
+NickServ::Account *ChanAccessImpl::GetAccount()
+{
+ if (!GetObj() || GetObj()->GetSerializableType()->GetName() != NickServ::Account::NAME)
+ return nullptr;
+
+ return anope_dynamic_static_cast<NickServ::Account *>(GetObj());
+}
+
+bool ChanAccessImpl::Matches(const User *u, NickServ::Account *acc)
+{
+ if (this->GetAccount())
+ return this->GetAccount() == acc;
+
+ if (u)
+ {
+ bool is_mask = this->Mask().find_first_of("!@?*") != Anope::string::npos;
+ if (is_mask && Anope::Match(u->nick, this->Mask()))
+ return true;
+ else if (Anope::Match(u->GetDisplayedMask(), this->Mask()))
+ return true;
+ }
+
+ if (acc)
+ for (NickServ::Nick *na : acc->GetRefs<NickServ::Nick *>())
+ if (Anope::Match(na->GetNick(), this->Mask()))
+ return true;
+
+ return false;
+}
diff --git a/modules/chanserv/main/chanaccesstype.h b/modules/chanserv/main/chanaccesstype.h
new file mode 100644
index 000000000..c755a7df5
--- /dev/null
+++ b/modules/chanserv/main/chanaccesstype.h
@@ -0,0 +1,42 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+template<typename T>
+class ChanAccessType : public Serialize::Type<T>
+{
+ static_assert(std::is_base_of<ChanServ::ChanAccess, T>::value, "");
+
+ public:
+ Serialize::ObjectField<ChanServ::ChanAccess, ChanServ::Channel *> ci;
+ Serialize::Field<ChanServ::ChanAccess, Anope::string> mask;
+ Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj;
+ Serialize::Field<ChanServ::ChanAccess, Anope::string> creator;
+ Serialize::Field<ChanServ::ChanAccess, time_t> last_seen;
+ Serialize::Field<ChanServ::ChanAccess, time_t> created;
+
+ ChanAccessType(Module *me) : Serialize::Type<T>(me)
+ , ci(this, "ci", &ChanServ::ChanAccess::channel, true)
+ , mask(this, "mask", &ChanServ::ChanAccess::mask)
+ , obj(this, "obj", &ChanServ::ChanAccess::object, true)
+ , creator(this, "creator", &ChanServ::ChanAccess::creator)
+ , last_seen(this, "last_seen", &ChanServ::ChanAccess::last_seen)
+ , created(this, "created", &ChanServ::ChanAccess::created)
+ {
+ }
+};
diff --git a/modules/chanserv/main/channel.cpp b/modules/chanserv/main/channel.cpp
new file mode 100644
index 000000000..67a4c94ec
--- /dev/null
+++ b/modules/chanserv/main/channel.cpp
@@ -0,0 +1,401 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+#include "module.h"
+#include "channeltype.h"
+#include "modules/chanserv/akick.h"
+
+ChannelImpl::~ChannelImpl()
+{
+ ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
+ map.erase(this->GetName());
+}
+
+void ChannelImpl::Delete()
+{
+ EventManager::Get()->Dispatch(&Event::DelChan::OnDelChan, this);
+
+ Log(LOG_DEBUG) << "Deleting channel " << this->GetName();
+
+ if (this->c)
+ {
+ if (this->GetBot() && this->c->FindUser(this->GetBot()))
+ this->GetBot()->Part(this->c);
+
+ /* Parting the service bot can cause the channel to go away */
+
+ if (this->c)
+ {
+ if (this->c && this->c->CheckDelete())
+ this->c->QueueForDeletion();
+
+ this->c = NULL;
+ }
+ }
+
+ return Serialize::Object::Delete();
+}
+
+Anope::string ChannelImpl::GetName()
+{
+ return Get<Anope::string>(&ChannelType::name);
+}
+
+void ChannelImpl::SetName(const Anope::string &name)
+{
+ Set(&ChannelType::name, name);
+}
+
+Anope::string ChannelImpl::GetDesc()
+{
+ return Get(&ChannelType::desc);
+}
+
+void ChannelImpl::SetDesc(const Anope::string &desc)
+{
+ Set(&ChannelType::desc, desc);
+}
+
+time_t ChannelImpl::GetTimeRegistered()
+{
+ return Get(&ChannelType::time_registered);
+}
+
+void ChannelImpl::SetTimeRegistered(const time_t &t)
+{
+ Set(&ChannelType::time_registered, t);
+}
+
+time_t ChannelImpl::GetLastUsed()
+{
+ return Get(&ChannelType::last_used);
+}
+
+void ChannelImpl::SetLastUsed(const time_t &t)
+{
+ Set(&ChannelType::last_used, t);
+}
+
+Anope::string ChannelImpl::GetLastTopic()
+{
+ return Get(&ChannelType::last_topic);
+}
+
+void ChannelImpl::SetLastTopic(const Anope::string &topic)
+{
+ Set(&ChannelType::last_topic, topic);
+}
+
+Anope::string ChannelImpl::GetLastTopicSetter()
+{
+ return Get(&ChannelType::last_topic_setter);
+}
+
+void ChannelImpl::SetLastTopicSetter(const Anope::string &setter)
+{
+ Set(&ChannelType::last_topic_setter, setter);
+}
+
+time_t ChannelImpl::GetLastTopicTime()
+{
+ return Get(&ChannelType::last_topic_time);
+}
+
+void ChannelImpl::SetLastTopicTime(const time_t &t)
+{
+ Set(&ChannelType::last_topic_time, t);
+}
+
+int16_t ChannelImpl::GetBanType()
+{
+ return Get(&ChannelType::bantype);
+}
+
+void ChannelImpl::SetBanType(const int16_t &i)
+{
+ Set(&ChannelType::bantype, i);
+}
+
+time_t ChannelImpl::GetBanExpire()
+{
+ return Get(&ChannelType::banexpire);
+}
+
+void ChannelImpl::SetBanExpire(const time_t &t)
+{
+ Set(&ChannelType::banexpire, t);
+}
+
+BotInfo *ChannelImpl::GetBI()
+{
+ return Get(&ChannelType::bi);
+}
+
+void ChannelImpl::SetBI(BotInfo *bi)
+{
+ Set(&ChannelType::bi, bi);
+}
+
+ServiceBot *ChannelImpl::GetBot()
+{
+ BotInfo *bi = GetBI();
+ return bi ? bi->bot : nullptr;
+}
+
+void ChannelImpl::SetBot(ServiceBot *bi)
+{
+ SetBI(bi->bi);
+}
+
+MemoServ::MemoInfo *ChannelImpl::GetMemos()
+{
+ return GetRef<MemoServ::MemoInfo *>();
+}
+
+void ChannelImpl::SetFounder(NickServ::Account *nc)
+{
+ Set(&ChannelType::founder, nc);
+}
+
+NickServ::Account *ChannelImpl::GetFounder()
+{
+ return Get(&ChannelType::founder);
+}
+
+void ChannelImpl::SetSuccessor(NickServ::Account *nc)
+{
+ Set(&ChannelType::successor, nc);
+}
+
+NickServ::Account *ChannelImpl::GetSuccessor()
+{
+ return Get(&ChannelType::successor);
+}
+
+ChanServ::ChanAccess *ChannelImpl::GetAccess(unsigned index)
+{
+ std::vector<ChanServ::ChanAccess *> a = GetRefs<ChanServ::ChanAccess *>();
+ return a.size() > index ? a[index] : nullptr;
+}
+
+ChanServ::AccessGroup ChannelImpl::AccessFor(const User *u, bool updateLastUsed)
+{
+ ChanServ::AccessGroup group;
+
+ if (u == NULL)
+ return group;
+
+ const NickServ::Account *nc = u->Account();
+ if (nc == NULL && !this->HasFieldS("NS_SECURE") && u->IsRecognized())
+ {
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (na != NULL)
+ nc = na->GetAccount();
+ }
+
+ group.super_admin = u->super_admin;
+ group.founder = IsFounder(u);
+ group.ci = this;
+ group.nc = nc;
+
+ for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
+ {
+ ChanServ::ChanAccess *a = this->GetAccess(i);
+ if (a->Matches(u, u->Account()))
+ group.push_back(a);
+ }
+
+ if (group.founder || !group.empty())
+ {
+ if (updateLastUsed)
+ this->SetLastUsed(Anope::CurTime);
+
+ for (unsigned i = 0; i < group.size(); ++i)
+ group[i]->SetLastSeen(Anope::CurTime);
+ }
+
+ return group;
+}
+
+ChanServ::AccessGroup ChannelImpl::AccessFor(NickServ::Account *nc, bool updateLastUsed)
+{
+ ChanServ::AccessGroup group;
+
+ group.founder = GetFounder() && GetFounder() == nc;
+ group.ci = this;
+ group.nc = nc;
+
+ for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
+ {
+ ChanServ::ChanAccess *a = this->GetAccess(i);
+ if (a->Matches(NULL, nc))
+ group.push_back(a);
+ }
+
+ if (group.founder || !group.empty())
+ if (updateLastUsed)
+ this->SetLastUsed(Anope::CurTime);
+
+ /* don't update access last seen here, this isn't the user requesting access */
+
+ return group;
+}
+
+unsigned ChannelImpl::GetAccessCount()
+{
+ return GetRefs<ChanServ::ChanAccess *>().size();
+}
+
+void ChannelImpl::ClearAccess()
+{
+ for (ChanServ::ChanAccess *a : GetRefs<ChanServ::ChanAccess *>())
+ a->Delete();
+}
+
+AutoKick *ChannelImpl::AddAkick(const Anope::string &user, NickServ::Account *akicknc, const Anope::string &reason, time_t t, time_t lu)
+{
+ AutoKick *ak = Serialize::New<AutoKick *>();
+ ak->SetChannel(this);
+ ak->SetAccount(akicknc);
+ ak->SetReason(reason);
+ ak->SetCreator(user);
+ ak->SetAddTime(t);
+ ak->SetLastUsed(lu);
+
+ return ak;
+}
+
+AutoKick *ChannelImpl::AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t, time_t lu)
+{
+ AutoKick *ak = Serialize::New<AutoKick *>();
+ ak->SetChannel(this);
+ ak->SetMask(mask);
+ ak->SetReason(reason);
+ ak->SetCreator(user);
+ ak->SetAddTime(t);
+ ak->SetLastUsed(lu);
+
+ return ak;
+}
+
+AutoKick *ChannelImpl::GetAkick(unsigned index)
+{
+ std::vector<AutoKick *> a = GetRefs<AutoKick *>();
+ return a.size() > index ? a[index] : nullptr;
+}
+
+unsigned ChannelImpl::GetAkickCount()
+{
+ std::vector<AutoKick *> t = GetRefs<AutoKick *>();
+ return t.size();
+}
+
+void ChannelImpl::ClearAkick()
+{
+ for (AutoKick *ak : GetRefs<AutoKick *>())
+ ak->Delete();
+}
+
+int16_t ChannelImpl::GetLevel(const Anope::string &priv)
+{
+ for (ChanServ::Level *l : this->GetRefs<ChanServ::Level *>())
+ if (l->GetName() == priv)
+ return l->GetLevel();
+
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(priv) : nullptr;
+ if (!p)
+ {
+ Log(LOG_DEBUG) << "Unknown privilege " + priv;
+ return ChanServ::ACCESS_INVALID;
+ }
+
+ return p->level;
+}
+
+void ChannelImpl::SetLevel(const Anope::string &priv, int16_t level)
+{
+ for (ChanServ::Level *l : this->GetRefs<ChanServ::Level *>())
+ if (l->GetName() == priv)
+ {
+ l->SetLevel(level);
+ return;
+ }
+
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(priv) : nullptr;
+ if (!p)
+ {
+ Log(LOG_DEBUG) << "Unknown privilege " + priv;
+ return;
+ }
+
+ ChanServ::Level *l = Serialize::New<ChanServ::Level *>();
+ l->SetChannel(this);
+ l->SetName(priv);
+ l->SetLevel(level);
+}
+
+void ChannelImpl::RemoveLevel(const Anope::string &priv)
+{
+ for (ChanServ::Level *l : this->GetRefs<ChanServ::Level *>())
+ if (l->GetName() == priv)
+ {
+ l->Delete();
+ return;
+ }
+}
+
+void ChannelImpl::ClearLevels()
+{
+ for (ChanServ::Level *l : this->GetRefs<ChanServ::Level *>())
+ l->Delete();
+}
+
+Anope::string ChannelImpl::GetIdealBan(User *u)
+{
+ int bt = this->GetBanType();
+ switch (bt)
+ {
+ case 0:
+ return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
+ case 1:
+ if (u->GetVIdent()[0] == '~')
+ return "*!*" + u->GetVIdent() + "@" + u->GetDisplayedHost();
+ else
+ return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
+ case 3:
+ return "*!" + u->Mask();
+ case 2:
+ default:
+ return "*!*@" + u->GetDisplayedHost();
+ }
+}
+
+bool ChannelImpl::IsFounder(const User *user)
+{
+ if (!user)
+ return false;
+
+ if (user->super_admin)
+ return true;
+
+ if (user->Account() && user->Account() == this->GetFounder())
+ return true;
+
+ return false;
+}
+
diff --git a/modules/chanserv/main/channel.h b/modules/chanserv/main/channel.h
new file mode 100644
index 000000000..94f56ddd4
--- /dev/null
+++ b/modules/chanserv/main/channel.h
@@ -0,0 +1,96 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class ChannelImpl : public ChanServ::Channel
+{
+ friend class ChannelType;
+
+ NickServ::Account *founder = nullptr, *successor = nullptr;
+ Anope::string name, desc;
+ time_t time_registered = 0, last_used = 0;
+ Anope::string last_topic, last_topic_setter;
+ time_t last_topic_time = 0;
+ int16_t bantype = 0;
+ time_t banexpire = 0;
+ BotInfo *bi = nullptr;
+
+ public:
+ ChannelImpl(Serialize::TypeBase *type) : ChanServ::Channel(type) { }
+ ChannelImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::Channel(type, id) { }
+ ~ChannelImpl();
+ void Delete() override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &) override;
+
+ Anope::string GetDesc() override;
+ void SetDesc(const Anope::string &) override;
+
+ time_t GetTimeRegistered() override;
+ void SetTimeRegistered(const time_t &) override;
+
+ time_t GetLastUsed() override;
+ void SetLastUsed(const time_t &) override;
+
+ Anope::string GetLastTopic() override;
+ void SetLastTopic(const Anope::string &) override;
+
+ Anope::string GetLastTopicSetter() override;
+ void SetLastTopicSetter(const Anope::string &) override;
+
+ time_t GetLastTopicTime() override;
+ void SetLastTopicTime(const time_t &) override;
+
+ int16_t GetBanType() override;
+ void SetBanType(const int16_t &) override;
+
+ time_t GetBanExpire() override;
+ void SetBanExpire(const time_t &) override;
+
+ BotInfo *GetBI() override;
+ void SetBI(BotInfo *) override;
+
+ ServiceBot *GetBot() override;
+ void SetBot(ServiceBot *) override;
+
+ MemoServ::MemoInfo *GetMemos() override;
+
+ void SetFounder(NickServ::Account *nc) override;
+ NickServ::Account *GetFounder() override;
+
+ void SetSuccessor(NickServ::Account *nc) override;
+ NickServ::Account *GetSuccessor() override;
+
+ bool IsFounder(const User *user) override;
+ ChanServ::ChanAccess *GetAccess(unsigned index) /*const*/ override;
+ ChanServ::AccessGroup AccessFor(const User *u, bool = true) override;
+ ChanServ::AccessGroup AccessFor(NickServ::Account *nc, bool = true) override;
+ unsigned GetAccessCount()/* const*/ override;
+ void ClearAccess() override;
+ AutoKick* AddAkick(const Anope::string &user, NickServ::Account *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) override;
+ AutoKick* AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) override;
+ AutoKick* GetAkick(unsigned index) override;
+ unsigned GetAkickCount() override;
+ void ClearAkick() override;
+ int16_t GetLevel(const Anope::string &priv) override;
+ void SetLevel(const Anope::string &priv, int16_t level) override;
+ void RemoveLevel(const Anope::string &priv) override;
+ void ClearLevels() override;
+ Anope::string GetIdealBan(User *u) override;
+};
diff --git a/modules/chanserv/main/channeltype.cpp b/modules/chanserv/main/channeltype.cpp
new file mode 100644
index 000000000..fa5e03e4c
--- /dev/null
+++ b/modules/chanserv/main/channeltype.cpp
@@ -0,0 +1,64 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "channeltype.h"
+
+ChannelType::ChannelType(Module *me) : Serialize::Type<ChannelImpl>(me)
+ , name(this, "name", &ChannelImpl::name)
+ , desc(this, "desc", &ChannelImpl::desc)
+ , time_registered(this, "time_registered", &ChannelImpl::time_registered)
+ , last_used(this, "last_used", &ChannelImpl::last_used)
+ , last_topic(this, "last_topic", &ChannelImpl::last_topic)
+ , last_topic_setter(this, "last_topic_setter", &ChannelImpl::last_topic_setter)
+ , last_topic_time(this, "last_topic_time", &ChannelImpl::last_topic_time)
+ , bantype(this, "bantype", &ChannelImpl::bantype)
+ , banexpire(this, "banexpire", &ChannelImpl::banexpire)
+ , founder(this, "founder", &ChannelImpl::founder)
+ , successor(this, "successor", &ChannelImpl::successor)
+ , bi(this, "bi", &ChannelImpl::bi)
+{
+
+}
+
+void ChannelType::Name::SetField(ChannelImpl *c, const Anope::string &value)
+{
+ ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
+ map.erase(GetField(c));
+
+ Serialize::Field<ChannelImpl, Anope::string>::SetField(c, value);
+
+ map[value] = c;
+}
+
+ChanServ::Channel *ChannelType::FindChannel(const Anope::string &chan)
+{
+ Serialize::ID id;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeFind, this, &this->name, chan, id);
+ if (result == EVENT_ALLOW)
+ return RequireID(id);
+
+ // fall back
+ ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
+ auto it = map.find(chan);
+ if (it != map.end())
+ return it->second;
+ return nullptr;
+}
+
diff --git a/modules/chanserv/main/channeltype.h b/modules/chanserv/main/channeltype.h
new file mode 100644
index 000000000..95158427a
--- /dev/null
+++ b/modules/chanserv/main/channeltype.h
@@ -0,0 +1,53 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "channel.h"
+
+class ChannelType : public Serialize::Type<ChannelImpl>
+{
+ public:
+ /* Channel name */
+ struct Name : Serialize::Field<ChannelImpl, Anope::string>
+ {
+ using Serialize::Field<ChannelImpl, Anope::string>::Field;
+
+ void SetField(ChannelImpl *c, const Anope::string &value) override;
+ } name;
+ Serialize::Field<ChannelImpl, Anope::string> desc;
+ Serialize::Field<ChannelImpl, time_t> time_registered;
+ Serialize::Field<ChannelImpl, time_t> last_used;
+
+ Serialize::Field<ChannelImpl, Anope::string> last_topic;
+ Serialize::Field<ChannelImpl, Anope::string> last_topic_setter;
+ Serialize::Field<ChannelImpl, time_t> last_topic_time;
+
+ Serialize::Field<ChannelImpl, int16_t> bantype;
+ Serialize::Field<ChannelImpl, time_t> banexpire;
+
+ /* Channel founder */
+ Serialize::ObjectField<ChannelImpl, NickServ::Account *> founder;
+ /* Who gets the channel if the founder nick is dropped or expires */
+ Serialize::ObjectField<ChannelImpl, NickServ::Account *> successor;
+
+ Serialize::ObjectField<ChannelImpl, BotInfo *> bi;
+
+ ChannelType(Module *);
+
+ ChanServ::Channel *FindChannel(const Anope::string &);
+};
diff --git a/modules/chanserv/main/chanserv.cpp b/modules/chanserv/main/chanserv.cpp
new file mode 100644
index 000000000..f53f6301b
--- /dev/null
+++ b/modules/chanserv/main/chanserv.cpp
@@ -0,0 +1,607 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/mode.h"
+#include "modules/help.h"
+#include "modules/botserv/bot.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/info.h"
+#include "modules/chanserv/akick.h"
+#include "channeltype.h"
+#include "leveltype.h"
+#include "modetype.h"
+#include "chanaccesstype.h"
+#include "modules/chanserv/main/chanaccess.h"
+
+class ChanServCore : public Module
+ , public ChanServ::ChanServService
+ , public EventHook<Event::ChannelCreate>
+ , public EventHook<Event::BotDelete>
+ , public EventHook<Event::BotPrivmsg>
+ , public EventHook<Event::DelCore>
+ , public EventHook<Event::DelChan>
+ , public EventHook<Event::Help>
+ , public EventHook<Event::CheckModes>
+ , public EventHook<Event::CanSet>
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::Log>
+ , public EventHook<Event::ExpireTick>
+ , public EventHook<Event::CheckDelete>
+ , public EventHook<Event::PreUplinkSync>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::ChannelModeSet>
+ , public EventHook<Event::ChanInfo>
+ , public EventHook<Event::SetCorrectModes>
+{
+ Reference<ServiceBot> ChanServ;
+ std::vector<Anope::string> defaults;
+ ExtensibleItem<bool> inhabit;
+ bool always_lower;
+ std::vector<ChanServ::Privilege> Privileges;
+ ChanServ::registered_channel_map registered_channels;
+ ChannelType channel_type;
+ LevelType level_type;
+ CSModeType mode_type;
+
+ public:
+ ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , ChanServService(this)
+ , EventHook<Event::ChannelCreate>(this)
+ , EventHook<Event::BotDelete>(this)
+ , EventHook<Event::BotPrivmsg>(this)
+ , EventHook<Event::DelCore>(this)
+ , EventHook<Event::DelChan>(this)
+ , EventHook<Event::Help>(this)
+ , EventHook<Event::CheckModes>(this)
+ , EventHook<Event::CanSet>(this)
+ , EventHook<Event::ChannelSync>(this)
+ , EventHook<Event::Log>(this)
+ , EventHook<Event::ExpireTick>(this)
+ , EventHook<Event::CheckDelete>(this)
+ , EventHook<Event::PreUplinkSync>(this)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::JoinChannel>(this)
+ , EventHook<Event::ChannelModeSet>(this)
+ , EventHook<Event::ChanInfo>(this)
+ , EventHook<Event::SetCorrectModes>(this)
+ , inhabit(this, "inhabit")
+ , always_lower(false)
+ , channel_type(this)
+ , level_type(this)
+ , mode_type(this)
+ {
+ ChanServ::service = this;
+ }
+
+ ~ChanServCore()
+ {
+ ChanServ::service = nullptr;
+ }
+
+ ChanServ::Channel *Find(const Anope::string &name) override
+ {
+ return channel_type.FindChannel(name);
+ }
+
+ ChanServ::registered_channel_map& GetChannels() override
+ {
+ return registered_channels;
+ }
+
+ void Hold(Channel *c) override
+ {
+ /** A timer used to keep the BotServ bot/ChanServ in the channel
+ * after kicking the last user in a channel
+ */
+ class ChanServTimer : public Timer
+ {
+ Reference<ServiceBot> &ChanServ;
+ ExtensibleItem<bool> &inhabit;
+ Reference<Channel> c;
+
+ public:
+ /** Constructor
+ * @param chan The channel
+ */
+ ChanServTimer(Reference<ServiceBot> &cs, ExtensibleItem<bool> &i, Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), ChanServ(cs), inhabit(i), c(chan)
+ {
+ if (!ChanServ || !c)
+ return;
+ inhabit.Set(c, true);
+ if (!c->ci || !c->ci->GetBot())
+ ChanServ->Join(c);
+ else if (!c->FindUser(c->ci->GetBot()))
+ c->ci->GetBot()->Join(c);
+
+ /* Set +ntsi to prevent rejoin */
+ c->SetMode(NULL, "NOEXTERNAL");
+ c->SetMode(NULL, "TOPIC");
+ c->SetMode(NULL, "SECRET");
+ c->SetMode(NULL, "INVITE");
+ }
+
+ /** Called when the delay is up
+ * @param The current time
+ */
+ void Tick(time_t) override
+ {
+ if (!c)
+ return;
+
+ inhabit.Unset(c);
+
+ /* In the event we don't part */
+ c->RemoveMode(NULL, "SECRET");
+ c->RemoveMode(NULL, "INVITE");
+
+ if (!c->ci || !c->ci->GetBot())
+ {
+ if (ChanServ)
+ ChanServ->Part(c);
+ }
+ /* If someone has rejoined this channel in the meantime, don't part the bot */
+ else if (c->users.size() <= 1)
+ c->ci->GetBot()->Part(c);
+ }
+ };
+
+ if (inhabit.HasExt(c))
+ return;
+
+ new ChanServTimer(ChanServ, inhabit, this, c);
+ }
+
+ void AddPrivilege(ChanServ::Privilege p) override
+ {
+ unsigned i;
+ for (i = 0; i < Privileges.size(); ++i)
+ {
+ ChanServ::Privilege &priv = Privileges[i];
+
+ if (priv.rank > p.rank)
+ break;
+ }
+
+ Privileges.insert(Privileges.begin() + i, p);
+ }
+
+ void RemovePrivilege(ChanServ::Privilege &p) override
+ {
+ std::vector<ChanServ::Privilege>::iterator it = std::find(Privileges.begin(), Privileges.end(), p);
+ if (it != Privileges.end())
+ Privileges.erase(it);
+
+ for (auto& cit : GetChannels())
+ {
+ ChanServ::Channel *ci = cit.second;
+ ci->RemoveLevel(p.name);
+ }
+ }
+
+ ChanServ::Privilege *FindPrivilege(const Anope::string &name) override
+ {
+ for (unsigned i = Privileges.size(); i > 0; --i)
+ if (Privileges[i - 1].name.equals_ci(name))
+ return &Privileges[i - 1];
+ return NULL;
+ }
+
+ std::vector<ChanServ::Privilege> &GetPrivileges() override
+ {
+ return Privileges;
+ }
+
+ void ClearPrivileges() override
+ {
+ Privileges.clear();
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &channick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (channick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(channick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + channick);
+
+ ChanServ = bi;
+
+ ClearPrivileges();
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
+ {
+ Configuration::Block *privilege = conf->GetBlock("privilege", i);
+
+ const Anope::string &nname = privilege->Get<Anope::string>("name"),
+ &desc = privilege->Get<Anope::string>("desc");
+ int rank = privilege->Get<int>("rank");
+ Anope::string value = privilege->Get<Anope::string>("level");
+ int level;
+ if (value.equals_ci("founder"))
+ level = ChanServ::ACCESS_FOUNDER;
+ else if (value.equals_ci("disabled"))
+ level = ChanServ::ACCESS_INVALID;
+ else
+ level = privilege->Get<int>("level");
+
+ AddPrivilege(ChanServ::Privilege(nname, desc, rank, level));
+ }
+
+ spacesepstream(conf->GetModule(this)->Get<Anope::string>("defaults", "greet fantasy")).GetTokens(defaults);
+ if (defaults.empty())
+ {
+ defaults.push_back("KEEPTOPIC");
+ defaults.push_back("CS_SECURE");
+ defaults.push_back("SECUREFOUNDER");
+ defaults.push_back("SIGNKICK");
+ }
+ else if (defaults[0].equals_ci("none"))
+ defaults.clear();
+
+ always_lower = conf->GetModule(this)->Get<bool>("always_lower_ts");
+ }
+
+ void OnChannelCreate(Channel *c) override
+ {
+ c->ci = Find(c->name);
+ if (c->ci)
+ c->ci->c = c;
+ }
+
+ void OnBotDelete(ServiceBot *bi) override
+ {
+ if (bi == ChanServ)
+ ChanServ = NULL;
+ }
+
+ EventReturn OnBotPrivmsg(User *u, ServiceBot *bi, Anope::string &message) override
+ {
+ if (bi == ChanServ && Config->GetModule(this)->Get<bool>("opersonly") && !u->HasMode("OPER"))
+ {
+ u->SendMessage(bi, _("Access denied."));
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnDelCore(NickServ::Account *nc) override
+ {
+ unsigned int max_reg = Config->GetModule(this)->Get<unsigned int>("maxregistered");
+ for (ChanServ::Channel *ci : nc->GetRefs<ChanServ::Channel *>())
+ {
+ if (ci->GetFounder() == nc)
+ {
+ NickServ::Account *newowner = NULL;
+ if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->GetChannelCount() < max_reg))
+ newowner = ci->GetSuccessor();
+ else
+ {
+ ChanServ::ChanAccess *highest = NULL;
+ for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
+ {
+ ChanServ::ChanAccess *ca = ci->GetAccess(j);
+ NickServ::Account *anc = ca->GetAccount();
+
+ if (!anc || (!anc->IsServicesOper() && max_reg && anc->GetChannelCount() >= max_reg) || (anc == nc))
+ continue;
+ if (!highest || *ca > *highest)
+ highest = ca;
+ }
+ if (highest)
+ newowner = highest->GetAccount();
+ }
+
+ if (newowner)
+ {
+ ::Log(LOG_NORMAL, "chanserv/drop", ChanServ) << "Transferring foundership of " << ci->GetName() << " from deleted nick " << nc->GetDisplay() << " to " << newowner->GetDisplay();
+ ci->SetFounder(newowner);
+ ci->SetSuccessor(NULL);
+ }
+ else
+ {
+ ::Log(LOG_NORMAL, "chanserv/drop", ChanServ) << "Deleting channel " << ci->GetName() << " owned by deleted nick " << nc->GetDisplay();
+
+ delete ci;
+ continue;
+ }
+ }
+
+ if (ci->GetSuccessor() == nc)
+ ci->SetSuccessor(NULL);
+
+ /* are these necessary? */
+ for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
+ {
+ ChanServ::ChanAccess *ca = ci->GetAccess(j);
+ NickServ::Account *anc = ca->GetAccount();
+
+ if (anc && anc == nc)
+ {
+ delete ca;
+ break;
+ }
+ }
+
+ for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
+ {
+ AutoKick *ak = ci->GetAkick(j);
+ if (ak->GetAccount() == nc)
+ {
+ delete ak;
+ break;
+ }
+ }
+ }
+ }
+
+ void OnDelChan(ChanServ::Channel *ci) override
+ {
+ /* remove access entries that are this channel */
+
+ for (ChanServ::Channel *c : ci->GetRefs<ChanServ::Channel *>())
+ {
+ for (unsigned j = 0; j < c->GetAccessCount(); ++j)
+ {
+ ChanServ::ChanAccess *a = c->GetAccess(j);
+
+ if (a->Mask().equals_ci(ci->GetName()))
+ {
+ delete a;
+ break;
+ }
+ }
+ }
+
+ if (ci->c)
+ {
+ ci->c->RemoveMode(ci->WhoSends(), "REGISTERED", "", false);
+
+ const Anope::string &require = Config->GetModule(this)->Get<Anope::string>("require");
+ if (!require.empty())
+ ci->c->SetModes(ci->WhoSends(), false, "-%s", require.c_str());
+ }
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *ChanServ)
+ return EVENT_CONTINUE;
+ 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"),
+ ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), source.command.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *ChanServ)
+ return;
+ time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
+ if (chanserv_expire >= 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."), chanserv_expire / 86400);
+ if (source.IsServicesOper())
+ source.Reply(_(" \n"
+ "Services Operators can also, depending on their access drop\n"
+ "any channel, view (and modify) the access, levels and akick\n"
+ "lists and settings for any channel."));
+ }
+
+ void OnCheckModes(Reference<Channel> &c) override
+ {
+ if (!c)
+ return;
+
+ if (c->ci)
+ c->SetMode(c->ci->WhoSends(), "REGISTERED", "", false);
+ else
+ c->RemoveMode(c->ci->WhoSends(), "REGISTERED", "", false);
+
+ const Anope::string &require = Config->GetModule(this)->Get<Anope::string>("require");
+ if (!require.empty())
+ {
+ if (c->ci)
+ c->SetModes(c->ci->WhoSends(), false, "+%s", require.c_str());
+ else
+ c->SetModes(c->ci->WhoSends(), false, "-%s", require.c_str());
+ }
+ }
+
+ EventReturn OnCanSet(User *u, const ChannelMode *cm) override
+ {
+ if (Config->GetModule(this)->Get<Anope::string>("nomlock").find(cm->mchar) != Anope::string::npos
+ || Config->GetModule(this)->Get<Anope::string>("require").find(cm->mchar) != Anope::string::npos)
+ return EVENT_STOP;
+ return EVENT_CONTINUE;
+ }
+
+ void OnChannelSync(Channel *c) override
+ {
+ bool perm = c->HasMode("PERM") || (c->ci && c->ci->HasFieldS("PERSIST"));
+ if (!perm && !c->botchannel && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
+ {
+ this->Hold(c);
+ }
+ }
+
+ void OnLog(::Log *l) override
+ {
+ if (l->type == LOG_CHANNEL)
+ l->bi = ChanServ;
+ }
+
+ void OnExpireTick() override
+ {
+ time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
+
+ if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly)
+ return;
+
+ for (ChanServ::Channel *ci : channel_type.List<ChanServ::Channel *>())
+ {
+ bool expire = false;
+
+ if (Anope::CurTime - ci->GetLastUsed() >= chanserv_expire)
+ {
+ if (ci->c)
+ {
+ time_t last_used = ci->GetLastUsed();
+ for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->GetLastUsed(); ++cit)
+ ci->AccessFor(cit->second->user);
+ expire = last_used == ci->GetLastUsed();
+ }
+ else
+ expire = true;
+ }
+
+ EventManager::Get()->Dispatch(&ChanServ::Event::PreChanExpire::OnPreChanExpire, ci, expire);
+
+ if (expire)
+ {
+ ::Log(LOG_NORMAL, "chanserv/expire", ChanServ) << "Expiring channel " << ci->GetName() << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "(none)") << ")";
+ EventManager::Get()->Dispatch(&ChanServ::Event::ChanExpire::OnChanExpire, ci);
+ delete ci;
+ }
+ }
+ }
+
+ EventReturn OnCheckDelete(Channel *c) override
+ {
+ /* Do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
+ if (inhabit.HasExt(c))
+ return EVENT_STOP;
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnPreUplinkSync(Server *serv) override
+ {
+ /* Find all persistent channels and create them, as we are about to finish burst to our uplink */
+ for (ChanServ::Channel *ci : channel_type.List<ChanServ::Channel *>())
+ {
+ if (ci->HasFieldS("PERSIST"))
+ {
+ bool c;
+ ci->c = Channel::FindOrCreate(ci->GetName(), c, ci->GetTimeRegistered());
+
+ if (ModeManager::FindChannelModeByName("PERM") != NULL)
+ {
+ if (c)
+ IRCD->SendChannel(ci->c);
+ ci->c->SetMode(NULL, "PERM");
+ }
+ else
+ {
+ if (!ci->GetBot())
+ ci->WhoSends()->Assign(NULL, ci);
+ if (ci->c->FindUser(ci->GetBot()) == NULL)
+ {
+ Anope::string botmodes = Config->GetModule("botserv")->Get<Anope::string>("botmodes",
+ Config->GetModule("chanserv")->Get<Anope::string>("botmodes"));
+ ChannelStatus status(botmodes);
+ ci->GetBot()->Join(ci->c, &status);
+ }
+ }
+ }
+ }
+
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ /* Set default chan flags */
+ for (unsigned i = 0; i < defaults.size(); ++i)
+ ci->SetS<bool>(defaults[i].upper(), true);
+
+ if (!ci->c)
+ return;
+ /* Mark the channel as persistent */
+ if (ci->c->HasMode("PERM"))
+ ci->SetS("PERSIST", true);
+ /* Persist may be in def cflags, set it here */
+ else if (ci->HasFieldS("PERSIST"))
+ ci->c->SetMode(NULL, "PERM");
+ }
+
+ void OnJoinChannel(User *u, Channel *c) override
+ {
+ if (always_lower && c->ci && c->creation_time > c->ci->GetTimeRegistered())
+ {
+ ::Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->GetTimeRegistered();
+ c->creation_time = c->ci->GetTimeRegistered();
+ IRCD->SendChannel(c);
+ c->Reset();
+ }
+ }
+
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override
+ {
+ if (!always_lower && Anope::CurTime == c->creation_time && c->ci && setter.GetUser() && !setter.GetUser()->server->IsULined())
+ {
+ ChanUserContainer *cu = c->FindUser(setter.GetUser());
+ ChannelMode *cm = ModeManager::FindChannelModeByName("OP");
+ if (cu && cm && !cu->status.HasMode(cm->mchar))
+ {
+ /* Our -o and their mode change crossing, bounce their mode */
+ c->RemoveMode(c->ci->WhoSends(), mode, param);
+ /* We don't set mlocks until after the join has finished processing, it will stack with this change,
+ * so there isn't much for the user to remove except -nt etc which is likely locked anyway.
+ */
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override
+ {
+ if (!show_all)
+ return;
+
+ time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
+ if (!ci->HasFieldS("CS_NO_EXPIRE") && chanserv_expire && !Anope::NoExpire && ci->GetLastUsed() != Anope::CurTime)
+ info[_("Expires")] = Anope::strftime(ci->GetLastUsed() + chanserv_expire, source.GetAccount());
+ }
+
+ void OnSetCorrectModes(User *user, Channel *chan, ChanServ::AccessGroup &access, bool &give_modes, bool &take_modes) override
+ {
+ if (always_lower)
+ // Since we always lower the TS, the other side will remove the modes if the channel ts lowers, so we don't
+ // have to worry about it
+ take_modes = false;
+ else if (ModeManager::FindChannelModeByName("REGISTERED"))
+ // Otherwise if the registered channel mode exists, we should remove modes if the channel is not +r
+ take_modes = !chan->HasMode("REGISTERED");
+ }
+};
+
+MODULE_INIT(ChanServCore)
+
diff --git a/modules/chanserv/main/level.cpp b/modules/chanserv/main/level.cpp
new file mode 100644
index 000000000..b06ff5594
--- /dev/null
+++ b/modules/chanserv/main/level.cpp
@@ -0,0 +1,52 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/chanserv.h"
+#include "leveltype.h"
+
+ChanServ::Channel *LevelImpl::GetChannel()
+{
+ return Get(&LevelType::channel);
+}
+
+void LevelImpl::SetChannel(ChanServ::Channel *c)
+{
+ Set(&LevelType::channel, c);
+}
+
+Anope::string LevelImpl::GetName()
+{
+ return Get(&LevelType::name);
+}
+
+void LevelImpl::SetName(const Anope::string &n)
+{
+ Set(&LevelType::name, n);
+}
+
+int LevelImpl::GetLevel()
+{
+ return Get(&LevelType::level);
+}
+
+void LevelImpl::SetLevel(const int &i)
+{
+ Set(&LevelType::level, i);
+}
+
diff --git a/modules/chanserv/main/level.h b/modules/chanserv/main/level.h
new file mode 100644
index 000000000..d22dc2831
--- /dev/null
+++ b/modules/chanserv/main/level.h
@@ -0,0 +1,40 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class LevelImpl : public ChanServ::Level
+{
+ friend class LevelType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string name;
+ int level = 0;
+
+ public:
+ LevelImpl(Serialize::TypeBase *type) : ChanServ::Level(type) { }
+ LevelImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::Level(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &) override;
+
+ int GetLevel() override;
+ void SetLevel(const int &) override;
+};
diff --git a/modules/chanserv/main/leveltype.h b/modules/chanserv/main/leveltype.h
new file mode 100644
index 000000000..198b9248a
--- /dev/null
+++ b/modules/chanserv/main/leveltype.h
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "level.h"
+
+class LevelType : public Serialize::Type<LevelImpl>
+{
+ public:
+ Serialize::ObjectField<LevelImpl, ChanServ::Channel *> channel;
+ Serialize::Field<LevelImpl, Anope::string> name;
+ Serialize::Field<LevelImpl, int> level;
+
+ LevelType(Module *creator) : Serialize::Type<LevelImpl>(creator)
+ , channel(this, "channel", &LevelImpl::channel, true)
+ , name(this, "name", &LevelImpl::name)
+ , level(this, "level", &LevelImpl::level)
+ {
+ }
+};
diff --git a/modules/chanserv/main/mode.cpp b/modules/chanserv/main/mode.cpp
new file mode 100644
index 000000000..38e63d91c
--- /dev/null
+++ b/modules/chanserv/main/mode.cpp
@@ -0,0 +1,52 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/chanserv.h"
+#include "modetype.h"
+
+ChanServ::Channel *ModeImpl::GetChannel()
+{
+ return Get(&CSModeType::channel);
+}
+
+void ModeImpl::SetChannel(ChanServ::Channel *c)
+{
+ Set(&CSModeType::channel, c);
+}
+
+Anope::string ModeImpl::GetMode()
+{
+ return Get(&CSModeType::mode);
+}
+
+void ModeImpl::SetMode(const Anope::string &m)
+{
+ Set(&CSModeType::mode, m);
+}
+
+Anope::string ModeImpl::GetParam()
+{
+ return Get(&CSModeType::param);
+}
+
+void ModeImpl::SetParam(const Anope::string &p)
+{
+ Set(&CSModeType::param, p);
+}
+
diff --git a/modules/chanserv/main/mode.h b/modules/chanserv/main/mode.h
new file mode 100644
index 000000000..b56360a22
--- /dev/null
+++ b/modules/chanserv/main/mode.h
@@ -0,0 +1,40 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class ModeImpl : public ChanServ::Mode
+{
+ friend class CSModeType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string mode, param;
+
+ public:
+ ModeImpl(Serialize::TypeBase *type) : ChanServ::Mode(type) { }
+ ModeImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::Mode(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
+
+ Anope::string GetMode() override;
+ void SetMode(const Anope::string &) override;
+
+ Anope::string GetParam() override;
+ void SetParam(const Anope::string &) override;
+};
+
diff --git a/modules/chanserv/main/modetype.h b/modules/chanserv/main/modetype.h
new file mode 100644
index 000000000..6b1660986
--- /dev/null
+++ b/modules/chanserv/main/modetype.h
@@ -0,0 +1,35 @@
+
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mode.h"
+
+class CSModeType : public Serialize::Type<ModeImpl>
+{
+ public:
+ Serialize::ObjectField<ModeImpl, ChanServ::Channel *> channel;
+ Serialize::Field<ModeImpl, Anope::string> mode, param;
+
+ CSModeType(Module *creator) : Serialize::Type<ModeImpl>(creator)
+ , channel(this, "channel", &ModeImpl::channel, true)
+ , mode(this, "mode", &ModeImpl::mode)
+ , param(this, "param", &ModeImpl::param)
+ {
+ }
+};
diff --git a/modules/chanserv/mode.cpp b/modules/chanserv/mode.cpp
new file mode 100644
index 000000000..4ff1ce1d3
--- /dev/null
+++ b/modules/chanserv/mode.cpp
@@ -0,0 +1,1011 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/mode.h"
+#include "modules/chanserv/info.h"
+
+class ModeLockImpl : public ModeLock
+{
+ friend class ModeLockType;
+
+ ChanServ::Channel *channel = nullptr;
+ bool set = false;
+ Anope::string name, param, setter;
+ time_t created = 0;
+
+ public:
+ ModeLockImpl(Serialize::TypeBase *type) : ModeLock(type) { }
+ ModeLockImpl(Serialize::TypeBase *type, Serialize::ID id) : ModeLock(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *ci) override;
+
+ bool GetSet() override;
+ void SetSet(const bool &) override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &name) override;
+
+ Anope::string GetParam() override;
+ void SetParam(const Anope::string &p) override;
+
+ Anope::string GetSetter() override;
+ void SetSetter(const Anope::string &s) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &) override;
+};
+
+class ModeLockType : public Serialize::Type<ModeLockImpl>
+{
+ public:
+ Serialize::ObjectField<ModeLockImpl, ChanServ::Channel *> ci;
+ Serialize::Field<ModeLockImpl, bool> set;
+ Serialize::Field<ModeLockImpl, Anope::string> name, param, setter;
+ Serialize::Field<ModeLockImpl, time_t> created;
+
+ ModeLockType(Module *me) : Serialize::Type<ModeLockImpl>(me)
+ , ci(this, "ci", &ModeLockImpl::channel, true)
+ , set(this, "set", &ModeLockImpl::set)
+ , name(this, "name", &ModeLockImpl::name)
+ , param(this, "param", &ModeLockImpl::param)
+ , setter(this, "setter", &ModeLockImpl::setter)
+ , created(this, "created", &ModeLockImpl::created)
+ {
+ }
+};
+
+ChanServ::Channel *ModeLockImpl::GetChannel()
+{
+ return Get(&ModeLockType::ci);
+}
+
+void ModeLockImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Set(&ModeLockType::ci, ci);
+}
+
+bool ModeLockImpl::GetSet()
+{
+ return Get(&ModeLockType::set);
+}
+
+void ModeLockImpl::SetSet(const bool &b)
+{
+ Set(&ModeLockType::set, b);
+}
+
+Anope::string ModeLockImpl::GetName()
+{
+ return Get(&ModeLockType::name);
+}
+
+void ModeLockImpl::SetName(const Anope::string &name)
+{
+ Set(&ModeLockType::name, name);
+}
+
+Anope::string ModeLockImpl::GetParam()
+{
+ return Get(&ModeLockType::param);
+}
+
+void ModeLockImpl::SetParam(const Anope::string &p)
+{
+ Set(&ModeLockType::name, p);
+}
+
+Anope::string ModeLockImpl::GetSetter()
+{
+ return Get(&ModeLockType::setter);
+}
+
+void ModeLockImpl::SetSetter(const Anope::string &s)
+{
+ Set(&ModeLockType::name, s);
+}
+
+time_t ModeLockImpl::GetCreated()
+{
+ return Get(&ModeLockType::created);
+}
+
+void ModeLockImpl::SetCreated(const time_t &c)
+{
+ Set(&ModeLockType::created, c);
+}
+
+class ModeLocksImpl : public ModeLocks
+{
+ public:
+ using ModeLocks::ModeLocks;
+
+ bool HasMLock(ChanServ::Channel *ci, ChannelMode *mode, const Anope::string &param, bool status) const override
+ {
+ if (!mode)
+ return false;
+
+ for (ModeLock *ml : ci->GetRefs<ModeLock *>())
+ if (ml->GetName() == mode->name && ml->GetSet() == status && ml->GetParam() == param)
+ return true;
+
+ return false;
+ }
+
+ bool SetMLock(ChanServ::Channel *ci, ChannelMode *mode, bool status, const Anope::string &param = "", Anope::string setter = "", time_t created = Anope::CurTime) override
+ {
+ if (!mode)
+ return false;
+
+ RemoveMLock(ci, mode, status, param);
+
+ if (setter.empty())
+ setter = ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "Unknown";
+
+ ModeLock *ml = Serialize::New<ModeLock *>();
+ ml->SetChannel(ci);
+ ml->SetSet(status);
+ ml->SetName(mode->name);
+ ml->SetParam(param);
+ ml->SetSetter(setter);
+ ml->SetCreated(created);
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::MLockEvents::OnMLock, ci, ml);
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete ml;
+ return false;
+ }
+
+ return true;
+ }
+
+ bool RemoveMLock(ChanServ::Channel *ci, ChannelMode *mode, bool status, const Anope::string &param = "") override
+ {
+ if (!mode)
+ return false;
+
+ for (ModeLock *m : ci->GetRefs<ModeLockImpl *>())
+ if (m->GetName() == mode->name)
+ {
+ // For list or status modes, we must check the parameter
+ if (mode->type == MODE_LIST || mode->type == MODE_STATUS)
+ if (m->GetParam() != param)
+ continue;
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::MLockEvents::OnUnMLock, ci, m);
+ if (MOD_RESULT == EVENT_STOP)
+ break;
+
+ delete m;
+ return true;
+ }
+
+ return false;
+ }
+
+ void ClearMLock(ChanServ::Channel *ci) override
+ {
+ for (ModeLock *m : ci->GetRefs<ModeLock *>())
+ delete m;
+ }
+
+ ModeList GetMLock(ChanServ::Channel *ci) const override
+ {
+ return ci->GetRefs<ModeLock *>();
+ }
+
+ std::list<ModeLock *> GetModeLockList(ChanServ::Channel *ci, const Anope::string &name) override
+ {
+ std::list<ModeLock *> mlist;
+ for (ModeLock *m : ci->GetRefs<ModeLock *>())
+ if (m->GetName() == name)
+ mlist.push_back(m);
+ return mlist;
+ }
+
+ ModeLock *GetMLock(ChanServ::Channel *ci, const Anope::string &mname, const Anope::string &param = "") override
+ {
+ for (ModeLock *m : ci->GetRefs<ModeLock *>())
+ if (m->GetName() == mname && m->GetParam() == param)
+ return m;
+
+ return NULL;
+ }
+
+ Anope::string GetMLockAsString(ChanServ::Channel *ci, bool complete) const override
+ {
+ Anope::string pos = "+", neg = "-", params;
+
+ for (ModeLock *ml : ci->GetRefs<ModeLock *>())
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(ml->GetName());
+
+ if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
+ continue;
+
+ if (ml->GetSet())
+ pos += cm->mchar;
+ else
+ neg += cm->mchar;
+
+ if (complete && ml->GetSet() && !ml->GetParam().empty() && cm->type == MODE_PARAM)
+ params += " " + ml->GetParam();
+ }
+
+ if (pos.length() == 1)
+ pos.clear();
+ if (neg.length() == 1)
+ neg.clear();
+
+ return pos + neg + params;
+ }
+};
+
+class CommandCSMode : public Command
+{
+ ServiceReference<ModeLocks> mlocks;
+
+ bool CanSet(CommandSource &source, ChanServ::Channel *ci, ChannelMode *cm, bool self)
+ {
+ if (!ci || !cm || cm->type != MODE_STATUS)
+ return false;
+
+ return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : ""));
+ }
+
+ void DoLock(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ User *u = source.GetUser();
+ const Anope::string &subcommand = params[2];
+ const Anope::string &param = params.size() > 3 ? params[3] : "";
+
+ bool override = !source.AccessFor(ci).HasPriv("MODE");
+
+ if (Anope::ReadOnly && !subcommand.equals_ci("LIST"))
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty())
+ {
+ /* If setting, remove the existing locks */
+ if (subcommand.equals_ci("SET"))
+ for (ModeLock *ml : mlocks->GetMLock(ci))
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(ml->GetName());
+ if (cm && cm->CanSet(source.GetUser()))
+ mlocks->RemoveMLock(ci, cm, ml->GetSet(), ml->GetParam());
+ }
+
+ spacesepstream sep(param);
+ Anope::string modes;
+
+ sep.GetToken(modes);
+
+ Anope::string pos = "+", neg = "-", pos_params, neg_params;
+
+ int adding = 1;
+ bool needreply = true;
+ for (size_t i = 0; i < modes.length(); ++i)
+ {
+ switch (modes[i])
+ {
+ case '+':
+ adding = 1;
+ break;
+ case '-':
+ adding = 0;
+ break;
+ default:
+ needreply = false;
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
+ if (!cm)
+ {
+ source.Reply(_("Unknown mode character \002{0}\002 ignored."), modes[i]);
+ break;
+ }
+ else if (u && !cm->CanSet(u))
+ {
+ source.Reply(_("You may not (un)lock mode \002{0}\002."), modes[i]);
+ break;
+ }
+
+ Anope::string mode_param;
+ if (((cm->type == MODE_STATUS || cm->type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
+ source.Reply(_("Missing parameter for mode \002{0}\002."), cm->mchar);
+ else if (cm->type == MODE_LIST && ci->c && IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) >= IRCD->GetMaxListFor(ci->c))
+ source.Reply(_("List for mode \002{0}\002 is full."), cm->mchar);
+ else if (ci->GetRefs<ModeLock *>().size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("max", "32"))
+ source.Reply(_("The mode lock list of \002{0}\002 is full."), ci->GetName());
+ else
+ {
+ mlocks->SetMLock(ci, cm, adding, mode_param, source.GetNick());
+
+ if (adding)
+ {
+ pos += cm->mchar;
+ if (!mode_param.empty())
+ pos_params += " " + mode_param;
+ }
+ else
+ {
+ neg += cm->mchar;
+ if (!mode_param.empty())
+ neg_params += " " + mode_param;
+ }
+ }
+ }
+ }
+
+ if (pos == "+")
+ pos.clear();
+ if (neg == "-")
+ neg.clear();
+ Anope::string reply = pos + neg + pos_params + neg_params;
+
+ if (!reply.empty())
+ {
+ source.Reply(_("\002{0}\002 locked on \002{1}\002."), reply, ci->GetName());
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << reply;
+ }
+ else if (needreply)
+ source.Reply(_("Nothing to do."));
+
+ if (ci->c)
+ ci->c->CheckModes();
+ }
+ else if (subcommand.equals_ci("DEL") && !param.empty())
+ {
+ spacesepstream sep(param);
+ Anope::string modes;
+
+ sep.GetToken(modes);
+
+ int adding = 1;
+ bool needreply = true;
+ for (size_t i = 0; i < modes.length(); ++i)
+ {
+ switch (modes[i])
+ {
+ case '+':
+ adding = 1;
+ break;
+ case '-':
+ adding = 0;
+ break;
+ default:
+ needreply = false;
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
+ if (!cm)
+ {
+ source.Reply(_("Unknown mode character \002{0}\002 ignored."), modes[i]);
+ break;
+ }
+ else if (u && !cm->CanSet(u))
+ {
+ source.Reply(_("You may not (un)lock mode \002{0}\002."), modes[i]);
+ break;
+ }
+
+ Anope::string mode_param;
+ if (cm->type != MODE_REGULAR && !sep.GetToken(mode_param))
+ source.Reply(_("Missing parameter for mode \002{0}\002."), cm->mchar);
+ else
+ {
+ if (mlocks->RemoveMLock(ci, cm, adding, mode_param))
+ {
+ if (!mode_param.empty())
+ mode_param = " " + mode_param;
+ source.Reply(_("\002{0}{1}{2}\002 has been unlocked from \002{3}\002."), adding == 1 ? '+' : '-', cm->mchar, mode_param, ci->GetName());
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unlock " << (adding ? '+' : '-') << cm->mchar << mode_param;
+ }
+ else
+ source.Reply(_("\002{0}{1}\002 is not locked on \002{2}\002."), adding == 1 ? '+' : '-', cm->mchar, ci->GetName());
+ }
+ }
+ }
+
+ if (needreply)
+ source.Reply(_("Nothing to do."));
+ }
+ else if (subcommand.equals_ci("LIST"))
+ {
+ ModeLocks::ModeList locks = mlocks->GetMLock(ci);
+ if (locks.empty())
+ {
+ source.Reply(_("Channel \002{0}\002 has no mode locks."), ci->GetName());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Mode")).AddColumn(_("Param")).AddColumn(_("Creator")).AddColumn(_("Created"));
+
+ for (ModeLock *ml : locks)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(ml->GetName());
+ if (!cm)
+ continue;
+
+ ListFormatter::ListEntry entry;
+ entry["Mode"] = Anope::printf("%c%c", ml->GetSet() ? '+' : '-', cm->mchar);
+ entry["Param"] = ml->GetParam();
+ entry["Creator"] = ml->GetSetter();
+ entry["Created"] = Anope::strftime(ml->GetCreated(), NULL, true);
+ list.AddEntry(entry);
+ }
+
+ source.Reply(_("Mode locks for \002{0}\002:"), ci->GetName());
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ else
+ this->OnSyntaxError(source, subcommand);
+ }
+
+ void DoSet(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ User *u = source.GetUser();
+
+ bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/administration");
+ bool can_override = source.HasPriv("chanserv/administration");
+
+ spacesepstream sep(params.size() > 3 ? params[3] : "");
+ Anope::string modes = params[2], param;
+
+ bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/administration");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2] << (params.size() > 3 ? " " + params[3] : "");
+
+ int adding = -1;
+ for (size_t i = 0; i < modes.length(); ++i)
+ {
+ switch (modes[i])
+ {
+ case '+':
+ adding = 1;
+ break;
+ case '-':
+ adding = 0;
+ break;
+ case '*':
+ if (adding == -1 || !has_access)
+ break;
+ for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j)
+ {
+ ChannelMode *cm = ModeManager::GetChannelModes()[j];
+
+ if (!u || cm->CanSet(u) || can_override)
+ {
+ if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM))
+ {
+ if (adding)
+ ci->c->SetMode(NULL, cm);
+ else
+ ci->c->RemoveMode(NULL, cm);
+ }
+ }
+ }
+ break;
+ default:
+ if (adding == -1)
+ break;
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
+ if (!cm || (u && !cm->CanSet(u) && !can_override))
+ continue;
+ switch (cm->type)
+ {
+ case MODE_REGULAR:
+ if (!has_access)
+ break;
+ if (adding)
+ ci->c->SetMode(NULL, cm);
+ else
+ ci->c->RemoveMode(NULL, cm);
+ break;
+ case MODE_PARAM:
+ if (!has_access)
+ break;
+ if (adding && !sep.GetToken(param))
+ break;
+ if (adding)
+ ci->c->SetMode(NULL, cm, param);
+ else
+ ci->c->RemoveMode(NULL, cm);
+ break;
+ case MODE_STATUS:
+ {
+ if (!sep.GetToken(param))
+ param = source.GetNick();
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci);
+
+ if (param.find_first_of("*?") != Anope::string::npos)
+ {
+ if (!this->CanSet(source, ci, cm, false) && !can_override)
+ {
+ source.Reply(_("You do not have access to set mode \002{0}\002."), cm->mchar);
+ break;
+ }
+
+ for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
+ {
+ ChanUserContainer *uc = it->second;
+ ++it;
+
+ ChanServ::AccessGroup targ_access = ci->AccessFor(uc->user);
+
+ if (uc->user->IsProtected() || (ci->HasFieldS("PEACE") && targ_access >= u_access && !can_override))
+ {
+ source.Reply(_("You do not have the access to change the modes of \002{0}\002."), uc->user->nick.c_str());
+ continue;
+ }
+
+ if (Anope::Match(uc->user->GetMask(), param))
+ {
+ if (adding)
+ ci->c->SetMode(NULL, cm, uc->user->GetUID());
+ else
+ ci->c->RemoveMode(NULL, cm, uc->user->GetUID());
+ }
+ }
+ }
+ else
+ {
+ User *target = User::Find(param, true);
+ if (target == NULL)
+ {
+ source.Reply(_("User \002{0}\002 isn't currently online."), param);
+ break;
+ }
+
+ if (!this->CanSet(source, ci, cm, source.GetUser() == target) && !can_override)
+ {
+ source.Reply(_("You do not have access to set mode \002{0}\002."), cm->mchar);
+ break;
+ }
+
+ if (source.GetUser() != target)
+ {
+ ChanServ::AccessGroup targ_access = ci->AccessFor(target);
+ if (ci->HasFieldS("PEACE") && targ_access >= u_access && !can_override)
+ {
+ source.Reply(_("You do not have the access to change the modes of \002{0}\002"), target->nick);
+ break;
+ }
+ else if (target->IsProtected())
+ {
+ source.Reply(_("Access denied. \002{0}\002 is protected and can not have their modes changed."), target->nick);
+ break;
+ }
+ }
+
+ if (adding)
+ ci->c->SetMode(NULL, cm, target->GetUID());
+ else
+ ci->c->RemoveMode(NULL, cm, target->GetUID());
+ }
+ break;
+ }
+ case MODE_LIST:
+ if (!has_access)
+ break;
+ if (!sep.GetToken(param))
+ break;
+ if (adding)
+ {
+ if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
+ ci->c->SetMode(NULL, cm, param);
+ }
+ else
+ {
+ std::vector<Anope::string> v = ci->c->GetModeList(cm->name);
+ for (unsigned j = 0; j < v.size(); ++j)
+ if (Anope::Match(v[j], param))
+ ci->c->RemoveMode(NULL, cm, v[j]);
+ }
+ }
+ }
+ }
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &param = params.size() > 2 ? params[2] : "";
+
+ if (param.empty())
+ {
+ std::vector<Anope::string> new_params;
+ new_params.push_back(params[0]);
+ new_params.push_back("SET");
+ new_params.push_back("-*");
+ this->DoSet(source, ci, new_params);
+ return;
+ }
+
+ ChannelMode *cm;
+ if (param.length() == 1)
+ cm = ModeManager::FindChannelModeByChar(param[0]);
+ else
+ {
+ cm = ModeManager::FindChannelModeByName(param.upper());
+ if (!cm)
+ cm = ModeManager::FindChannelModeByName(param.substr(0, param.length() - 1).upper());
+ }
+
+ if (!cm)
+ {
+ source.Reply(_("There is no such mode \002{0}\002."), param);
+ return;
+ }
+
+ if (cm->type != MODE_STATUS && cm->type != MODE_LIST)
+ {
+ source.Reply(_("Mode \002{0}\002 is not a status or list mode."), param);
+ return;
+ }
+
+ std::vector<Anope::string> new_params;
+ new_params.push_back(params[0]);
+ new_params.push_back("SET");
+ new_params.push_back("-" + stringify(cm->mchar));
+ new_params.push_back("*");
+ this->DoSet(source, ci, new_params);
+ }
+
+ public:
+ CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 2, 4)
+ {
+ this->SetDesc(_("Control modes and mode locks on a channel"));
+ this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|SET|LIST} [\037what\037]"));
+ this->SetSyntax(_("\037channel\037 SET \037modes\037"));
+ this->SetSyntax(_("\037channel\037 CLEAR [\037what\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &subcommand = params[1];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (subcommand.equals_ci("LOCK") && params.size() > 2)
+ {
+ if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MODE", ci->GetName());
+ else
+ this->DoLock(source, ci, params);
+ }
+ else if (!ci->c)
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ else if (subcommand.equals_ci("SET") && params.size() > 2)
+ this->DoSet(source, ci, params);
+ else if (subcommand.equals_ci("CLEAR"))
+ {
+ if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MODE", ci->GetName());
+ else
+ this->DoClear(source, ci, params);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Controls mode locks and allows changing modes on a channel."
+ "\n"
+ "The \002{0} LOCK\002 command allows you to add, delete, and view mode locks on a channel."
+ " If a mode is locked on or off, services will not allow that mode to be changed."
+ " The \002SET\002 command will clear all existing mode locks and set the new one given, while \002ADD\002 and \002DEL\002 modify the existing mode lock.\n"
+ "\n"
+ "Example:\n"
+ " {0} #channel LOCK ADD +bmnt *!*@*aol*\n"
+ "\n"
+ "The \002{0} SET\002 command allows you to set modes through services. Wildcards * and ? may be given as parameters for list and status modes.\n"
+ "Example:\n"
+ " {0} #channel SET +v *\n"
+ " Sets voice status to all users in the channel.\n"
+ "\n"
+ " {0} #channel SET -b ~c:*\n"
+ " Clears all extended bans that start with ~c:\n"
+ "\n"
+ "The \002{0} CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices."
+ " If \037what\037 is not given then all basic modes are removed."),
+ source.command.upper());
+ return true;
+ }
+};
+
+static Anope::map<std::pair<bool, Anope::string> > modes;
+
+class CommandCSModes : public Command
+{
+ public:
+ CommandCSModes(Module *creator) : Command(creator, "chanserv/modes", 1, 2)
+ {
+ this->SetSyntax(_("\037channel\037 [\037user\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ User *u = source.GetUser(),
+ *targ = params.size() > 1 ? User::Find(params[1], true) : u;
+
+ if (!targ)
+ {
+ source.Reply(_("User \002{0}\002 isn't currently online."), params.size() > 1 ? params[1] : source.GetNick());
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!ci->c)
+ {
+ source.Reply(_("Channel \002%s\002 doesn't exist."), ci->GetName());
+ return;
+ }
+
+ ChanServ::AccessGroup u_access = source.AccessFor(ci), targ_access = ci->AccessFor(targ);
+ const std::pair<bool, Anope::string> &m = modes[source.command];
+
+ bool can_override = source.HasPriv("chanserv/administration");
+ bool override = false;
+
+ if (m.second.empty())
+ return; // Configuration issue
+
+ const Anope::string &want = u == targ ? m.second + "ME" : m.second;
+ if (!u_access.HasPriv(want))
+ {
+ if (!can_override)
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), want, ci->GetName());
+ return;
+ }
+ else
+ override = true;
+ }
+
+ if (!override && !m.first && u != targ && (targ->IsProtected() || (ci->HasFieldS("PEACE") && targ_access >= u_access)))
+ {
+ if (!can_override)
+ {
+ source.Reply(_("Access denied. \002{0}\002 has the same or more privileges than you on \002{1}\002."), targ->nick, ci->GetName());
+ return;
+ }
+ else
+ override = true;
+ }
+
+ if (!ci->c->FindUser(targ))
+ {
+ source.Reply(_("User \002{0}\002 is not on channel \002{1}\002."), targ->nick, ci->GetName());
+ return;
+ }
+
+ if (m.first)
+ ci->c->SetMode(NULL, m.second, targ->GetUID());
+ else
+ ci->c->RemoveMode(NULL, m.second, targ->GetUID());
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "on " << targ->nick;
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ const std::pair<bool, Anope::string> &m = modes[source.command];
+ if (!m.second.empty())
+ {
+ if (m.first)
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Gives you or the specified nick %s status on a channel")), m.second.c_str());
+ else
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
+ }
+ else
+ return "";
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ const std::pair<bool, Anope::string> &m = modes[source.command];
+ if (m.second.empty())
+ return false;
+
+ if (m.first)
+ source.Reply(_("Gives {0} status to the selected \037user\037 on \037channel\037. If \037user\037 is not given, it will give the status to you."),
+ m.second.upper());
+ else
+ source.Reply(_("Removes {0} status from the selected \037user\037 on \037channel\037. If \037user\037 is not given, it will remove the status from you."),
+ m.second.upper());
+ source.Reply(" ");
+ source.Reply(_("Use of this command requires the \002{1}(ME)\002 privilege on \037channel\037."), m.second.upper());
+
+ return true;
+ }
+};
+
+class CSMode : public Module
+ , public EventHook<Event::CheckModes>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::ChanInfo>
+{
+ CommandCSMode commandcsmode;
+ CommandCSModes commandcsmodes;
+ ModeLocksImpl modelock;
+ ModeLockType modelock_type;
+
+ public:
+ CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::CheckModes>(this)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::ChanInfo>(this)
+ , commandcsmode(this)
+ , commandcsmodes(this)
+ , modelock(this)
+ , modelock_type(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ modes.clear();
+
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
+ {
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ const Anope::string &cname = block->Get<Anope::string>("name"),
+ &cmd = block->Get<Anope::string>("command");
+
+ if (cname.empty() || cmd != "chanserv/modes")
+ continue;
+
+ const Anope::string &set = block->Get<Anope::string>("set"),
+ &unset = block->Get<Anope::string>("unset");
+
+ if (set.empty() && unset.empty())
+ continue;
+
+ modes[cname] = std::make_pair(!set.empty(), !set.empty() ? set : unset);
+ }
+ }
+
+ void OnCheckModes(Reference<Channel> &c) override
+ {
+ if (!c || !c->ci)
+ return;
+
+ ModeLocks::ModeList locks = modelock.GetMLock(c->ci);
+ for (ModeLock *ml : locks)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(ml->GetName());
+ if (!cm)
+ continue;
+
+ if (cm->type == MODE_REGULAR)
+ {
+ if (!c->HasMode(cm->name) && ml->GetSet())
+ c->SetMode(NULL, cm, "", false);
+ else if (c->HasMode(cm->name) && !ml->GetSet())
+ c->RemoveMode(NULL, cm, "", false);
+ }
+ else if (cm->type == MODE_PARAM)
+ {
+ /* If the channel doesn't have the mode, or it does and it isn't set correctly */
+ if (ml->GetSet())
+ {
+ Anope::string param;
+ c->GetParam(cm->name, param);
+
+ if (!c->HasMode(cm->name) || (!param.empty() && !ml->GetParam().empty() && !param.equals_cs(ml->GetParam())))
+ c->SetMode(NULL, cm, ml->GetParam(), false);
+ }
+ else
+ {
+ if (c->HasMode(cm->name))
+ c->RemoveMode(NULL, cm, "", false);
+ }
+ }
+ else if (cm->type == MODE_LIST || cm->type == MODE_STATUS)
+ {
+ if (ml->GetSet())
+ c->SetMode(NULL, cm, ml->GetParam(), false);
+ else
+ c->RemoveMode(NULL, cm, ml->GetParam(), false);
+ }
+ }
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ Anope::string mlock;
+ spacesepstream sep(Config->GetModule(this)->Get<Anope::string>("mlock", "+nt"));
+ if (sep.GetToken(mlock))
+ {
+ bool add = true;
+ for (unsigned i = 0; i < mlock.length(); ++i)
+ {
+ if (mlock[i] == '+')
+ {
+ add = true;
+ continue;
+ }
+
+ if (mlock[i] == '-')
+ {
+ add = false;
+ continue;
+ }
+
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
+ if (!cm)
+ continue;
+
+ Anope::string param;
+ if (cm->type == MODE_PARAM)
+ {
+ ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
+ if (add || !cmp->minus_no_arg)
+ {
+ sep.GetToken(param);
+ if (param.empty() || !cmp->IsValid(param))
+ continue;
+ }
+ }
+ else if (cm->type != MODE_REGULAR)
+ {
+ sep.GetToken(param);
+ if (param.empty())
+ continue;
+ }
+
+ modelock.SetMLock(ci, cm, add, param);
+ }
+ }
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_hidden) override
+ {
+ if (!show_hidden)
+ return;
+
+ const Anope::string &m = modelock.GetMLockAsString(ci, true);
+ if (!m.empty())
+ info[_("Mode lock")] = m;
+ }
+};
+
+MODULE_INIT(CSMode)
diff --git a/modules/chanserv/register.cpp b/modules/chanserv/register.cpp
new file mode 100644
index 000000000..47356b507
--- /dev/null
+++ b/modules/chanserv/register.cpp
@@ -0,0 +1,174 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandCSRegister : public Command
+{
+ public:
+ CommandCSRegister(Module *creator) : Command(creator, "chanserv/register", 1, 2)
+ {
+ this->SetDesc(_("Register a channel"));
+ this->SetSyntax(_("\037channel\037 [\037description\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
+
+ User *u = source.GetUser();
+ NickServ::Account *nc = source.nc;
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, channel registration is temporarily disabled."));
+ return;
+ }
+
+ if (nc->HasFieldS("UNCONFIRMED"))
+ {
+ source.Reply(_("You must confirm your account before you can register a channel."));
+ return;
+ }
+
+ if (chan[0] == '&')
+ {
+ source.Reply(_("Local channels can not be registered."));
+ return;
+ }
+
+ if (chan[0] != '#')
+ {
+ source.Reply(_("Please use the symbol of \002#\002 when attempting to register."));
+ return;
+ }
+
+ if (!IRCD->IsChannelValid(chan))
+ {
+ source.Reply(_("Channel \002{0}\002 is not a valid channel."), chan);
+ return;
+ }
+
+ Channel *c = Channel::Find(params[0]);
+ if (!c && u)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), chan);
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci)
+ {
+ source.Reply(_("Channel \002{0}\002 is already registered!"), chan);
+ return;
+ }
+
+ if (c && u && !c->HasUserStatus(u, "OP"))
+ {
+ source.Reply(_("You must be a channel operator to register the channel."));
+ return;
+ }
+
+ unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
+ if (maxregistered && nc->GetChannelCount() >= maxregistered && !source.HasPriv("chanserv/no-register-limit"))
+ {
+ if (nc->GetChannelCount() > maxregistered)
+ source.Reply(_("Sorry, you have already exceeded your limit of \002{0}\002 channels."), maxregistered);
+ else
+ source.Reply(_("Sorry, you have already reached your limit of \002{0}\002 channels."), maxregistered);
+ return;
+ }
+
+ ci = Serialize::New<ChanServ::Channel *>();
+ if (ci == nullptr)
+ return;
+
+ ci->SetName(chan);
+ ci->SetFounder(nc);
+ ci->SetDesc(chdesc);
+ ci->SetTimeRegistered(Anope::CurTime);
+ ci->SetLastUsed(Anope::CurTime);
+ ci->SetBanType(2);
+
+ ci->c = c; // XXX? this isnt set on reconstrubted objects?
+ c->ci = ci;
+
+ if (c && !c->topic.empty())
+ {
+ ci->SetLastTopic(c->topic);
+ ci->SetLastTopicSetter(c->topic_setter);
+ ci->SetLastTopicTime(c->topic_time);
+ }
+ else
+ {
+ ci->SetLastTopicSetter(source.service->nick);
+ }
+
+ Log(LOG_COMMAND, source, this, ci);
+ source.Reply(_("Channel \002{0}\002 registered under your account: \002{1}\002"), chan, nc->GetDisplay());
+
+ /* Implement new mode lock */
+ if (c)
+ {
+ c->CheckModes();
+ if (u)
+ c->SetCorrectModes(u, true);
+
+ EventManager::Get()->Dispatch(&Event::ChanRegistered::OnChanRegistered, ci);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Registers a channel, which sets you as the founder and prevents other users from gaining unauthorized access in the channel."
+ " To use this command, you must first be a channel operator on \037channel\037."
+ " The description, which is optional, is a general description of the channel's purpose.\n"
+ "\n"
+ "When you register a channel, you are recorded as the founder of the channel."
+ " The channel founder is allowed to change all of the channel settings for the channel,"
+ " and will automatically be given channel operator status when entering the channel."));
+
+ ServiceBot *bi;
+ Anope::string cmd;
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (Command::FindCommandFromService("chanserv/access", bi, cmd) && help)
+ source.Reply(_("\n"
+ "See the \002{0}\002 command (\002{1}{2} {3} {0}\002) for information on giving a subset of these privileges to other users."),
+ cmd, Config->StrictPrivmsg, bi->nick, help->cname);
+
+ return true;
+ }
+};
+
+
+class CSRegister : public Module
+{
+ CommandCSRegister commandcsregister;
+
+ public:
+ CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsregister(this)
+ {
+ }
+};
+
+MODULE_INIT(CSRegister)
diff --git a/modules/commands/cs_seen.cpp b/modules/chanserv/seen.cpp
index 80bc8e548..fc2d92597 100644
--- a/modules/commands/cs_seen.cpp
+++ b/modules/chanserv/seen.cpp
@@ -1,14 +1,24 @@
-/* cs_seen: provides a seen command by tracking all users
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2011 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+#warning "this is disabled"
+#if 0
#include "module.h"
enum TypeInfo
@@ -22,7 +32,7 @@ static SeenInfo *FindInfo(const Anope::string &nick);
typedef Anope::hash_map<SeenInfo *> database_map;
database_map database;
-struct SeenInfo : Serializable
+struct SeenInfo : Serialize::Object
{
Anope::string nick;
Anope::string vhost;
@@ -32,7 +42,7 @@ struct SeenInfo : Serializable
Anope::string message; // for part/kick/quit
time_t last; // the time when the user was last seen
- SeenInfo() : Serializable("SeenInfo")
+ SeenInfo() : Serialize::Object("SeenInfo")
{
}
@@ -43,7 +53,8 @@ struct SeenInfo : Serializable
database.erase(iter);
}
- void Serialize(Serialize::Data &data) const anope_override
+#if 0
+ void Serialize(Serialize::Data &data) const override
{
data["nick"] << nick;
data["vhost"] << vhost;
@@ -57,7 +68,7 @@ struct SeenInfo : Serializable
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
{
Anope::string snick;
-
+
data["nick"] >> snick;
SeenInfo *s;
@@ -85,6 +96,7 @@ struct SeenInfo : Serializable
database[s->nick] = s;
return s;
}
+#endif
};
static SeenInfo *FindInfo(const Anope::string &nick)
@@ -98,7 +110,7 @@ static SeenInfo *FindInfo(const Anope::string &nick)
static bool ShouldHide(const Anope::string &channel, User *u)
{
Channel *targetchan = Channel::Find(channel);
- const ChannelInfo *targetchan_ci = targetchan ? *targetchan->ci : ChannelInfo::Find(channel);
+ const ChanServ::Channel *targetchan_ci = targetchan ? *targetchan->ci : ChanServ::Find(channel);
if (targetchan && targetchan->HasMode("SECRET"))
return true;
@@ -119,7 +131,7 @@ class CommandOSSeen : public Command
this->SetSyntax(_("CLEAR \037time\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (params[0].equals_ci("STATS"))
{
@@ -165,8 +177,17 @@ class CommandOSSeen : public Command
this->SendSyntax(source);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
+<<<<<<< HEAD
+ source.Reply(_("The \002STATS\002 command prints out statistics about stored nicks and memory usage.\n"
+ "The \002CLEAR\002 command lets you clean the database by removing all entries from the entries from the database that were added within \037time\037.\n"
+ "\n"
+ "Example:\n"
+ " {0} CLEAR 30m\n"
+ " Will remove all entries that were added within the last 30 minutes."),
+ source.command);
+=======
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("The \002STATS\002 command prints out statistics about stored nicks and memory usage."));
@@ -176,6 +197,7 @@ class CommandOSSeen : public Command
"Example:\n"
" %s CLEAR 30m\n"
" Will remove all entries that were added within the last 30 minutes."), source.command.c_str());
+>>>>>>> 2.0
return true;
}
};
@@ -191,24 +213,24 @@ class CommandSeen : public Command
return;
}
- BotInfo *bi = BotInfo::Find(params[0], true);
+ ServiceBot *bi = ServiceBot::Find(params[0], true);
if (bi)
{
- if (bi == source.c->ci->bi)
+ if (bi == source.c->ci->GetBot())
source.Reply(_("You found me, %s!"), source.GetNick().c_str());
else
source.Reply(_("%s is a network service."), bi->nick.c_str());
return;
}
- NickAlias *na = NickAlias::Find(params[0]);
+ NickServ::Nick *na = NickServ::FindNick(params[0]);
if (!na)
{
source.Reply(_("I don't know who %s is."), params[0].c_str());
return;
}
- if (source.GetAccount() == na->nc)
+ if (source.GetAccount() == na->GetAccount())
{
source.Reply(_("Looking for yourself, eh %s?"), source.GetNick().c_str());
return;
@@ -227,32 +249,27 @@ class CommandSeen : public Command
ChanUserContainer *uc = it->second;
User *u = uc->user;
- if (u->Account() == na->nc)
+ if (u->Account() == na->GetAccount())
{
source.Reply(_("%s is on the channel right now (as %s)!"), params[0].c_str(), u->nick.c_str());
return;
}
}
- AccessGroup ag = source.c->ci->AccessFor(na->nc);
+ ChanServ::AccessGroup ag = source.c->ci->AccessFor(na->GetAccount());
time_t last = 0;
- for (unsigned int i = 0; i < ag.paths.size(); ++i)
+ for (unsigned i = 0; i < ag.size(); ++i)
{
- ChanAccess::Path &p = ag.paths[i];
-
- if (p.empty())
- continue;
-
- ChanAccess *a = p[p.size() - 1];
+ ChanServ::ChanAccess *a = ag[i];
- if (a->GetAccount() == na->nc && a->last_seen > last)
- last = a->last_seen;
+ if (a->GetAccount() == na->GetAccount() && a->GetLastSeen() > last)
+ last = a->GetLastSeen();
}
if (last > Anope::CurTime || !last)
- source.Reply(_("I've never seen %s on this channel."), na->nick.c_str());
+ source.Reply(_("I've never seen %s on this channel."), na->GetNick().c_str());
else
- source.Reply(_("%s was last seen here %s ago."), na->nick.c_str(), Anope::Duration(Anope::CurTime - last, source.GetAccount()).c_str());
+ source.Reply(_("%s was last seen here %s ago."), na->GetNick().c_str(), Anope::Duration(Anope::CurTime - last, source.GetAccount()).c_str());
}
public:
@@ -262,7 +279,7 @@ class CommandSeen : public Command
this->SetSyntax(_("\037nick\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &target = params[0];
@@ -271,26 +288,26 @@ class CommandSeen : public Command
if (target.length() > Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"))
{
- source.Reply(_("Nick too long, max length is %u characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"));
+ source.Reply(_("Nick too long, max length is \002{0}\002 characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"));
return;
}
- if (BotInfo::Find(target, true) != NULL)
+ if (ServiceBot::Find(target, true) != NULL)
{
- source.Reply(_("%s is a client on services."), target.c_str());
+ source.Reply(_("\002{0}\002 is a service bot."), target);
return;
}
if (target.equals_ci(source.GetNick()))
{
- source.Reply(_("You might see yourself in the mirror, %s."), source.GetNick().c_str());
+ source.Reply(_("You might see yourself in the mirror, \002{0}\002."), source.GetNick());
return;
}
SeenInfo *info = FindInfo(target);
if (!info)
{
- source.Reply(_("Sorry, I have not seen %s."), target.c_str());
+ source.Reply(_("Sorry, I have not seen \002{0}\002."), target);
return;
}
@@ -306,8 +323,8 @@ class CommandSeen : public Command
if (info->type == NEW)
{
- source.Reply(_("%s (%s) was last seen connecting %s ago (%s)%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), timebuf2.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen connecting \002{2}\002 ago (\002{3}\002){4}"),
+ target, info->vhost, timebuf, timebuf2, onlinestatus);
}
else if (info->type == NICK_TO)
{
@@ -317,75 +334,82 @@ class CommandSeen : public Command
else
onlinestatus = Anope::printf(_(", but %s mysteriously dematerialized."), info->nick2.c_str());
- source.Reply(_("%s (%s) was last seen changing nick to %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->nick2.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen changing nick to \002{2}\002 \002{3}\002 ago{4}"),
+ target, info->vhost, info->nick2, timebuf, onlinestatus);
}
else if (info->type == NICK_FROM)
{
- source.Reply(_("%s (%s) was last seen changing nick from %s to %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->nick2.c_str(), target.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen changing nick from \002{2}\002 to \002{3} {4}\002 ago{5}"),
+ target, info->vhost, info->nick2, target, timebuf, onlinestatus);
}
else if (info->type == JOIN)
{
if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was last seen joining a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen joining a secret channel \002{2}\002 ago{3}"),
+ target, info->vhost, timebuf, onlinestatus);
else
- source.Reply(_("%s (%s) was last seen joining %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen joining \002{2} {3}\002 ago{4}"),
+ target, info->vhost, info->channel, timebuf, onlinestatus);
}
else if (info->type == PART)
{
if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was last seen parting a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen parting a secret channel \002{2}\002 ago{3}"),
+ target, info->vhost, timebuf, onlinestatus);
else
- source.Reply(_("%s (%s) was last seen parting %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen parting \002{2} {3}\002 ago{4}"),
+ target, info->vhost, info->channel, timebuf, onlinestatus);
}
else if (info->type == QUIT)
{
- source.Reply(_("%s (%s) was last seen quitting (%s) %s ago (%s)."),
- target.c_str(), info->vhost.c_str(), info->message.c_str(), timebuf.c_str(), timebuf2.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was last seen quitting (\002{2}\002) \002{3}\002 ago (\002{4}\\2)."),
+ target, info->vhost, info->message, timebuf, timebuf2);
}
else if (info->type == KICK)
{
if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was kicked from a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was kicked from a secret channel \002{2}\002 ago{3}"),
+ target, info->vhost, timebuf, onlinestatus);
else
- source.Reply(_("%s (%s) was kicked from %s (\"%s\") %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), info->message.c_str(), timebuf.c_str(), onlinestatus.c_str());
+ source.Reply(_("\002{0}\002 (\002{1}\002) was kicked from \002{2}\002 (\"{3}\") {4} ago{5}"),
+ target, info->vhost, info->channel, info->message, timebuf, onlinestatus);
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Checks for the last time \037nick\037 was seen joining, leaving,\n"
- "or changing nick on the network and tells you when and, depending\n"
- "on channel or user settings, where it was."));
+ source.Reply(_("Checks for the last time \037nick\037 was seen joining, leaving, or changing nick on the network and tells you when and, depending on channel or user settings, where it was."));
return true;
}
};
class CSSeen : public Module
+ , public EventHook<Event::ExpireTick>
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::UserQuit>
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::PartChannel>
+ , public EventHook<Event::PreUserKicked>
{
- Serialize::Type seeninfo_type;
+ //Serialize::TypeBase seeninfo_type;
CommandSeen commandseen;
CommandOSSeen commandosseen;
+
public:
- CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), seeninfo_type("SeenInfo", SeenInfo::Unserialize), commandseen(this), commandosseen(this)
+ CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ // , seeninfo_type("SeenInfo", SeenInfo::Unserialize)
+ , commandseen(this)
+ , commandosseen(this)
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
simple = conf->GetModule(this)->Get<bool>("simple");
}
- void OnExpireTick() anope_override
+ void OnExpireTick() override
{
size_t previous_size = database.size();
time_t purgetime = Config->GetModule(this)->Get<time_t>("purgetime");
@@ -405,36 +429,37 @@ class CSSeen : public Module
Log(LOG_DEBUG) << "cs_seen: Purged database, checked " << previous_size << " nicks and removed " << (previous_size - database.size()) << " old entries.";
}
- void OnUserConnect(User *u, bool &exempt) anope_override
+ void OnUserConnect(User *u, bool &exempt) override
{
if (!u->Quitting())
UpdateUser(u, NEW, u->nick, "", "", "");
}
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
+ void OnUserNickChange(User *u, const Anope::string &oldnick) override
{
UpdateUser(u, NICK_TO, oldnick, u->nick, "", "");
UpdateUser(u, NICK_FROM, u->nick, oldnick, "", "");
}
- void OnUserQuit(User *u, const Anope::string &msg) anope_override
+ void OnUserQuit(User *u, const Anope::string &msg) override
{
UpdateUser(u, QUIT, u->nick, "", "", msg);
}
- void OnJoinChannel(User *u, Channel *c) anope_override
+ void OnJoinChannel(User *u, Channel *c) override
{
UpdateUser(u, JOIN, u->nick, "", c->name, "");
}
- void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) anope_override
+ void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) override
{
UpdateUser(u, PART, u->nick, "", channel, msg);
}
- void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) anope_override
+ EventReturn OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) override
{
UpdateUser(cu->user, KICK, cu->user->nick, source.GetSource(), cu->chan->name, msg);
+ return EVENT_CONTINUE;
}
private:
@@ -457,3 +482,4 @@ class CSSeen : public Module
};
MODULE_INIT(CSSeen)
+#endif
diff --git a/modules/chanserv/set.cpp b/modules/chanserv/set.cpp
new file mode 100644
index 000000000..0d3e6e77e
--- /dev/null
+++ b/modules/chanserv/set.cpp
@@ -0,0 +1,1291 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/mode.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/info.h"
+#include "modules/chanserv/set.h"
+
+class CommandCSSet : public Command
+{
+ ServiceReference<ModeLocks> mlocks;
+
+ public:
+ CommandCSSet(Module *creator) : Command(creator, "chanserv/set", 2, 3)
+ {
+ this->SetDesc(_("Set channel options and information"));
+ this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Allows the channel founder to set various channel options and other information.\n"
+ "\n"
+ "Available options:"));
+ Anope::string this_name = source.command;
+ bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
+ hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
+ for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
+ {
+ const Anope::string &c_name = it->first;
+ const CommandInfo &info = it->second;
+ if (c_name.find_ci(this_name + " ") == 0)
+ {
+ ServiceReference<Command> c(info.name);
+
+ // XXX dup
+ if (!c)
+ continue;
+ else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
+ continue;
+ else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
+ continue;
+
+ source.command = it->first;
+ c->OnServHelp(source);
+ }
+ }
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("Type \002{0}{1} {2} {3} \037option\037\002 for more information on a particular option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, this_name);
+
+ return true;
+ }
+};
+
+class CommandCSSetAutoOp : public Command
+{
+ public:
+ CommandCSSetAutoOp(Module *creator, const Anope::string &cname = "chanserv/set/autoop") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Should services automatically give status to users"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, params[1]);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (params[1].equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable autoop";
+ ci->UnsetS<bool>("NOAUTOOP");
+ source.Reply(_("Services will now automatically give modes to users in \002{0}\002."), ci->GetName());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable autoop";
+ ci->SetS<bool>("NOAUTOOP", true);
+ source.Reply(_("Services will no longer automatically give modes to users in \002{0}\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "AUTOOP");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables AUTOOP for a \037channel\037. When disabled, users who join \037channel\037 will not automatically gain any status from {0}."), source.service->nick);
+ return true;
+ }
+};
+
+class CommandCSSetBanType : public Command
+{
+ public:
+ CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Set how Services make bans on the channel"));
+ this->SetSyntax(_("\037channel\037 \037bantype\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, params[1]);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ try
+ {
+ int16_t new_type = convertTo<int16_t>(params[1]);
+ if (new_type < 0 || new_type > 3)
+ throw ConvertException("Invalid range");
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the ban type to " << new_type;
+ ci->SetBanType(new_type);
+ source.Reply(_("Ban type for channel \002{0}\002 is now \002#{1}\002."), ci->GetName(), new_type);
+ }
+ catch (const ConvertException &)
+ {
+ source.Reply(_("\002{0}\002 is not a valid ban type."), params[1]);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets the ban type that will be used by services whenever they need to ban someone from your channel.\n"
+ "\n"
+ "Bantype is a number between 0 and 3 that means:\n"
+ "\n"
+ "0: ban in the form *!user@host\n"
+ "1: ban in the form *!*user@host\n"
+ "2: ban in the form *!*@host\n"
+ "3: ban in the form *!*user@*.domain"));
+ return true;
+ }
+};
+
+class CommandCSSetDescription : public Command
+{
+ public:
+ CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description") : Command(creator, cname, 1, 2)
+ {
+ this->SetDesc(_("Set the channel description"));
+ this->SetSyntax(_("\037channel\037 [\037description\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params.size() > 1 ? params[1] : "";
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ ci->SetDesc(param);
+ if (!param.empty())
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the description to " << ci->GetDesc();
+ source.Reply(_("Description of \002{0}\002 changed to \002{1}\002."), ci->GetName(), ci->GetDesc());
+ }
+ else
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset the description";
+ source.Reply(_("Description of \002{0}\002 unset."), ci->GetName());
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets the description for the channel, which shows up with the \002LIST\002 and \002INFO\002 commands."));
+ return true;
+ }
+};
+
+class CommandCSSetFounder : public Command
+{
+ public:
+ CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Set the founder of a channel"));
+ this->SetSyntax(_("\037channel\037 \037user\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && (ci->HasFieldS("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(param);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), param);
+ return;
+ }
+
+ NickServ::Account *nc = na->GetAccount();
+ unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
+ if (max_reg && nc->GetChannelCount() >= max_reg && !source.HasPriv("chanserv/no-register-limit"))
+ {
+ source.Reply(_("\002{0}\002 has too many channels registered."), na->GetNick());
+ return;
+ }
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "(none)") << " to " << nc->GetDisplay();
+
+ ci->SetFounder(nc);
+
+ source.Reply(_("Founder of \002{0}\002 changed to \002{1}\002."), ci->GetName(), na->GetNick());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the founder of \037channel\037 to \037user\037. Using this command will cause you to lose your founder access to \037channel\037, and cannot be undone."
+ "\n"
+ "Use of this command requires being the founder or \037channel\037 or having the \002{0}\002 privilege, if secure founder is enabled or not, respectively."));
+ return true;
+ }
+};
+
+class CommandCSSetKeepModes : public Command
+{
+ public:
+ CommandCSSetKeepModes(Module *creator, const Anope::string &cname = "chanserv/set/keepmodes") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Retain modes when channel is not in use"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keep modes";
+ ci->SetS<bool>("CS_KEEP_MODES", true);
+ source.Reply(_("Keep modes for \002{0}\002 is now \002on\002."), ci->GetName());
+ if (ci->c)
+ for (const std::pair<Anope::string, Anope::string> &p : ci->c->GetModes())
+ {
+ ChanServ::Mode *mode = Serialize::New<ChanServ::Mode *>();
+ mode->SetChannel(ci);
+ mode->SetMode(p.first);
+ mode->SetParam(p.second);
+ }
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keep modes";
+ ci->UnsetS<bool>("CS_KEEP_MODES");
+ source.Reply(_("Keep modes for \002{0}\002 is now \002off\002."), ci->GetName());
+ for (ChanServ::Mode *m : ci->GetRefs<ChanServ::Mode *>())
+ m->Delete();
+ }
+ else
+ this->OnSyntaxError(source, "KEEPMODES");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables keepmodes for \037channel\037. If keepmodes is enabled, services will remember modes set on the channel and re-set them the next time the channel is created."));
+ return true;
+ }
+};
+
+class CommandCSSetPeace : public Command
+{
+ public:
+ CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Regulate the use of critical commands"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable peace";
+ ci->SetS<bool>("PEACE", true);
+ source.Reply(_("Peace option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable peace";
+ ci->UnsetS<bool>("PEACE");
+ source.Reply(_("Peace option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "PEACE");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables the \002peace\002 option for \037channel\037."
+ " When \002peace\002 is set, a user won't be able to kick, ban or remove a channel status of a user that has a level superior or equal to his via services."),
+ source.service->nick);
+ return true;
+ }
+};
+
+inline static Anope::string BotModes()
+{
+ return Config->GetModule("botserv")->Get<Anope::string>("botmodes",
+ Config->GetModule("chanserv")->Get<Anope::string>("botmodes", "o")
+ );
+}
+
+class CommandCSSetPersist : public Command
+{
+ ServiceReference<ModeLocks> mlocks;
+
+ public:
+ CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Set the channel as permanent"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
+
+ if (params[1].equals_ci("ON"))
+ {
+ if (!ci->HasFieldS("PERSIST"))
+ {
+ ci->SetS<bool>("PERSIST", true);
+
+ /* Channel doesn't exist, create it */
+ if (!ci->c)
+ {
+ bool created;
+ Channel *c = Channel::FindOrCreate(ci->GetName(), created);
+ if (ci->GetBot())
+ {
+ ChannelStatus status(BotModes());
+ ci->GetBot()->Join(c, &status);
+ }
+ if (created)
+ c->Sync();
+ }
+
+ /* Set the perm mode */
+ if (cm)
+ {
+ if (ci->c && !ci->c->HasMode("PERM"))
+ ci->c->SetMode(NULL, cm);
+ /* Add it to the channels mlock */
+ if (mlocks)
+ mlocks->SetMLock(ci, cm, true, "", source.GetNick());
+ }
+ /* No botserv bot, no channel mode, give them ChanServ.
+ * Yes, this works fine with no BotServ.
+ */
+ else if (!ci->GetBot())
+ {
+ ServiceBot *ChanServ = Config->GetClient("ChanServ");
+ if (!ChanServ)
+ {
+ source.Reply(_("ChanServ is required to enable persist on this network."));
+ return;
+ }
+
+ ChanServ->Assign(NULL, ci);
+ if (!ci->c->FindUser(ChanServ))
+ {
+ ChannelStatus status(BotModes());
+ ChanServ->Join(ci->c, &status);
+ }
+ }
+ }
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable persist";
+ source.Reply(_("Channel \002{0}\002 is now persistent."), ci->GetName());
+ }
+ else if (params[1].equals_ci("OFF"))
+ {
+ if (ci->HasFieldS("PERSIST"))
+ {
+ ci->UnsetS<bool>("PERSIST");
+
+ ServiceBot *ChanServ = Config->GetClient("ChanServ"),
+ *BotServ = Config->GetClient("BotServ");
+
+ /* Unset perm mode */
+ if (cm)
+ {
+ if (ci->c && ci->c->HasMode("PERM"))
+ ci->c->RemoveMode(NULL, cm);
+ /* Remove from mlock */
+ if (mlocks)
+ mlocks->RemoveMLock(ci, cm, true);
+ }
+ /* No channel mode, no BotServ, but using ChanServ as the botserv bot
+ * which was assigned when persist was set on
+ */
+ else if (!cm && !BotServ && ci->GetBot())
+ {
+ if (!ChanServ)
+ {
+ source.Reply(_("ChanServ is required to enable persist on this network."));
+ return;
+ }
+
+ /* Unassign bot */
+ ChanServ->UnAssign(NULL, ci);
+ }
+ }
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable persist";
+ source.Reply(_("Channel \002{0}\002 is no longer persistent."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "PERSIST");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables the persistent channel setting."
+ " When persistent is set, the service bot will remain in the channel when it has emptied of users."));
+ return true;
+ }
+};
+
+class CommandCSSetRestricted : public Command
+{
+ public:
+ CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Restrict access to the channel"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable restricted";
+ ci->SetS<bool>("RESTRICTED", true);
+ source.Reply(_("Restricted access option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable restricted";
+ ci->UnsetS<bool>("RESTRICTED");
+ source.Reply(_("Restricted access option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "RESTRICTED");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables the \002restricted access\002 option for \037channel\037. When \002restricted access\002 is set, users not on the access list will not be permitted to join the channel."));
+ return true;
+ }
+};
+
+class CommandCSSetSecure : public Command
+{
+ public:
+ CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Activate security features"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure";
+ ci->SetS<bool>("CS_SECURE", true);
+ source.Reply(_("Secure option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure";
+ ci->UnsetS<bool>("CS_SECURE");
+ source.Reply(_("Secure option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "SECURE");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables security features for a channel."
+ " When \002secure\002 is set, only users who have logged in (eg. not recognized based on their hostmask)"
+ " will be given access to channels from account-based access entries"));
+ return true;
+ }
+};
+
+class CommandCSSetSecureFounder : public Command
+{
+ public:
+ CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Stricter control of channel founder status"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && (ci->HasFieldS("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure founder";
+ ci->SetS<bool>("SECUREFOUNDER", true);
+ source.Reply(_("Secure founder option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure founder";
+ ci->UnsetS<bool>("SECUREFOUNDER");
+ source.Reply(_("Secure founder option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "SECUREFOUNDER");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Enables or disables the \002secure founder\002 option for a channel."
+ " When \002secure founder\002 is set, only the real founder will be able to drop the channel, change its founder, and change its successor."
+ " Otherwise, anyone with the \002{0}\002 privilege will be able to use these commands."),
+ "FOUNDER");
+ return true;
+ }
+};
+
+class CommandCSSetSecureOps : public Command
+{
+ public:
+ CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Stricter control of chanop status"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure ops";
+ ci->SetS<bool>("SECUREOPS", true);
+ source.Reply(_("Secure ops option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure ops";
+ ci->UnsetS<bool>("SECUREOPS");
+ source.Reply(_("Secure ops option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "SECUREOPS");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables the \002secure ops\002 option for \037channel\037."
+ " When \002secure ops\002 is set, users will not be allowed to have channel operator status if they do not have the privileges for it."));
+ return true;
+ }
+};
+
+class CommandCSSetSignKick : public Command
+{
+ public:
+ CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Sign kicks that are done with the KICK command"));
+ this->SetSyntax(_("\037channel\037 {ON | LEVEL | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ ci->SetS<bool>("SIGNKICK", true);
+ ci->UnsetS<bool>("SIGNKICK_LEVEL");
+ source.Reply(_("Signed kick option for \002{0}\002 is now \002on\002."), ci->GetName());
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick";
+ }
+ else if (param.equals_ci("LEVEL"))
+ {
+ ci->SetS<bool>("SIGNKICK_LEVEL", true);
+ ci->UnsetS<bool>("SIGNKICK");
+ source.Reply(_("Signed kick option for \002{0}\002 is now \002on\002, but depends of the privileges of the user that is using the command."), ci->GetName());
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick level";
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ ci->UnsetS<bool>("SIGNKICK");
+ ci->UnsetS<bool>("SIGNKICK_LEVEL");
+ source.Reply(_("Signed kick option for \002{0}\002 is now \002off\002."), ci->GetName());
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable sign kick";
+ }
+ else
+ this->OnSyntaxError(source, "SIGNKICK");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables \002signed kicks\002 for \037channel\037."
+ " When \002signed kicks\002 is enabled, kicks issued through services will have the nickname of the user who performed the kick included in the kick reason."
+ " If you use \002LEVEL\002 setting, then only users who do not have the \002{0}\002 privilege will have their kicks signed."),
+ "SIGNKICK");
+ return true;
+ }
+};
+
+class CommandCSSetSuccessor : public Command
+{
+ public:
+ CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor") : Command(creator, cname, 1, 2)
+ {
+ this->SetDesc(_("Set the successor for a channel"));
+ this->SetSyntax(_("\037channel\037 \037nick\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && (ci->HasFieldS("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ NickServ::Account *nc;
+
+ if (!param.empty())
+ {
+ NickServ::Nick *na = NickServ::FindNick(param);
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), param);
+ return;
+ }
+
+ if (na->GetAccount() == ci->GetFounder())
+ {
+ source.Reply(_("\002{0}\002 cannot be the successor of channel \002{1}\002 as they are the founder."), na->GetNick(), ci->GetName());
+ return;
+ }
+
+ nc = na->GetAccount();
+ }
+ else
+ nc = NULL;
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the successor from " << (ci->GetSuccessor() ? ci->GetSuccessor()->GetDisplay() : "(none)") << " to " << (nc ? nc->GetDisplay() : "(none)");
+
+ ci->SetSuccessor(nc);
+
+ if (nc)
+ source.Reply(_("Successor for \002{0}\002 changed to \002{1}\002."), ci->GetName(), nc->GetDisplay());
+ else
+ source.Reply(_("Successor for \002{0}\002 unset."), ci->GetName());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the successor of \037channel\037."
+ " The successor of a channel is automatically given ownership of the channel if the founder's account drops of expires."
+ " If the success has too many registered channels or there is no successor, the channel may instead be given to one of the users on the channel access list with the most privileges."));
+ return true;
+ }
+};
+
+class CommandCSSetNoexpire : public Command
+{
+ public:
+ CommandCSSetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2)
+ {
+ this->SetDesc(_("Prevent the channel from expiring"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (source.permission.empty() && !source.AccessFor(ci).HasPriv("SET"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(LOG_ADMIN, source, this, ci) << "to enable noexpire";
+ ci->SetS<bool>("CS_NO_EXPIRE", true);
+ source.Reply(_("Channel \002{0} will not\002 expire."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(LOG_ADMIN, source, this, ci) << "to disable noexpire";
+ ci->UnsetS<bool>("CS_NO_EXPIRE");
+ source.Reply(_("Channel \002{0} will\002 expire."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "NOEXPIRE");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets whether the given \037channel\037 will expire. Setting \002 noexpire\002 to \002on\002 prevents the channel from expiring."));
+ return true;
+ }
+};
+
+class CSSet : public Module
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::CheckKick>
+ , public EventHook<Event::DelChan>
+ , public EventHook<Event::ChannelModeSet>
+ , public EventHook<Event::ChannelModeUnset>
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::SetCorrectModes>
+ , public EventHook<ChanServ::Event::PreChanExpire>
+ , public EventHook<Event::ChanInfo>
+{
+ Serialize::Field<ChanServ::Channel, bool> noautoop, peace, securefounder,
+ restricted, secure, secureops, signkick, signkick_level, noexpire, keep_modes, persist;
+
+ CommandCSSet commandcsset;
+ CommandCSSetAutoOp commandcssetautoop;
+ CommandCSSetBanType commandcssetbantype;
+ CommandCSSetDescription commandcssetdescription;
+ CommandCSSetFounder commandcssetfounder;
+ CommandCSSetKeepModes commandcssetkeepmodes;
+ CommandCSSetPeace commandcssetpeace;
+ CommandCSSetPersist commandcssetpersist;
+ CommandCSSetRestricted commandcssetrestricted;
+ CommandCSSetSecure commandcssetsecure;
+ CommandCSSetSecureFounder commandcssetsecurefounder;
+ CommandCSSetSecureOps commandcssetsecureops;
+ CommandCSSetSignKick commandcssetsignkick;
+ CommandCSSetSuccessor commandcssetsuccessor;
+ CommandCSSetNoexpire commandcssetnoexpire;
+
+ ExtensibleRef<bool> inhabit;
+
+ bool persist_lower_ts;
+
+ public:
+ CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::ChannelSync>(this)
+ , EventHook<Event::CheckKick>(this)
+ , EventHook<Event::DelChan>(this)
+ , EventHook<Event::ChannelModeSet>(this)
+ , EventHook<Event::ChannelModeUnset>(this)
+ , EventHook<Event::JoinChannel>(this)
+ , EventHook<Event::SetCorrectModes>(this)
+ , EventHook<ChanServ::Event::PreChanExpire>(this)
+ , EventHook<Event::ChanInfo>(this)
+
+ , noautoop(this, "NOAUTOOP")
+ , peace(this, "PEACE")
+ , securefounder(this, "SECUREFOUNDER")
+ , restricted(this, "RESTRICTED")
+ , secure(this, "CS_SECURE")
+ , secureops(this, "SECUREOPS")
+ , signkick(this, "SIGNKICK")
+ , signkick_level(this, "SIGNKICK_LEVEL")
+ , noexpire(this, "CS_NO_EXPIRE")
+ , keep_modes(this, "CS_KEEP_MODES")
+ , persist(this, "PERSIST")
+
+ , commandcsset(this)
+ , commandcssetautoop(this)
+ , commandcssetbantype(this)
+ , commandcssetdescription(this)
+ , commandcssetfounder(this)
+ , commandcssetkeepmodes(this)
+ , commandcssetpeace(this)
+ , commandcssetpersist(this)
+ , commandcssetrestricted(this)
+ , commandcssetsecure(this)
+ , commandcssetsecurefounder(this)
+ , commandcssetsecureops(this)
+ , commandcssetsignkick(this)
+ , commandcssetsuccessor(this)
+ , commandcssetnoexpire(this)
+
+ , inhabit("inhabit")
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ persist_lower_ts = conf->GetModule(this)->Get<bool>("persist_lower_ts");
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ ci->SetBanType(Config->GetModule(this)->Get<int>("defbantype", "2"));
+ }
+
+ void OnChannelSync(Channel *c) override
+ {
+ if (c->ci && keep_modes.HasExt(c->ci))
+ for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>())
+ c->SetMode(c->ci->WhoSends(), m->GetMode(), m->GetParam());
+ }
+
+ EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
+ {
+ if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
+ return EVENT_CONTINUE;
+
+ if (c->ci->AccessFor(u).empty() && (!c->ci->GetFounder() || u->Account() != c->ci->GetFounder()))
+ return EVENT_STOP;
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnDelChan(ChanServ::Channel *ci) override
+ {
+ if (ci->c && persist.HasExt(ci))
+ ci->c->RemoveMode(ci->WhoSends(), "PERM", "", false);
+ persist.Unset(ci);
+ }
+
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override
+ {
+ if (c->ci)
+ {
+ /* Channel mode +P or so was set, mark this channel as persistent */
+ if (mode->name == "PERM")
+ persist.Set(c->ci, true);
+
+ if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
+ {
+ ChanServ::Mode *m = Serialize::New<ChanServ::Mode *>();
+ if (m != nullptr)
+ {
+ m->SetChannel(c->ci);
+ m->SetMode(mode->name);
+ m->SetParam(param);
+ }
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override
+ {
+ if (mode->name == "PERM")
+ {
+ if (c->ci)
+ persist.Unset(c->ci);
+ }
+
+ if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
+ for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>())
+ if (m->GetMode() == mode->name && m->GetParam().equals_ci(param))
+ m->Delete();
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnJoinChannel(User *u, Channel *c) override
+ {
+ if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->GetTimeRegistered())
+ {
+ Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->GetTimeRegistered();
+ c->creation_time = c->ci->GetTimeRegistered();
+ IRCD->SendChannel(c);
+ c->Reset();
+ }
+ }
+
+ void OnSetCorrectModes(User *user, Channel *chan, ChanServ::AccessGroup &access, bool &give_modes, bool &take_modes) override
+ {
+ if (chan->ci)
+ {
+ if (noautoop.HasExt(chan->ci))
+ give_modes = false;
+ if (secureops.HasExt(chan->ci))
+ // This overrides what chanserv does because it is loaded after chanserv
+ take_modes = true;
+ }
+ }
+
+ void OnPreChanExpire(ChanServ::Channel *ci, bool &expire) override
+ {
+ if (noexpire.HasExt(ci))
+ expire = false;
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override
+ {
+ if (!show_all)
+ return;
+
+ if (peace.HasExt(ci))
+ info.AddOption(_("Peace"));
+ if (restricted.HasExt(ci))
+ info.AddOption(_("Restricted access"));
+ if (secure.HasExt(ci))
+ info.AddOption(_("Security"));
+ if (securefounder.HasExt(ci))
+ info.AddOption(_("Secure founder"));
+ if (secureops.HasExt(ci))
+ info.AddOption(_("Secure ops"));
+ if (signkick.HasExt(ci) || signkick_level.HasExt(ci))
+ info.AddOption(_("Signed kicks"));
+ if (persist.HasExt(ci))
+ info.AddOption(_("Persistent"));
+ if (noexpire.HasExt(ci))
+ info.AddOption(_("No expire"));
+ if (keep_modes.HasExt(ci))
+ info.AddOption(_("Keep modes"));
+ if (noautoop.HasExt(ci))
+ info.AddOption(_("No auto-op"));
+ }
+};
+
+MODULE_INIT(CSSet)
diff --git a/modules/chanserv/set_misc.cpp b/modules/chanserv/set_misc.cpp
new file mode 100644
index 000000000..b2c0dc50c
--- /dev/null
+++ b/modules/chanserv/set_misc.cpp
@@ -0,0 +1,227 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/chanserv/set_misc.h"
+#include "modules/chanserv/info.h"
+#include "modules/chanserv/set.h"
+
+static Anope::map<Anope::string> descriptions;
+
+class CSMiscDataImpl : public CSMiscData
+{
+ friend class CSMiscDataType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string name, data;
+
+ public:
+ CSMiscDataImpl(Serialize::TypeBase *type) : CSMiscData(type) { }
+ CSMiscDataImpl(Serialize::TypeBase *type, Serialize::ID id) : CSMiscData(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *s) override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &n) override;
+
+ Anope::string GetData() override;
+ void SetData(const Anope::string &d) override;
+};
+
+class CSMiscDataType : public Serialize::Type<CSMiscDataImpl>
+{
+ public:
+ Serialize::ObjectField<CSMiscDataImpl, ChanServ::Channel *> owner;
+ Serialize::Field<CSMiscDataImpl, Anope::string> name, data;
+
+ CSMiscDataType(Module *me) : Serialize::Type<CSMiscDataImpl>(me)
+ , owner(this, "owner", &CSMiscDataImpl::channel, true)
+ , name(this, "name", &CSMiscDataImpl::name)
+ , data(this, "data", &CSMiscDataImpl::data)
+ {
+ }
+};
+
+ChanServ::Channel *CSMiscDataImpl::GetChannel()
+{
+ return Get(&CSMiscDataType::owner);
+}
+
+void CSMiscDataImpl::SetChannel(ChanServ::Channel *s)
+{
+ Set(&CSMiscDataType::owner, s);
+}
+
+Anope::string CSMiscDataImpl::GetName()
+{
+ return Get(&CSMiscDataType::name);
+}
+
+void CSMiscDataImpl::SetName(const Anope::string &n)
+{
+ Set(&CSMiscDataType::name, n);
+}
+
+Anope::string CSMiscDataImpl::GetData()
+{
+ return Get(&CSMiscDataType::data);
+}
+
+void CSMiscDataImpl::SetData(const Anope::string &d)
+{
+ Set(&CSMiscDataType::data, d);
+}
+
+class CommandCSSetMisc : public Command
+{
+ Anope::string GetAttribute(const Anope::string &command)
+ {
+ size_t sp = command.rfind(' ');
+ if (sp != Anope::string::npos)
+ return command.substr(sp + 1);
+ return command;
+ }
+
+ public:
+ CommandCSSetMisc(Module *creator, const Anope::string &cname = "chanserv/set/misc") : Command(creator, cname, 1, 2)
+ {
+ this->SetSyntax(_("\037channel\037 [\037parameters\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ Anope::string scommand = GetAttribute(source.command);
+
+ /* remove existing */
+ for (CSMiscData *data : ci->GetRefs<CSMiscData *>())
+ if (data->GetName() == scommand)
+ {
+ data->Delete();
+ break;
+ }
+
+ if (!param.empty())
+ {
+ CSMiscData *data = Serialize::New<CSMiscData *>();
+ data->SetChannel(ci);
+ data->SetName(scommand);
+ data->SetData(param);
+
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change it to " << param;
+ source.Reply(_("\002{0}\002 for \002{1}\002 set to \002{2}\002."), scommand, ci->GetName(), param);
+ }
+ else
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset it";
+ source.Reply(_("\002{0}\002 for \002{1}\002 unset."), scommand, ci->GetName());
+ }
+ }
+
+ void OnServHelp(CommandSource &source) override
+ {
+ if (descriptions.count(source.command))
+ {
+ this->SetDesc(descriptions[source.command]);
+ Command::OnServHelp(source);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (descriptions.count(source.command))
+ {
+ source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
+ return true;
+ }
+ return false;
+ }
+};
+
+class CSSetMisc : public Module
+ , public EventHook<Event::ChanInfo>
+{
+ CommandCSSetMisc commandcssetmisc;
+ CSMiscDataType type;
+
+ public:
+ CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanInfo>(this)
+ , commandcssetmisc(this)
+ , type(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ descriptions.clear();
+
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
+ {
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ if (block->Get<Anope::string>("command") != "chanserv/set/misc")
+ continue;
+
+ Anope::string cname = block->Get<Anope::string>("name");
+ Anope::string desc = block->Get<Anope::string>("misc_description");
+
+ if (cname.empty() || desc.empty())
+ continue;
+
+ descriptions[cname] = desc;
+ }
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool) override
+ {
+ for (CSMiscData *data : ci->GetRefs<CSMiscData *>())
+ info[data->GetName()] = data->GetData();
+ }
+};
+
+MODULE_INIT(CSSetMisc)
diff --git a/modules/chanserv/status.cpp b/modules/chanserv/status.cpp
new file mode 100644
index 000000000..3e4b669d3
--- /dev/null
+++ b/modules/chanserv/status.cpp
@@ -0,0 +1,123 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/akick.h"
+
+class CommandCSStatus : public Command
+{
+public:
+ CommandCSStatus(Module *creator) : Command(creator, "chanserv/status", 1, 2)
+ {
+ this->SetDesc(_("Find a user's status on a channel"));
+ this->SetSyntax(_("\037channel\037 [\037user\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &channel = params[0];
+
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/auspex"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+
+ Anope::string nick = source.GetNick();
+ if (params.size() > 1)
+ nick = params[1];
+
+ ChanServ::AccessGroup ag;
+ User *u = User::Find(nick, true);
+ NickServ::Nick *na = NULL;
+ if (u != NULL)
+ ag = ci->AccessFor(u);
+ else
+ {
+ na = NickServ::FindNick(nick);
+ if (na != NULL)
+ ag = ci->AccessFor(na->GetAccount());
+ }
+
+ if (ag.super_admin)
+ source.Reply(_("\002{0}\002 is a super administrator."), nick);
+ else if (ag.founder)
+ source.Reply(_("\002{0}\002 is the founder of \002{1}\002."), nick, ci->GetName());
+ else if (ag.empty())
+ source.Reply(_("\002{0}\002 has no access on \002{1}\002."), nick, ci->GetName());
+ else
+ {
+ source.Reply(_("Access for \002{0}\002 on \002{1}\002:"), nick, ci->GetName());
+
+ for (unsigned i = 0; i < ag.size(); ++i)
+ {
+ ChanServ::ChanAccess *acc = ag[i];
+
+ source.Reply(_("\002{0}\002 matches access entry \002{1}\002, which has privilege \002{2}\002."), nick, acc->Mask(), acc->AccessSerialize());
+ }
+ }
+
+ for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
+ {
+ AutoKick *ak = ci->GetAkick(j);
+
+ if (ak->GetAccount())
+ {
+ if (na && ak->GetAccount() == na->GetAccount())
+ source.Reply(_("\002{0}\002 is on the auto kick list of \002{1}\002 ({2})."), na->GetAccount()->GetDisplay(), ci->GetName(), ak->GetReason());
+ }
+ else if (u != NULL)
+ {
+ Entry akick_mask("", ak->GetMask());
+ if (akick_mask.Matches(u))
+ source.Reply(_("\002{0}\002 matches auto kick entry \002{1}\002 on \002{2}\002 ({3})."), u->nick, ak->GetMask(), ci->GetName(), ak->GetReason());
+ }
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command tells you what access \037user\037 has on \037channel\037."
+ "It will also tell you which access and auto kick entries match \037user\037.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "ACCESS_CHANGE");
+ return true;
+ }
+};
+
+class CSStatus : public Module
+{
+ CommandCSStatus commandcsstatus;
+
+ public:
+ CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsstatus(this)
+ {
+ }
+};
+
+MODULE_INIT(CSStatus)
diff --git a/modules/cs_statusupdate.cpp b/modules/chanserv/statusupdate.cpp
index ffdbec3e7..0d3a25d0f 100644
--- a/modules/cs_statusupdate.cpp
+++ b/modules/chanserv/statusupdate.cpp
@@ -1,32 +1,46 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
class StatusUpdate : public Module
+ , public EventHook<Event::AccessAdd>
+ , public EventHook<Event::AccessDel>
{
public:
StatusUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::AccessAdd>(this)
+ , EventHook<Event::AccessDel>(this)
{
}
- void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override
+ void OnAccessAdd(ChanServ::Channel *ci, CommandSource &, ChanServ::ChanAccess *access) override
{
if (ci->c)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
User *user = it->second->user;
- ChannelInfo *next;
- if (user->server != Me && access->Matches(user, user->Account(), next))
+ if (user->server != Me && access->Matches(user, user->Account()))
{
- AccessGroup ag = ci->AccessFor(user);
+ ChanServ::AccessGroup ag = ci->AccessFor(user);
for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
{
@@ -39,17 +53,17 @@ class StatusUpdate : public Module
}
}
- void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override
+ // XXX this relies on the access entry already being removed from the list?
+ void OnAccessDel(ChanServ::Channel *ci, CommandSource &, ChanServ::ChanAccess *access) override
{
if (ci->c)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
User *user = it->second->user;
- ChannelInfo *next;
- if (user->server != Me && access->Matches(user, user->Account(), next))
+ if (user->server != Me && access->Matches(user, user->Account()))
{
- AccessGroup ag = ci->AccessFor(user);
+ ChanServ::AccessGroup ag = ci->AccessFor(user);
for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
{
diff --git a/modules/chanserv/suspend.cpp b/modules/chanserv/suspend.cpp
new file mode 100644
index 000000000..c825c35f7
--- /dev/null
+++ b/modules/chanserv/suspend.cpp
@@ -0,0 +1,350 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/suspend.h"
+#include "modules/chanserv/drop.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/info.h"
+
+class CSSuspendInfoImpl : public CSSuspendInfo
+{
+ friend class CSSuspendType;
+
+ ChanServ::Channel *channel = nullptr;
+ Anope::string by, reason;
+ time_t when = 0, expires = 0;
+
+ public:
+ CSSuspendInfoImpl(Serialize::TypeBase *type) : CSSuspendInfo(type) { }
+ CSSuspendInfoImpl(Serialize::TypeBase *type, Serialize::ID id) : CSSuspendInfo(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *s) override;
+
+ Anope::string GetBy() override;
+ void SetBy(const Anope::string &by) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &reason) override;
+
+ time_t GetWhen() override;
+ void SetWhen(const time_t &w) override;
+
+ time_t GetExpires() override;
+ void SetExpires(const time_t &e) override;
+};
+
+class CSSuspendType : public Serialize::Type<CSSuspendInfoImpl>
+{
+ public:
+ Serialize::ObjectField<CSSuspendInfoImpl, ChanServ::Channel *> channel;
+ Serialize::Field<CSSuspendInfoImpl, Anope::string> by, reason;
+ Serialize::Field<CSSuspendInfoImpl, time_t> when, expires;
+
+ CSSuspendType(Module *me) : Serialize::Type<CSSuspendInfoImpl>(me)
+ , channel(this, "chan", &CSSuspendInfoImpl::channel, true)
+ , by(this, "by", &CSSuspendInfoImpl::by)
+ , reason(this, "reason", &CSSuspendInfoImpl::reason)
+ , when(this, "time", &CSSuspendInfoImpl::when)
+ , expires(this, "expires", &CSSuspendInfoImpl::expires)
+ {
+ }
+};
+
+ChanServ::Channel *CSSuspendInfoImpl::GetChannel()
+{
+ return Get(&CSSuspendType::channel);
+}
+
+void CSSuspendInfoImpl::SetChannel(ChanServ::Channel *s)
+{
+ Set(&CSSuspendType::channel, s);
+}
+
+Anope::string CSSuspendInfoImpl::GetBy()
+{
+ return Get(&CSSuspendType::by);
+}
+
+void CSSuspendInfoImpl::SetBy(const Anope::string &by)
+{
+ Set(&CSSuspendType::by, by);
+}
+
+Anope::string CSSuspendInfoImpl::GetReason()
+{
+ return Get(&CSSuspendType::reason);
+}
+
+void CSSuspendInfoImpl::SetReason(const Anope::string &reason)
+{
+ Set(&CSSuspendType::reason, reason);
+}
+
+time_t CSSuspendInfoImpl::GetWhen()
+{
+ return Get(&CSSuspendType::when);
+}
+
+void CSSuspendInfoImpl::SetWhen(const time_t &w)
+{
+ Set(&CSSuspendType::when, w);
+}
+
+time_t CSSuspendInfoImpl::GetExpires()
+{
+ return Get(&CSSuspendType::expires);
+}
+
+void CSSuspendInfoImpl::SetExpires(const time_t &e)
+{
+ Set(&CSSuspendType::expires, e);
+}
+
+class CommandCSSuspend : public Command
+{
+ public:
+ CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 2, 3)
+ {
+ this->SetDesc(_("Prevent a channel from being used preserving channel data and settings"));
+ this->SetSyntax(_("\037channel\037 [+\037expiry\037] [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ Anope::string expiry = params[1];
+ Anope::string reason = params.size() > 2 ? params[2] : "";
+ time_t expiry_secs = Config->GetModule(this->GetOwner())->Get<time_t>("expire");
+
+ if (!expiry.empty() && expiry[0] != '+')
+ {
+ reason = expiry + " " + reason;
+ reason.trim();
+ expiry.clear();
+ }
+ else
+ {
+ expiry_secs = Anope::DoTime(expiry);
+ if (expiry_secs == -1)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ CSSuspendInfo *si = ci->GetRef<CSSuspendInfo *>();
+ if (si)
+ {
+ source.Reply(_("\002{0}\002 is already suspended."), ci->GetName());
+ return;
+ }
+
+ si = Serialize::New<CSSuspendInfo *>();
+ si->SetChannel(ci);
+ si->SetBy(source.GetNick());
+ si->SetReason(reason);
+ si->SetWhen(Anope::CurTime);
+ si->SetExpires(expiry_secs ? expiry_secs + Anope::CurTime : 0);
+
+ if (ci->c)
+ {
+ std::vector<User *> users;
+
+ for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *uc = it->second;
+ User *user = uc->user;
+ if (!user->HasMode("OPER") && user->server != Me)
+ users.push_back(user);
+ }
+
+ for (unsigned i = 0; i < users.size(); ++i)
+ ci->c->Kick(NULL, users[i], "%s", !reason.empty() ? reason.c_str() : Language::Translate(users[i], _("This channel has been suspended.")));
+ }
+
+ Log(LOG_ADMIN, source, this, ci) << "(" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
+ source.Reply(_("Channel \002{0}\002 is now suspended."), ci->GetName());
+
+ EventManager::Get()->Dispatch(&Event::ChanSuspend::OnChanSuspend, ci);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Disallows anyone from using the given channel."
+ " All channel settings are preserved while the channel is suspended."
+ "If \037expiry\037 is given the channel will be unsuspended after that period of time."));
+ return true;
+ }
+};
+
+class CommandCSUnSuspend : public Command
+{
+ public:
+ CommandCSUnSuspend(Module *creator) : Command(creator, "chanserv/unsuspend", 1, 1)
+ {
+ this->SetDesc(_("Releases a suspended channel"));
+ this->SetSyntax(_("\037channel\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ CSSuspendInfo *si = ci->GetRef<CSSuspendInfo *>();
+ if (!si)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't suspended."), ci->GetName());
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this, ci) << "which was suspended by " << si->GetBy() << " for: " << (!si->GetReason().empty() ? si->GetReason() : "No reason");
+
+ si->Delete();
+
+ source.Reply(_("Channel \002%s\002 is now released."), ci->GetName().c_str());
+
+ EventManager::Get()->Dispatch(&Event::ChanUnsuspend::OnChanUnsuspend, ci);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Releases a suspended channel. All data and settings are preserved from before the suspension."));
+ return true;
+ }
+};
+
+class CSSuspend : public Module
+ , public EventHook<Event::ChanInfo>
+ , public EventHook<ChanServ::Event::PreChanExpire>
+ , public EventHook<Event::CheckKick>
+ , public EventHook<Event::ChanDrop>
+{
+ CommandCSSuspend commandcssuspend;
+ CommandCSUnSuspend commandcsunsuspend;
+ std::vector<Anope::string> show;
+ CSSuspendType cst;
+
+ struct trim
+ {
+ Anope::string operator()(Anope::string s) const
+ {
+ return s.trim();
+ }
+ };
+
+ bool Show(CommandSource &source, const Anope::string &what) const
+ {
+ return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
+ }
+
+ public:
+ CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChanInfo>(this)
+ , EventHook<ChanServ::Event::PreChanExpire>(this)
+ , EventHook<Event::CheckKick>(this)
+ , EventHook<Event::ChanDrop>(this)
+ , commandcssuspend(this)
+ , commandcsunsuspend(this)
+ , cst(this)
+ {
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_hidden) override
+ {
+ CSSuspendInfo *si = ci->GetRef<CSSuspendInfo *>();
+ if (!si)
+ return;
+
+ if (show_hidden || Show(source, "suspended"))
+ info[_("Suspended")] = _("This channel is \002suspended\002.");
+ if (!si->GetBy().empty() && (show_hidden || Show(source, "by")))
+ info[_("Suspended by")] = si->GetBy();
+ if (!si->GetReason().empty() && (show_hidden || Show(source, "reason")))
+ info[_("Suspend reason")] = si->GetReason();
+ if (si->GetWhen() && (show_hidden || Show(source, "on")))
+ info[_("Suspended on")] = Anope::strftime(si->GetWhen(), source.GetAccount());
+ if (si->GetExpires() && (show_hidden || Show(source, "expires")))
+ info[_("Suspension expires")] = Anope::strftime(si->GetExpires(), source.GetAccount());
+ }
+
+ void OnPreChanExpire(ChanServ::Channel *ci, bool &expire) override
+ {
+ CSSuspendInfo *si = ci->GetRef<CSSuspendInfo *>();
+ if (!si)
+ return;
+
+ expire = false;
+
+ if (!si->GetExpires())
+ return;
+
+ if (si->GetExpires() < Anope::CurTime)
+ {
+ ci->SetLastUsed(Anope::CurTime);
+ si->Delete();
+
+ Log(this) << "Expiring suspend for " << ci->GetName();
+ }
+ }
+
+ EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
+ {
+ if (u->HasMode("OPER") || !c->ci || !c->ci->GetRef<CSSuspendInfo *>())
+ return EVENT_CONTINUE;
+
+ reason = Language::Translate(u, _("This channel may not be used."));
+ return EVENT_STOP;
+ }
+
+ EventReturn OnChanDrop(CommandSource &source, ChanServ::Channel *ci) override
+ {
+ CSSuspendInfo *si = ci->GetRef<CSSuspendInfo *>();
+ if (si && !source.HasCommand("chanserv/drop"))
+ {
+ source.Reply(_("Channel \002{0}\002 is currently suspended."), ci->GetName());
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(CSSuspend)
diff --git a/modules/chanserv/sync.cpp b/modules/chanserv/sync.cpp
new file mode 100644
index 000000000..9f9ba4ff7
--- /dev/null
+++ b/modules/chanserv/sync.cpp
@@ -0,0 +1,85 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandCSSync : public Command
+{
+ public:
+ CommandCSSync(Module *creator) : Command(creator, "chanserv/sync", 1, 1)
+ {
+ this->SetDesc(_("Sync users channel modes"));
+ this->SetSyntax(_("\037channel\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (ci->c == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/administration");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
+
+ for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
+ ci->c->SetCorrectModes(it->second->user, true);
+
+ source.Reply(_("All user modes on \002{0}\002 have been synced."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &params) override
+ {
+ source.Reply(_("Syncs all channel status modes on all users on \037channel\037 with the modes they should have based on the channel access list.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "ACCESS_CHNAGE");
+ return true;
+ }
+};
+
+class CSSync : public Module
+{
+ CommandCSSync commandcssync;
+
+ public:
+ CSSync(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcssync(this)
+ {
+
+ }
+};
+
+MODULE_INIT(CSSync)
diff --git a/modules/chanserv/topic.cpp b/modules/chanserv/topic.cpp
new file mode 100644
index 000000000..fe9d2a80f
--- /dev/null
+++ b/modules/chanserv/topic.cpp
@@ -0,0 +1,289 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/chanserv/mode.h"
+#include "modules/chanserv/info.h"
+#include "modules/chanserv/set.h"
+
+class CommandCSSetKeepTopic : public Command
+{
+ public:
+ CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
+ {
+ this->SetDesc(_("Retain topic when channel is not in use"));
+ this->SetSyntax(_("\037channel\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &param = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (param.equals_ci("ON"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic";
+ ci->SetS<bool>("KEEPTOPIC", true);
+ source.Reply(_("Topic retention option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic";
+ ci->UnsetS<bool>("KEEPTOPIC");
+ source.Reply(_("Topic retention option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, "KEEPTOPIC");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables the \002topic retention\002 option for a \037channel\037."
+ " When \002topic retention\002 is set, the topic for the channel will be remembered by {0} even after the last user leaves the channel, and will be restored the next time the channel is created."),
+ source.service->nick);
+ return true;
+ }
+};
+
+class CommandCSTopic : public Command
+{
+ ExtensibleRef<bool> topiclock;
+
+ void Lock(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, "topiclock on");
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ topiclock->Set(ci, true);
+ source.Reply(_("Topic lock option for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+
+ void Unlock(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, "topiclock off");
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ topiclock->Unset(ci);
+ source.Reply(_("Topic lock option for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+
+ void Set(CommandSource &source, ChanServ::Channel *ci, const Anope::string &topic)
+ {
+ bool has_topiclock = topiclock->HasExt(ci);
+ topiclock->Unset(ci);
+ ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime);
+ if (has_topiclock)
+ topiclock->Set(ci, true);
+
+ bool override = !source.AccessFor(ci).HasPriv("TOPIC");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : "");
+ }
+
+ void Append(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &topic = params[2];
+
+ Anope::string new_topic;
+ if (!ci->c->topic.empty())
+ {
+ new_topic = ci->c->topic + " " + topic;
+ ci->SetLastTopic("");
+ }
+ else
+ new_topic = topic;
+
+ this->Set(source, ci, new_topic);
+ }
+
+ public:
+ CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3),
+ topiclock("TOPICLOCK")
+ {
+ this->SetDesc(_("Manipulate the topic of the specified channel"));
+ this->SetSyntax(_("\037channel\037 [SET] [\037topic\037]"));
+ this->SetSyntax(_("\037channel\037 APPEND \037topic\037"));
+ this->SetSyntax(_("\037channel\037 [UNLOCK|LOCK]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &channel = params[0];
+ const Anope::string &subcmd = params[1];
+
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ if (ci == NULL)
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
+ else if (!source.AccessFor(ci).HasPriv("TOPIC") && !source.HasCommand("chanserv/topic"))
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "TOPIC", ci->GetName());
+ else if (subcmd.equals_ci("LOCK"))
+ this->Lock(source, ci, params);
+ else if (subcmd.equals_ci("UNLOCK"))
+ this->Unlock(source, ci, params);
+ else if (!ci->c)
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
+ else if (subcmd.equals_ci("APPEND") && params.size() > 2)
+ this->Append(source, ci, params);
+ else
+ {
+ Anope::string topic;
+ if (subcmd.equals_ci("SET"))
+ {
+ topic = params.size() > 2 ? params[2] : "";
+ }
+ else
+ {
+ topic = subcmd;
+ if (params.size() > 2)
+ topic += " " + params[2];
+ }
+ this->Set(source, ci, topic);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows manipulating the topic of the specified channel."
+ " The \002SET\002 command changes the topic of the channel to the given topic or unsets the topic if no topic is given."
+ " The \002APPEND\002 command appends the given topic to the existing topic.\n"
+ "\n"
+ "\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock."
+ " When topic lock is set, the channel topic will be unchangeable by users who do not have the \002TOPIC\002 privilege.\n"
+ "\n"
+ "Use of this command requires the \002{0}\002 privilege on \037channel\037."),
+ "TOPIC");
+ return true;
+ }
+};
+
+class CSTopic : public Module
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::TopicUpdated>
+ , public EventHook<Event::ChanInfo>
+{
+ CommandCSTopic commandcstopic;
+ CommandCSSetKeepTopic commandcssetkeeptopic;
+
+ Serialize::Field<ChanServ::Channel, bool> topiclock, keeptopic;
+
+ ServiceReference<ModeLocks> mlocks;
+
+ public:
+ CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChannelSync>(this)
+ , EventHook<Event::TopicUpdated>(this)
+ , EventHook<Event::ChanInfo>(this)
+ , commandcstopic(this)
+ , commandcssetkeeptopic(this)
+ , topiclock(this, "TOPICLOCK")
+ , keeptopic(this, "KEEPTOPIC")
+ {
+
+ }
+
+ void OnChannelSync(Channel *c) override
+ {
+ if (c->ci)
+ {
+ /* Update channel topic */
+ if ((topiclock.HasExt(c->ci) || keeptopic.HasExt(c->ci)) && c->ci->GetLastTopic() != c->topic)
+ {
+ c->ChangeTopic(!c->ci->GetLastTopicSetter().empty() ? c->ci->GetLastTopicSetter() : c->ci->WhoSends()->nick, c->ci->GetLastTopic(), c->ci->GetLastTopicTime() ? c->ci->GetLastTopicTime() : Anope::CurTime);
+ }
+ }
+ }
+
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override
+ {
+ if (!c->ci)
+ return;
+
+ /* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
+ * allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
+ * This desyncs what is really set with what we have stored, and we end up resetting the topic often when
+ * it is not required
+ */
+ if (topiclock.HasExt(c->ci) && c->ci->GetLastTopic() != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC")))
+ {
+ c->ChangeTopic(c->ci->GetLastTopicSetter(), c->ci->GetLastTopic(), c->ci->GetLastTopicTime());
+ }
+ else
+ {
+ c->ci->SetLastTopic(c->topic);
+ c->ci->SetLastTopicSetter(c->topic_setter);
+ c->ci->SetLastTopicTime(c->topic_ts);
+ }
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override
+ {
+ if (keeptopic.HasExt(ci))
+ info.AddOption(_("Topic retention"));
+ if (topiclock.HasExt(ci))
+ info.AddOption(_("Topic lock"));
+
+ ModeLock *secret = mlocks ? mlocks->GetMLock(ci, "SECRET") : nullptr;
+ if (!ci->GetLastTopic().empty() && (show_all || ((!secret || secret->GetSet() == false) && (!ci->c || !ci->c->HasMode("SECRET")))))
+ {
+ info[_("Last topic")] = ci->GetLastTopic();
+ info[_("Topic set by")] = ci->GetLastTopicSetter();
+ }
+ }
+};
+
+MODULE_INIT(CSTopic)
diff --git a/modules/commands/cs_unban.cpp b/modules/chanserv/unban.cpp
index 64ecc7151..c4ee62e21 100644
--- a/modules/commands/cs_unban.cpp
+++ b/modules/chanserv/unban.cpp
@@ -1,12 +1,20 @@
-/* ChanServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandCSUnban : public Command
this->SetSyntax(_("\037channel\037 [\037nick\037]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
ChannelMode *cm = ModeManager::FindChannelModeByName("BAN");
if (!cm)
@@ -34,14 +42,10 @@ class CommandCSUnban : public Command
if (!source.GetUser())
return;
- std::deque<ChannelInfo *> queue;
- source.GetAccount()->GetChannelReferences(queue);
-
unsigned count = 0;
- for (unsigned i = 0; i < queue.size(); ++i)
- {
- ChannelInfo *ci = queue[i];
+ for (ChanServ::Channel *ci : source.GetAccount()->GetRefs<ChanServ::Channel *>())
+ {
if (!ci->c || !source.AccessFor(ci).HasPriv("UNBAN"))
continue;
@@ -56,22 +60,23 @@ class CommandCSUnban : public Command
return;
}
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
+ const Anope::string &chan = params[0];
+ ChanServ::Channel *ci = ChanServ::Find(chan);
if (ci == NULL)
{
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
return;
}
if (ci->c == NULL)
{
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
return;
}
if (!source.AccessFor(ci).HasPriv("UNBAN") && !source.HasPriv("chanserv/kick"))
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "UNBAN", ci->GetName());
return;
}
@@ -81,7 +86,8 @@ class CommandCSUnban : public Command
if (!u2)
{
- source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
+ if (params.size() > 1)
+ source.Reply(_("User \002{0}\002 isn't currently online."), params[1]);
return;
}
@@ -91,22 +97,18 @@ class CommandCSUnban : public Command
for (unsigned i = 0; i < modes.size(); ++i)
ci->c->Unban(u2, modes[i]->name, source.GetUser() == u2);
if (u2 == source.GetUser())
- source.Reply(_("You have been unbanned from \002%s\002."), ci->c->name.c_str());
+ source.Reply(_("You have been unbanned from \002{0}\002."), ci->c->name);
else
- source.Reply(_("\002%s\002 has been unbanned from \002%s\002."), u2->nick.c_str(), ci->c->name.c_str());
+ source.Reply(_("\002{0}\002 has been unbanned from \002{1}\002."), u2->nick, ci->c->name);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- 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. If no channel is\n"
- "given, all bans affecting you in channels you have access\n"
- "in are removed.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access and above\n"
- "on the channel."), source.service->nick.c_str());
+ source.Reply(_("Tells {0} to remove all bans preventing you or the given \037user\037 from entering \037channel\037."
+ " If no channel is given, all bans affecting you in channels you have access in are removed.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ source.service->nick, "UNBAN");
return true;
}
};
@@ -116,8 +118,8 @@ class CSUnban : public Module
CommandCSUnban commandcsunban;
public:
- CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsunban(this)
+ CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsunban(this)
{
}
diff --git a/modules/commands/cs_updown.cpp b/modules/chanserv/updown.cpp
index ab3ab60ce..baa540163 100644
--- a/modules/commands/cs_updown.cpp
+++ b/modules/chanserv/updown.cpp
@@ -1,12 +1,20 @@
-/* ChanServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -22,7 +30,7 @@ class CommandCSUp : public Command
bool giving = true;
/* whether or not we have given a mode */
bool given = false;
- AccessGroup u_access = c->ci->AccessFor(u);
+ ChanServ::AccessGroup u_access = c->ci->AccessFor(u);
for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
{
@@ -46,10 +54,10 @@ class CommandCSUp : public Command
CommandCSUp(Module *creator) : Command(creator, "chanserv/up", 0, 2)
{
this->SetDesc(_("Updates a selected nicks status on a channel"));
- this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
+ this->SetSyntax(_("[\037channel\037 [\037user\037]]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (params.empty())
{
@@ -64,42 +72,52 @@ class CommandCSUp : public Command
}
else
{
- const Anope::string &channel = params[0];
+ const Anope::string &chan = params[0];
const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
- Channel *c = Channel::Find(channel);
-
- if (c == NULL)
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
{
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
return;
}
- else if (!c->ci)
+
+ if (ci->c == NULL)
{
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
return;
}
User *u = User::Find(nick, true);
User *srcu = source.GetUser();
+ Channel *c = ci->c;
bool override = false;
if (u == NULL)
{
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
+ source.Reply(_("User \002{0}\002 isn't currently online."), nick);
return;
}
- else if (srcu && !srcu->FindChannel(c))
+
+ if (srcu && !srcu->FindChannel(c))
{
source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
return;
}
- else if (!u->FindChannel(c))
+
+ if (!u->FindChannel(c))
{
- source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
+ source.Reply(_("You must be on channel \002{0}\002 to use this command."), c->name);
return;
}
- else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
+
+ if (!u->FindChannel(c))
+ {
+ source.Reply(_("\002{0}\002 is not on channel \002{1}\002."), u->nick, c->name);
+ return;
+ }
+
+ if (source.GetUser() && u != source.GetUser() && c->ci->HasFieldS("PEACE"))
{
if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
{
@@ -107,7 +125,7 @@ class CommandCSUp : public Command
override = true;
else
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. \002{0}\002 has more privileges than you on \002{1}\002."), u->nick, ci->GetName());
return;
}
}
@@ -119,13 +137,11 @@ class CommandCSUp : public Command
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Updates a selected nicks status modes on a channel. If \037nick\037 is\n"
- "omitted then your status is updated. If \037channel\037 is omitted then\n"
- "your channel status is updated on every channel you are in."));
+ source.Reply(_("Updates the status modes of \037user\037 on \037channel\037."
+ " If \037user\037 is omitted then your status is updated."
+ " If \037channel\037 is omitted then your status is updated on every channel you are in."));
return true;
}
};
@@ -147,7 +163,7 @@ class CommandCSDown : public Command
this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (params.empty())
{
@@ -165,39 +181,50 @@ class CommandCSDown : public Command
const Anope::string &channel = params[0];
const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
- Channel *c = Channel::Find(channel);
-
- if (c == NULL)
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ if (ci == NULL)
{
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
return;
}
- else if (!c->ci)
+
+ if (ci->c == NULL)
{
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), ci->GetName());
return;
}
User *u = User::Find(nick, true);
+ Channel *c = ci->c;
+
User *srcu = source.GetUser();
bool override = false;
if (u == NULL)
{
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
+ source.Reply(_("User \002{0}\002 isn't currently online."), nick);
+ return;
+ }
+
+ if (srcu && !srcu->FindChannel(c))
+ {
+ source.Reply(_("You must be on channel \002{0}\002 to use this command."), c->name);
return;
}
- else if (srcu && !srcu->FindChannel(c))
+
+ if (srcu && !srcu->FindChannel(c))
{
source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
return;
}
- else if (!u->FindChannel(c))
+
+ if (!u->FindChannel(c))
{
- source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
+ source.Reply(_("\002%s\002 is not on channel %s."), u->nick, c->name);
return;
}
- else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
+
+ if (source.GetUser() && u != source.GetUser() && c->ci->HasFieldS("PEACE"))
{
if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
{
@@ -205,7 +232,7 @@ class CommandCSDown : public Command
override = true;
else
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. \002{0}\002 has more privileges than you on \002{1}\002."), u->nick, ci->GetName());
return;
}
}
@@ -216,13 +243,11 @@ class CommandCSDown : public Command
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Removes a selected nicks status modes on a channel. If \037nick\037 is\n"
- "omitted then your status is removed. If \037channel\037 is omitted then\n"
- "your channel status is removed on every channel you are in."));
+ source.Reply(_("Removes a selected nicks status modes on a channel."
+ " If \037nick\037 is ommited then your status is removed."
+ " If \037channel\037 is ommited then channel status is removed on every channel you are in."));
return true;
}
};
@@ -233,8 +258,9 @@ class CSUpDown : public Module
CommandCSDown commandcsdown;
public:
- CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsup(this), commandcsdown(this)
+ CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsup(this)
+ , commandcsdown(this)
{
}
diff --git a/modules/chanserv/xop.cpp b/modules/chanserv/xop.cpp
new file mode 100644
index 000000000..74feaca7e
--- /dev/null
+++ b/modules/chanserv/xop.cpp
@@ -0,0 +1,668 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/* Dependencies: anope_chanserv.main */
+
+#include "module.h"
+#include "modules/chanserv.h"
+#include "modules/chanserv/access.h"
+#include "modules/chanserv/main/chanaccess.h"
+#include "main/chanaccesstype.h"
+
+namespace
+{
+ std::vector<Anope::string> order;
+ std::map<Anope::string, std::vector<Anope::string> > permissions;
+}
+
+class XOPChanAccessImpl : public XOPChanAccess
+{
+ friend class XOPChanAccessType;
+
+ Anope::string type;
+
+ public:
+ using XOPChanAccess::XOPChanAccess;
+
+ const Anope::string &GetType() override;
+ void SetType(const Anope::string &) override;
+
+ bool HasPriv(const Anope::string &priv) override
+ {
+ for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->GetType()); it != order.end(); ++it)
+ {
+ const std::vector<Anope::string> &privs = permissions[*it];
+ if (std::find(privs.begin(), privs.end(), priv) != privs.end())
+ return true;
+ }
+ return false;
+ }
+
+ Anope::string AccessSerialize() override
+ {
+ return this->GetType();
+ }
+
+ void AccessUnserialize(const Anope::string &data) override
+ {
+ this->SetType(data);
+ }
+
+ static Anope::string DetermineLevel(ChanServ::ChanAccess *access)
+ {
+ if (access->GetSerializableType()->GetName() == NAME)
+ {
+ XOPChanAccess *xaccess = anope_dynamic_static_cast<XOPChanAccess *>(access);
+ return xaccess->GetType();
+ }
+
+ std::map<Anope::string, int> count;
+
+ for (std::map<Anope::string, std::vector<Anope::string> >::const_iterator it = permissions.begin(), it_end = permissions.end(); it != it_end; ++it)
+ {
+ int &c = count[it->first];
+ const std::vector<Anope::string> &perms = it->second;
+ for (unsigned i = 0; i < perms.size(); ++i)
+ if (access->HasPriv(perms[i]))
+ ++c;
+ }
+
+ Anope::string max;
+ int maxn = 0;
+ for (std::map<Anope::string, int>::iterator it = count.begin(), it_end = count.end(); it != it_end; ++it)
+ if (it->second > maxn)
+ {
+ maxn = it->second;
+ max = it->first;
+ }
+
+ return max;
+ }
+
+};
+
+class XOPChanAccessType : public ChanAccessType<XOPChanAccessImpl>
+{
+ public:
+ Serialize::Field<XOPChanAccessImpl, Anope::string> type;
+
+ XOPChanAccessType(Module *me) : ChanAccessType<XOPChanAccessImpl>(me)
+ , type(this, "type", &XOPChanAccessImpl::type)
+ {
+ Serialize::SetParent(XOPChanAccess::NAME, ChanServ::ChanAccess::NAME);
+ }
+};
+
+const Anope::string &XOPChanAccessImpl::GetType()
+{
+ return Get(&XOPChanAccessType::type);
+}
+
+void XOPChanAccessImpl::SetType(const Anope::string &i)
+{
+ Object::Set(&XOPChanAccessType::type, i);
+}
+
+class CommandCSXOP : public Command
+{
+ private:
+ void DoAdd(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ Anope::string mask = params.size() > 2 ? params[2] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ ChanServ::ChanAccess *highest = access.Highest();
+ bool override = false;
+
+ std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
+ access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccessImpl::DetermineLevel(highest)) : order.end();
+
+ if (!access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ override = true;
+ else
+ {
+ source.Reply(_("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002."), "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+ }
+
+ NickServ::Nick *na = nullptr;
+ ChanServ::Channel *targ_ci = nullptr;
+
+ if (IRCD->IsChannelValid(mask))
+ {
+ if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
+ {
+ source.Reply(_("Channels may not be on access lists."));
+ return;
+ }
+
+ targ_ci = ChanServ::Find(mask);
+ if (targ_ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), mask);
+ return;
+ }
+
+ if (ci == targ_ci)
+ {
+ source.Reply(_("You can't add a channel to its own access list."));
+ return;
+ }
+
+ mask = targ_ci->GetName();
+ }
+ else
+ {
+ na = NickServ::FindNick(mask);
+
+ if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
+ {
+ source.Reply(_("Masks and unregistered users may not be on access lists."));
+ return;
+ }
+
+ if (mask.find_first_of("!*@") == Anope::string::npos && !na)
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
+ return;
+ }
+ }
+
+ if (na)
+ mask = na->GetNick();
+ }
+
+ for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ ChanServ::ChanAccess *a = ci->GetAccess(i);
+
+ if ((na && na->GetAccount() == a->GetAccount()) || mask.equals_ci(a->Mask()))
+ {
+ if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->GetName(), a->Mask());
+ return;
+ }
+
+ a->Delete();
+ break;
+ }
+ }
+
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
+ {
+ source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
+ return;
+ }
+
+ XOPChanAccess *acc = Serialize::New<XOPChanAccess *>();
+ if (na)
+ acc->SetObj(na->GetAccount());
+ else if (targ_ci)
+ acc->SetObj(targ_ci);
+ acc->SetChannel(ci);
+ acc->SetMask(mask);
+ acc->SetCreator(source.GetNick());
+ acc->SetType(source.command.upper());
+ acc->SetLastSeen(0);
+ acc->SetCreated(Anope::CurTime);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
+
+ EventManager::Get()->Dispatch(&Event::AccessAdd::OnAccessAdd, ci, source, acc);
+ source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask(), ci->GetName().c_str(), source.command.c_str());
+ }
+
+ void DoDel(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+ NickServ::Account *nc = source.nc;
+ Anope::string mask = params.size() > 2 ? params[2] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
+ return;
+ }
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("%s %s list is empty."), ci->GetName().c_str(), source.command.c_str());
+ return;
+ }
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+ ChanServ::ChanAccess *highest = access.Highest();
+ bool override = false;
+
+ if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickServ::FindNick(mask))
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
+ return;
+ }
+ }
+
+ std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
+ access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccessImpl::DetermineLevel(highest)) : order.end();
+
+ if (!mask.equals_ci(nc->GetDisplay()) && !access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
+ {
+ if (source.HasPriv("chanserv/access/modify"))
+ override = true;
+ else
+ {
+ source.Reply(_("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002."), "ACCESS_CHANGE", ci->GetName());
+ return;
+ }
+ }
+
+ /* Special case: is it a number/list? Only do search if it isn't. */
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ unsigned int deleted = 0;
+ Anope::string nicks;
+
+ NumberList(mask, true,
+ [&](unsigned int number)
+ {
+ if (!number || number > ci->GetAccessCount())
+ return;
+
+ ChanServ::ChanAccess *caccess = ci->GetAccess(number - 1);
+
+ if (caccess->GetSerializableType()->GetName() != "XOPChanAccess" || source.command.upper() != caccess->AccessSerialize())
+ return;
+
+ ++deleted;
+ if (!nicks.empty())
+ nicks += ", " + caccess->Mask();
+ else
+ nicks = caccess->Mask();
+
+ EventManager::Get()->Dispatch(&Event::AccessDel::OnAccessDel, ci, source, caccess);
+ delete caccess;
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("No matching entries on %s %s list."), ci->GetName().c_str(), source.command.c_str());
+ else
+ {
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << nicks;
+
+ if (deleted == 1)
+ source.Reply(_("Deleted one entry from %s %s list."), ci->GetName().c_str(), source.command.c_str());
+ else
+ source.Reply(_("Deleted %d entries from %s %s list."), deleted, ci->GetName().c_str(), source.command.c_str());
+ }
+ });
+ }
+ else
+ {
+ for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ ChanServ::ChanAccess *a = ci->GetAccess(i);
+
+ if (a->GetSerializableType()->GetName() != "XOPChanAccess" || source.command.upper() != a->AccessSerialize())
+ continue;
+
+ if (a->Mask().equals_ci(mask))
+ {
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask();
+
+ source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->GetName().c_str(), source.command.c_str());
+
+ EventManager::Get()->Dispatch(&Event::AccessDel::OnAccessDel, ci, source, a);
+ delete a;
+
+ return;
+ }
+ }
+
+ source.Reply(_("\002%s\002 not found on %s %s list."), mask.c_str(), ci->GetName().c_str(), source.command.c_str());
+ }
+ }
+
+ void DoList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> &params)
+ {
+
+ const Anope::string &nick = params.size() > 2 ? params[2] : "";
+
+ ChanServ::AccessGroup access = source.AccessFor(ci);
+
+ if (!access.HasPriv("ACCESS_LIST") && !source.HasPriv("chanserv/access/list"))
+ {
+ source.Reply(_("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002."), "ACCESS_LIST", ci->GetName());
+ return;
+ }
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("%s %s list is empty."), ci->GetName().c_str(), source.command.c_str());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask"));
+
+ if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(nick, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > ci->GetAccessCount())
+ return;
+
+ ChanServ::ChanAccess *a = ci->GetAccess(number - 1);
+
+ if (a->GetSerializableType()->GetName() != "XOPChanAccess" || source.command.upper() != a->AccessSerialize())
+ return;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ entry["Mask"] = a->Mask();
+ list.AddEntry(entry);
+ },
+ []{});
+ }
+ else
+ {
+ for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
+ {
+ ChanServ::ChanAccess *a = ci->GetAccess(i);
+
+ if (a->GetSerializableType()->GetName() != "XOPChanAccess" || source.command.upper() != a->AccessSerialize())
+ continue;
+ if (!nick.empty() && !Anope::Match(a->Mask(), nick))
+ continue;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Mask"] = a->Mask();
+ list.AddEntry(entry);
+ }
+ }
+
+ if (list.IsEmpty())
+ source.Reply(_("No matching entries on %s access list."), ci->GetName().c_str());
+ else
+ {
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("%s list for %s"), source.command.c_str(), ci->GetName().c_str());
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ }
+
+ void DoClear(CommandSource &source, ChanServ::Channel *ci)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
+ return;
+ }
+
+ if (!ci->GetAccessCount())
+ {
+ source.Reply(_("%s %s list is empty."), ci->GetName().c_str(), source.command.c_str());
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify"))
+ {
+ source.Reply(_("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002."), "FOUNDER", ci->GetName());
+ return;
+ }
+
+ bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
+
+ for (unsigned i = ci->GetAccessCount(); i > 0; --i)
+ {
+ ChanServ::ChanAccess *access = ci->GetAccess(i - 1);
+
+ if (access->GetSerializableType()->GetName() != "XOPChanAccess" || source.command.upper() != access->AccessSerialize())
+ continue;
+
+ delete access;
+ }
+
+ EventManager::Get()->Dispatch(&Event::AccessClear::OnAccessClear, ci, source);
+
+ source.Reply(_("Channel %s %s list has been cleared."), ci->GetName().c_str(), source.command.c_str());
+ }
+
+ public:
+ CommandCSXOP(Module *modname) : Command(modname, "chanserv/xop", 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"));
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Modify the list of %s users")), source.command.upper().c_str());
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+
+ const Anope::string &cmd = params[1];
+
+ if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, ci, params);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, ci, params);
+ else if (cmd.equals_ci("LIST"))
+ return this->DoList(source, ci, params);
+ else if (cmd.equals_ci("CLEAR"))
+ return this->DoClear(source, ci);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("The \002{0} ADD\002 command adds \037mask\037 to the {0} list of \037channel\037."
+ " If you have the privilege to use this command, you may use it if you have more privileges than it grants."),
+ source.command);
+
+ source.Reply(_("Use of this command requires the \002{0}\002 privilege on \037channel\037.\n"
+ "Example:\n"
+ " {1} #anope ADD Adam"
+ " Adds \"Adam\" to the access list of \"#anope\" with the privilege set {1}"),
+ "ACCESS_CHANGE", source.command);
+ }
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes the given \037mask\037 from the {0} list of \037channel\037."
+ " If a list of entry numbers is given, those entries are deleted.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037.\n"
+ "Example:\n"
+ " {0} #anope DEL Cronus"
+ " Removes \"Cronus\" from the {0} list of \"#anope\""),
+ source.command, "ACCESS_CHANGE");
+ else if (subcommand.equals_ci("LIST"))
+ source.Reply(_("The \002{0} LIST\002 command displays the {0} list of \037channel\037."
+ " If a wildcard mask is given, only those entries matching the mask are displayed."
+ " If a list of entry numbers is given, only those entries are shown.\n"
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037.\n"
+ "\n"
+ "Example:"
+ " {0} #anope LIST 2-5,7-9\n"
+ " List entries numbered 2 through 5 and 7 through 9 on the {0} of \"#anope\""),
+ source.command, "ACCESS_LIST");
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("The \002{0} CLEAR\002 command clears the {0} list of \037channel\037."
+ "\n"
+ "Use of this command requires the \002{1}\002 privilege on \037channel\037."),
+ source.command, "FOUNDER");
+
+ else
+ {
+ source.Reply(_("Maintains the \002{0} list\002 for a channel."
+ " Users who match an access entry on the {0} list receive the following privileges:\n"
+ "\n"),
+ source.command);
+
+ Anope::string buf;
+ for (unsigned i = 0; i < permissions[source.command].size(); ++i)
+ buf += "," + permissions[source.command][i];
+
+ source.Reply(buf);
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ {
+ source.Reply(_("\n"
+ "The \002ADD\002 command adds \037mask\037 to the {0} list.\n"
+ "Use of this command requires the \002{change}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the {0} list.\n"
+ "Use of this command requires the \002{change}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 command shows the {0} list for \037channel\037.\n"
+ "Use of this commands requires the \002{list}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} LIST\002 for more information.\n"
+ "\n"
+ "The \002CLEAR\002 command clears the {0} list."
+ "Use of this command requires the \002{founder}\002 privilege on \037channel\037.\n"
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information.)"),
+ source.command, "change"_kw = "ACCESS_CHANGE", "list"_kw = "ACCESS_LIST", "help"_kw = help->cname);
+
+ Anope::string access_cmd, flags_cmd;
+ ServiceBot *access_bi, *flags_bi;
+ Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
+ Command::FindCommandFromService("chanserv/flags", flags_bi, access_cmd);
+ if (!access_cmd.empty() || !flags_cmd.empty())
+ {
+ source.Reply(_("\n"
+ "Alternative methods of modifying channel access lists are available:\n"));
+ if (!access_cmd.empty())
+ source.Reply(_("See \002{0}{1} {2} {3}\002 for more information about the access list."), Config->StrictPrivmsg, access_bi->nick, help->cname, access_cmd);
+ if (!flags_cmd.empty())
+ source.Reply(_("See \002{0}{1} {2} {3}\002 for more information about the flags system."), Config->StrictPrivmsg, flags_bi->nick, help->cname, flags_cmd);
+ }
+ }
+ }
+ return true;
+ }
+};
+
+class CSXOP : public Module
+{
+ CommandCSXOP commandcsxop;
+ XOPChanAccessType xopaccesstype;
+
+ public:
+ CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandcsxop(this)
+ , xopaccesstype(this)
+ {
+ this->SetPermanent(true);
+
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ order.clear();
+ permissions.clear();
+
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
+ {
+ Configuration::Block *block = conf->GetBlock("privilege", i);
+ const Anope::string &pname = block->Get<Anope::string>("name");
+
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(pname) : nullptr;
+ if (p == NULL)
+ continue;
+
+ const Anope::string &xop = block->Get<Anope::string>("xop");
+ if (pname.empty() || xop.empty())
+ continue;
+
+ permissions[xop].push_back(pname);
+ }
+
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
+ {
+ Configuration::Block *block = conf->GetBlock("command", i);
+ const Anope::string &cname = block->Get<Anope::string>("name"),
+ &cserv = block->Get<Anope::string>("command");
+ if (cname.empty() || cserv != "chanserv/xop")
+ continue;
+
+ order.push_back(cname);
+ }
+ }
+};
+
+template<> void ModuleInfo<CSXOP>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
+MODULE_INIT(CSXOP)
diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp
deleted file mode 100644
index 0d1989fe9..000000000
--- a/modules/commands/bs_assign.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 : 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<Anope::string> &params) anope_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) anope_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 : 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<Anope::string> &params) anope_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) anope_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 : 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<Anope::string> &params) anope_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<bool>("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<bool>("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 &) anope_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 : public Module
-{
- ExtensibleItem<bool> 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) anope_override
- {
- BotInfo *bi;
- if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = dynamic_cast<BotInfo *>(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) anope_override
- {
- if (nobot.HasExt(ci))
- info.AddOption(_("No bot"));
- }
-};
-
-MODULE_INIT(BSAssign)
diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp
deleted file mode 100644
index 57731b168..000000000
--- a/modules/commands/bs_badwords.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 : BadWord, Serializable
-{
- BadWordImpl() : Serializable("BadWord") { }
- ~BadWordImpl();
-
- void Serialize(Serialize::Data &data) const anope_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 : BadWords
-{
- Serialize::Reference<ChannelInfo> ci;
- typedef std::vector<BadWordImpl *> list;
- Serialize::Checker<list> badwords;
-
- BadWordsImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), badwords("BadWord") { }
-
- ~BadWordsImpl();
-
- BadWord* AddBadWord(const Anope::string &word, BadWordType type) anope_override
- {
- BadWordImpl *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 anope_override
- {
- if (this->badwords->empty() || index >= this->badwords->size())
- return NULL;
-
- BadWordImpl *bw = (*this->badwords)[index];
- bw->QueueUpdate();
- return bw;
- }
-
- unsigned GetBadWordCount() const anope_override
- {
- return this->badwords->size();
- }
-
- void EraseBadWord(unsigned index) anope_override
- {
- if (this->badwords->empty() || index >= this->badwords->size())
- return;
-
- FOREACH_MOD(OnBadWordDel, (ci, (*this->badwords)[index]));
-
- delete this->badwords->at(index);
- }
-
- void ClearBadWords() anope_override
- {
- while (!this->badwords->empty())
- delete this->badwords->back();
- }
-
- void Check() anope_override
- {
- if (this->badwords->empty())
- ci->Shrink<BadWords>("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<BadWordsImpl>("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<BadWordImpl *>(obj);
- else
- bw = new BadWordImpl();
- bw->chan = sci;
- bw->word = sword;
- bw->type = static_cast<BadWordType>(n);
-
- BadWordsImpl *bws = ci->Require<BadWordsImpl>("badwords");
- if (!obj)
- bws->badwords->push_back(bw);
-
- return bw;
-}
-
-class BadwordsDelCallback : public NumberList
-{
- CommandSource &source;
- ChannelInfo *ci;
- BadWords *bw;
- Command *c;
- unsigned deleted;
- bool override;
- public:
- 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 (!source.AccessFor(ci).HasPriv("BADWORDS") && source.HasPriv("botserv/administration"))
- this->override = true;
- bw = ci->Require<BadWords>("badwords");
- }
-
- ~BadwordsDelCallback()
- {
- 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) anope_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 : 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>("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 : 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) anope_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<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Bad words list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- 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>("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<unsigned>("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<bool>("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>("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>("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<Anope::string> &params) anope_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") && (!need_args || !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) anope_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 : public Module
-{
- CommandBSBadwords commandbsbadwords;
- ExtensibleItem<BadWordsImpl> 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/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp
deleted file mode 100644
index 6a152937a..000000000
--- a/modules/commands/bs_bot.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- 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<unsigned>("nicklen"))
- {
- source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
- return;
- }
-
- if (user.length() > networkinfo->Get<unsigned>("userlen"))
- {
- source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
- return;
- }
-
- if (host.length() > networkinfo->Get<unsigned>("hostlen"))
- {
- source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("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;
- }
-
- BotInfo *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<Anope::string> &params)
- {
- 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<unsigned>("nicklen"))
- {
- source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
- return;
- }
-
- if (user.length() > networkinfo->Get<unsigned>("userlen"))
- {
- source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
- return;
- }
-
- if (host.length() > networkinfo->Get<unsigned>("hostlen"))
- {
- source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("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<Anope::string> &params)
- {
- 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<Anope::string> &params) anope_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<Anope::string> 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) anope_override
- {
- 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"
- "\002BOT ADD\002 adds a bot with the given nickname, username,\n"
- "hostname and realname. Since no integrity checks are done\n"
- "for these settings, be really careful.\n"
- " \n"
- "\002BOT CHANGE\002 allows you to change the nickname, username, hostname\n"
- "or realname of a bot without deleting it (and\n"
- "all the data associated with it).\n"
- " \n"
- "\002BOT DEL\002 removes the given bot from the bot list.\n"
- " \n"
- "\002Note\002: You cannot create a bot with a nick that is\n"
- "currently registered. If an unregistered user is currently\n"
- "using the nick, they will be killed."));
- return true;
- }
-};
-
-class BSBot : public Module
-{
- CommandBSBot commandbsbot;
-
- public:
- BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsbot(this)
- {
-
- }
-};
-
-MODULE_INIT(BSBot)
diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp
deleted file mode 100644
index 089c2894d..000000000
--- a/modules/commands/bs_botlist.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 CommandBSBotList : public Command
-{
- public:
- CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
- {
- this->SetDesc(_("Lists available bots"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned count = 0;
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Nick")).AddColumn(_("Mask"));
-
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- {
- BotInfo *bi = it->second;
-
- if (source.HasPriv("botserv/administration") || !bi->oper_only)
- {
- ++count;
- ListFormatter::ListEntry entry;
- entry["Nick"] = (bi->oper_only ? "* " : "") + bi->nick;
- entry["Mask"] = bi->GetIdent() + "@" + bi->host;
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- if (!count)
- source.Reply(_("There are no bots available at this time.\n"
- "Ask a Services Operator to create one!"));
- else
- {
- source.Reply(_("Bot list:"));
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("%d bots available."), count);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all available bots on this network.\n"
- "Bots prefixed by a * are reserved for IRC Operators."));
- return true;
- }
-};
-
-class BSBotList : public Module
-{
- CommandBSBotList commandbsbotlist;
-
- public:
- BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsbotlist(this)
- {
-
- }
-};
-
-MODULE_INIT(BSBotList)
diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp
deleted file mode 100644
index bdacf8dd1..000000000
--- a/modules/commands/bs_control.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 specified text on the specified channel"));
- this->SetSyntax(_("\037channel\037 \037text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &text = params[1];
-
- 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("SAY") && !source.HasPriv("botserv/administration"))
- {
- 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;
- }
-
- IRCD->SendPrivmsg(*ci->bi, ci->name, "%s", text.c_str());
- ci->bi->lastmsg = Anope::CurTime;
-
- bool override = !source.AccessFor(ci).HasPriv("SAY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << text;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the bot say the specified text on the specified 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) anope_override
- {
- Anope::string message = params[1];
-
- 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("SAY") && !source.HasPriv("botserv/administration"))
- {
- 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;
- }
-
- message = message.replace_all_cs("\1", "");
- if (message.empty())
- return;
-
- IRCD->SendAction(*ci->bi, ci->name, "%s", message.c_str());
- ci->bi->lastmsg = Anope::CurTime;
-
- bool override = !source.AccessFor(ci).HasPriv("SAY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << message;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n"
- "on the specified channel using the specified text."));
- return true;
- }
-};
-
-class BSControl : public Module
-{
- CommandBSSay commandbssay;
- CommandBSAct commandbsact;
-
- public:
- BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbssay(this), commandbsact(this)
- {
-
- }
-};
-
-MODULE_INIT(BSControl)
diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp
deleted file mode 100644
index 76dcfa4f4..000000000
--- a/modules/commands/bs_info.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 CommandBSInfo : public Command
-{
- private:
- void send_bot_channels(std::vector<Anope::string> &buffers, const BotInfo *bi)
- {
- Anope::string buf;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == bi)
- {
- buf += " " + ci->name + " ";
- if (buf.length() > 300)
- {
- buffers.push_back(buf);
- buf.clear();
- }
- }
- }
- if (!buf.empty())
- buffers.push_back(buf);
- }
-
- public:
- CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
- {
- this->SetSyntax(_("{\037channel\037 | \037nickname\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &query = params[0];
-
- BotInfo *bi = BotInfo::Find(query, true);
- ChannelInfo *ci = ChannelInfo::Find(query);
- InfoFormatter info(source.nc);
-
- if (bi)
- {
- source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
- info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
- info[_("Real name")] = bi->realname;
- info[_("Created")] = Anope::strftime(bi->created, source.GetAccount());
- info[_("Options")] = bi->oper_only ? _("Private") : _("None");
- info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
-
- FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- if (source.HasPriv("botserv/administration"))
- {
- std::vector<Anope::string> buf;
- this->send_bot_channels(buf, bi);
- for (unsigned i = 0; i < buf.size(); ++i)
- source.Reply(buf[i]);
- }
-
- }
- else if (ci)
- {
- if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
- info[_("Bot nick")] = ci->bi ? ci->bi->nick : _("not assigned yet");
-
- Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
- Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
-
- FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- else
- source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str());
- }
-};
-
-class BSInfo : public Module
-{
- CommandBSInfo commandbsinfo;
-
- public:
- BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(BSInfo)
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
deleted file mode 100644
index 1897bc5e6..000000000
--- a/modules/commands/bs_kick.cpp
+++ /dev/null
@@ -1,1474 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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_kick.h"
-#include "modules/bs_badwords.h"
-
-static Module *me;
-
-struct KickerDataImpl : KickerData
-{
- KickerDataImpl(Extensible *obj)
- {
- amsgs = badwords = bolds = caps = colors = flood = italics = repeat = reverses = underlines = false;
- for (int16_t i = 0; i < TTB_SIZE; ++i)
- ttb[i] = 0;
- capsmin = capspercent = 0;
- floodlines = floodsecs = 0;
- repeattimes = 0;
-
- dontkickops = dontkickvoices = false;
- }
-
- void Check(ChannelInfo *ci) anope_override
- {
- if (amsgs || badwords || bolds || caps || colors || flood || italics || repeat || reverses || underlines)
- return;
-
- ci->Shrink<KickerData>("kickerdata");
- }
-
- struct ExtensibleItem : ::ExtensibleItem<KickerDataImpl>
- {
- ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem<KickerDataImpl>(m, ename) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(e);
- KickerData *kd = this->Get(ci);
- if (kd == NULL)
- return;
-
- data["kickerdata:amsgs"] << kd->amsgs;
- data["kickerdata:badwords"] << kd->badwords;
- data["kickerdata:bolds"] << kd->bolds;
- data["kickerdata:caps"] << kd->caps;
- data["kickerdata:colors"] << kd->colors;
- data["kickerdata:flood"] << kd->flood;
- data["kickerdata:italics"] << kd->italics;
- data["kickerdata:repeat"] << kd->repeat;
- data["kickerdata:reverses"] << kd->reverses;
- data["kickerdata:underlines"] << kd->underlines;
-
- data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin;
- data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent;
- data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines;
- data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << kd->floodsecs;
- data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << kd->repeattimes;
- for (int16_t i = 0; i < TTB_SIZE; ++i)
- data["ttb"] << kd->ttb[i] << " ";
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(e);
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- data["kickerdata:amsgs"] >> kd->amsgs;
- data["kickerdata:badwords"] >> kd->badwords;
- data["kickerdata:bolds"] >> kd->bolds;
- data["kickerdata:caps"] >> kd->caps;
- data["kickerdata:colors"] >> kd->colors;
- data["kickerdata:flood"] >> kd->flood;
- data["kickerdata:italics"] >> kd->italics;
- data["kickerdata:repeat"] >> kd->repeat;
- data["kickerdata:reverses"] >> kd->reverses;
- data["kickerdata:underlines"] >> kd->underlines;
-
- data["capsmin"] >> kd->capsmin;
- data["capspercent"] >> kd->capspercent;
- data["floodlines"] >> kd->floodlines;
- data["floodsecs"] >> kd->floodsecs;
- data["repeattimes"] >> kd->repeattimes;
-
- Anope::string ttb, tok;
- data["ttb"] >> ttb;
- spacesepstream sep(ttb);
- for (int i = 0; sep.GetToken(tok) && i < TTB_SIZE; ++i)
- try
- {
- kd->ttb[i] = convertTo<int16_t>(tok);
- }
- catch (const ConvertException &) { }
-
- kd->Check(ci);
- }
- };
-};
-
-class CommandBSKick : public Command
-{
- public:
- CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 0)
- {
- this->SetDesc(_("Configures kickers"));
- this->SetSyntax(_("\037option\037 \037channel\037 {\037ON|OFF\037} [\037settings\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Configures bot kickers. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> command("Command", info.name);
- if (command)
- {
- source.command = c_name;
- command->OnServHelp(source);
- }
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option.\n"
- " \n"
- "Note: access to this command is controlled by the\n"
- "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
-
- return true;
- }
-};
-
-class CommandBSKickBase : public Command
-{
- public:
- CommandBSKickBase(Module *creator, const Anope::string &cname, int minarg, int maxarg) : Command(creator, cname, minarg, maxarg)
- {
- }
-
- virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override = 0;
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override = 0;
-
- protected:
- bool CheckArguments(CommandSource &source, const std::vector<Anope::string> &params, ChannelInfo* &ci)
- {
- const Anope::string &chan = params[0];
- const Anope::string &option = params[1];
-
- ci = ChannelInfo::Find(chan);
-
- if (Anope::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 (option.empty())
- this->OnSyntaxError(source, "");
- else if (!option.equals_ci("ON") && !option.equals_ci("OFF"))
- this->OnSyntaxError(source, "");
- else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("botserv/administration"))
- source.Reply(ACCESS_DENIED);
- else if (!ci->bi)
- source.Reply(BOT_NOT_ASSIGNED);
- else
- return true;
-
- return false;
- }
-
- void Process(CommandSource &source, ChannelInfo *ci, const Anope::string &param, const Anope::string &ttb, size_t ttb_idx, const Anope::string &optname, KickerData *kd, bool &val)
- {
- if (param.equals_ci("ON"))
- {
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[ttb_idx] = i;
- }
- else
- kd->ttb[ttb_idx] = 0;
-
- val = true;
- if (kd->ttb[ttb_idx])
- source.Reply(_("Bot will now kick for \002%s\002, and will place a ban\n"
- "after %d kicks for the same user."), optname.c_str(), kd->ttb[ttb_idx]);
- else
- source.Reply(_("Bot will now kick for \002%s\002."), optname.c_str());
-
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable the " << optname << " kicker";
- }
- else if (param.equals_ci("OFF"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable the " << optname << " kicker";
-
- val = false;
- source.Reply(_("Bot won't kick for \002%s\002 anymore."), optname.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-};
-
-class CommandBSKickAMSG : public CommandBSKickBase
-{
- public:
- CommandBSKickAMSG(Module *creator) : CommandBSKickBase(creator, "botserv/kick/amsg", 2, 3)
- {
- this->SetDesc(_("Configures AMSG kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_AMSGS, "AMSG", kd, kd->amsgs);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- BotInfo *bi = Config->GetClient("BotServ");
- source.Reply(_("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 %s bots are.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before they get banned. Don't give ttb to disable\n"
- "the ban system once activated."), bi ? bi->nick.c_str() : "BotServ");
- return true;
- }
-};
-
-class CommandBSKickBadwords : public CommandBSKickBase
-{
- public:
- CommandBSKickBadwords(Module *creator) : CommandBSKickBase(creator, "botserv/kick/badwords", 2, 3)
- {
- this->SetDesc(_("Configures badwords kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BADWORDS, "badwords", kd, kd->badwords);
- kd->Check(ci);
- }
-
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the bad words kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who say certain words\n"
- "on the channels.\n"
- "You can define bad words for your channel using the\n"
- "\002BADWORDS\002 command. Type \002%s%s HELP BADWORDS\002 for\n"
- "more information.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandBSKickBolds : public CommandBSKickBase
-{
- public:
- CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3)
- {
- this->SetDesc(_("Configures bolds kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BOLDS, "bolds", kd, kd->bolds);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the bolds kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use bolds.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickCaps : public CommandBSKickBase
-{
- public:
- CommandBSKickCaps(Module *creator) : CommandBSKickBase(creator, "botserv/kick/caps", 2, 5)
- {
- this->SetDesc(_("Configures caps kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &min = params.size() > 3 ? params[3] : "",
- &percent = params.size() > 4 ? params[4] : "";
-
- if (!ttb.empty())
- {
- try
- {
- kd->ttb[TTB_CAPS] = convertTo<int16_t>(ttb);
- if (kd->ttb[TTB_CAPS] < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- kd->ttb[TTB_CAPS] = 0;
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
- }
- else
- kd->ttb[TTB_CAPS] = 0;
-
- kd->capsmin = 10;
- try
- {
- kd->capsmin = convertTo<int16_t>(min);
- }
- catch (const ConvertException &) { }
- if (kd->capsmin < 1)
- kd->capsmin = 10;
-
- kd->capspercent = 25;
- try
- {
- kd->capspercent = convertTo<int16_t>(percent);
- }
- catch (const ConvertException &) { }
- if (kd->capspercent < 1 || kd->capspercent > 100)
- kd->capspercent = 25;
-
- kd->caps = true;
- if (kd->ttb[TTB_CAPS])
- source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n"
- "%d characters and %d%% of the entire message), and will\n"
- "place a ban after %d kicks for the same user."), kd->capsmin, kd->capspercent, kd->ttb[TTB_CAPS]);
- else
- source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n"
- "%d characters and %d%% of the entire message)."), kd->capsmin, kd->capspercent);
- }
- else
- {
- kd->caps = false;
- source.Reply(_("Bot won't kick for \002caps\002 anymore."));
- }
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the caps kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are talking in\n"
- "CAPS.\n"
- "The bot kicks only if there are at least \002min\002 caps\n"
- "and they constitute at least \002percent\002%% of the total\n"
- "text line (if not given, it defaults to 10 characters\n"
- "and 25%%).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickColors : public CommandBSKickBase
-{
- public:
- CommandBSKickColors(Module *creator) : CommandBSKickBase(creator, "botserv/kick/colors", 2, 3)
- {
- this->SetDesc(_("Configures color kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_COLORS, "colors", kd, kd->colors);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the colors kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use colors.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickFlood : public CommandBSKickBase
-{
- public:
- CommandBSKickFlood(Module *creator) : CommandBSKickBase(creator, "botserv/kick/flood", 2, 5)
- {
- this->SetDesc(_("Configures flood kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &lines = params.size() > 3 ? params[3] : "",
- &secs = params.size() > 4 ? params[4] : "";
-
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[TTB_FLOOD] = i;
- }
- else
- kd->ttb[TTB_FLOOD] = 0;
-
- kd->floodlines = 6;
- try
- {
- kd->floodlines = convertTo<int16_t>(lines);
- }
- catch (const ConvertException &) { }
- if (kd->floodlines < 2)
- kd->floodlines = 6;
-
- kd->floodsecs = 10;
- try
- {
- kd->floodsecs = convertTo<int16_t>(secs);
- }
- catch (const ConvertException &) { }
- if (kd->floodsecs < 1)
- kd->floodsecs = 10;
- if (kd->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata"))
- kd->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata");
-
- kd->flood = true;
- if (kd->ttb[TTB_FLOOD])
- source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds\n"
- "and will place a ban after %d kicks for the same user."), kd->floodlines, kd->floodsecs, kd->ttb[TTB_FLOOD]);
- else
- source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds)."), kd->floodlines, kd->floodsecs);
- }
- else if (params[1].equals_ci("OFF"))
- {
- kd->flood = false;
- source.Reply(_("Bot won't kick for \002flood\002 anymore."));
- }
- else
- this->OnSyntaxError(source, params[1]);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the flood kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are flooding\n"
- "the channel using at least \002ln\002 lines in \002secs\002 seconds\n"
- "(if not given, it defaults to 6 lines in 10 seconds).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickItalics : public CommandBSKickBase
-{
- public:
- CommandBSKickItalics(Module *creator) : CommandBSKickBase(creator, "botserv/kick/italics", 2, 3)
- {
- this->SetDesc(_("Configures italics kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_ITALICS, "italics", kd, kd->italics);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the italics kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use italics.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickRepeat : public CommandBSKickBase
-{
- public:
- CommandBSKickRepeat(Module *creator) : CommandBSKickBase(creator, "botserv/kick/repeat", 2, 4)
- {
- this->SetDesc(_("Configures repeat kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &times = params.size() > 3 ? params[3] : "";
-
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[TTB_REPEAT] = i;
- }
- else
- kd->ttb[TTB_REPEAT] = 0;
-
- kd->repeattimes = 3;
- try
- {
- kd->repeattimes = convertTo<int16_t>(times);
- }
- catch (const ConvertException &) { }
- if (kd->repeattimes < 1)
- kd->repeattimes = 3;
-
- kd->repeat = true;
- if (kd->ttb[TTB_REPEAT])
- {
- if (kd->repeattimes != 1)
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d times), and will place a ban after %d\n"
- "kicks for the same user."), kd->repeattimes, kd->ttb[TTB_REPEAT]);
- else
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d time), and will place a ban after %d\n"
- "kicks for the same user."), kd->repeattimes, kd->ttb[TTB_REPEAT]);
- }
- else
- {
- if (kd->repeattimes != 1)
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d times)."), kd->repeattimes);
- else
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d time)."), kd->repeattimes);
- }
- }
- else if (params[1].equals_ci("OFF"))
- {
- kd->repeat = false;
- source.Reply(_("Bot won't kick for \002repeats\002 anymore."));
- }
- else
- this->OnSyntaxError(source, params[1]);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the repeat kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are repeating\n"
- "themselves \002num\002 times (if num is not given, it\n"
- "defaults to 3).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickReverses : public CommandBSKickBase
-{
- public:
- CommandBSKickReverses(Module *creator) : CommandBSKickBase(creator, "botserv/kick/reverses", 2, 3)
- {
- this->SetDesc(_("Configures reverses kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_REVERSES, "reverses", kd, kd->reverses);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the reverses kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use reverses.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickUnderlines : public CommandBSKickBase
-{
- public:
- CommandBSKickUnderlines(Module *creator) : CommandBSKickBase(creator, "botserv/kick/underlines", 2, 3)
- {
- this->SetDesc(_("Configures underlines kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_UNDERLINES, "underlines", kd, kd->underlines);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the underlines kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use underlines.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSSetDontKickOps : public Command
-{
- public:
- CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("To protect ops against bot kicks"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- 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("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot option setting is temporarily disabled."));
- return;
- }
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- if (params[1].equals_ci("ON"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops";
-
- kd->dontkickops = true;
- source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops";
-
- kd->dontkickops = false;
- source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002ops protection\002 mode on a channel.\n"
- "When it is enabled, ops won't be kicked by the bot\n"
- "even if they don't match the NOKICK level."));
- return true;
- }
-};
-
-class CommandBSSetDontKickVoices : public Command
-{
- public:
- CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("To protect voices against bot kicks"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- 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("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot option setting is temporarily disabled."));
- return;
- }
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- if (params[1].equals_ci("ON"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices";
-
- kd->dontkickvoices = true;
- source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices";
-
- kd->dontkickvoices = false;
- source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002voices protection\002 mode on a channel.\n"
- "When it is enabled, voices won't be kicked by the bot\n"
- "even if they don't match the NOKICK level."));
- return true;
- }
-};
-
-struct BanData
-{
- struct Data
- {
- Anope::string mask;
- time_t last_use;
- int16_t ttb[TTB_SIZE];
-
- Data()
- {
- last_use = 0;
- for (int i = 0; i < TTB_SIZE; ++i)
- this->ttb[i] = 0;
- }
- };
-
- private:
- typedef Anope::map<Data> data_type;
- data_type data_map;
-
- public:
- BanData(Extensible *) { }
-
- Data &get(const Anope::string &key)
- {
- return this->data_map[key];
- }
-
- bool empty() const
- {
- return this->data_map.empty();
- }
-
- void purge()
- {
- time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata");
- for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
- {
- const Anope::string &user = it->first;
- Data &bd = it->second;
- ++it;
-
- if (Anope::CurTime - bd.last_use > keepdata)
- data_map.erase(user);
- }
- }
-};
-
-struct UserData
-{
- UserData(Extensible *)
- {
- last_use = last_start = Anope::CurTime;
- lines = times = 0;
- lastline.clear();
- }
-
- /* Data validity */
- time_t last_use;
-
- /* for flood kicker */
- int16_t lines;
- time_t last_start;
-
- /* for repeat kicker */
- Anope::string lasttarget;
- int16_t times;
-
- Anope::string lastline;
-};
-
-class BanDataPurger : public Timer
-{
- public:
- BanDataPurger(Module *o) : Timer(o, 300, Anope::CurTime, true) { }
-
- void Tick(time_t) anope_override
- {
- 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;
-
- BanData *bd = c->GetExt<BanData>("bandata");
- if (bd != NULL)
- {
- bd->purge();
- if (bd->empty())
- c->Shrink<BanData>("bandata");
- }
- }
- }
-};
-
-class BSKick : public Module
-{
- ExtensibleItem<BanData> bandata;
- ExtensibleItem<UserData> userdata;
- KickerDataImpl::ExtensibleItem kickerdata;
-
- CommandBSKick commandbskick;
- CommandBSKickAMSG commandbskickamsg;
- CommandBSKickBadwords commandbskickbadwords;
- CommandBSKickBolds commandbskickbolds;
- CommandBSKickCaps commandbskickcaps;
- CommandBSKickColors commandbskickcolors;
- CommandBSKickFlood commandbskickflood;
- CommandBSKickItalics commandbskickitalics;
- CommandBSKickRepeat commandbskickrepeat;
- CommandBSKickReverses commandbskickreverse;
- CommandBSKickUnderlines commandbskickunderlines;
-
- CommandBSSetDontKickOps commandbssetdontkickops;
- CommandBSSetDontKickVoices commandbssetdontkickvoices;
-
- BanDataPurger purger;
-
- BanData::Data &GetBanData(User *u, Channel *c)
- {
- BanData *bd = bandata.Require(c);
- return bd->get(u->GetMask());
- }
-
- UserData *GetUserData(User *u, Channel *c)
- {
- ChanUserContainer *uc = c->FindUser(u);
- if (uc == NULL)
- return NULL;
-
- UserData *ud = userdata.Require(uc);
- return ud;
- }
-
- void check_ban(ChannelInfo *ci, User *u, KickerData *kd, int ttbtype)
- {
- /* Don't ban ulines or protected users */
- if (u->IsProtected())
- return;
-
- BanData::Data &bd = this->GetBanData(u, ci->c);
-
- ++bd.ttb[ttbtype];
- if (kd->ttb[ttbtype] && bd.ttb[ttbtype] >= kd->ttb[ttbtype])
- {
- /* Should not use == here because bd.ttb[ttbtype] could possibly be > kd->ttb[ttbtype]
- * if the TTB was changed after it was not set (0) before and the user had already been
- * kicked a few times. Bug #1056 - Adam */
-
- bd.ttb[ttbtype] = 0;
-
- Anope::string mask = ci->GetIdealBan(u);
-
- ci->c->SetMode(NULL, "BAN", mask);
- FOREACH_MOD(OnBotBan, (u, ci, mask));
- }
- }
-
- void bot_kick(ChannelInfo *ci, User *u, const char *message, ...)
- {
- va_list args;
- char buf[1024];
-
- if (!ci || !ci->bi || !ci->c || !u || u->IsProtected() || !ci->c->FindUser(u))
- return;
-
- Anope::string fmt = Language::Translate(u, message);
- va_start(args, message);
- vsnprintf(buf, sizeof(buf), fmt.c_str(), args);
- va_end(args);
-
- ci->c->Kick(ci->bi, u, "%s", buf);
- }
-
- public:
- BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- bandata(this, "bandata"),
- userdata(this, "userdata"),
- kickerdata(this, "kickerdata"),
-
- commandbskick(this),
- commandbskickamsg(this), commandbskickbadwords(this), commandbskickbolds(this), commandbskickcaps(this),
- commandbskickcolors(this), commandbskickflood(this), commandbskickitalics(this), commandbskickrepeat(this),
- commandbskickreverse(this), commandbskickunderlines(this),
-
- commandbssetdontkickops(this), commandbssetdontkickvoices(this),
-
- purger(this)
- {
- me = this;
-
- }
-
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
- {
- if (!ci)
- return;
-
- Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
- Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
- KickerData *kd = kickerdata.Get(ci);
-
- if (kd && kd->badwords)
- {
- if (kd->ttb[TTB_BADWORDS])
- info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->ttb[TTB_BADWORDS]);
- else
- info[_("Bad words kicker")] = enabled;
- }
- else
- info[_("Bad words kicker")] = disabled;
-
- if (kd && kd->bolds)
- {
- if (kd->ttb[TTB_BOLDS])
- info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->ttb[TTB_BOLDS]);
- else
- info[_("Bolds kicker")] = enabled;
- }
- else
- info[_("Bolds kicker")] = disabled;
-
- if (kd && kd->caps)
- {
- if (kd->ttb[TTB_CAPS])
- info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%)"), enabled.c_str(), kd->ttb[TTB_CAPS], kd->capsmin, kd->capspercent);
- else
- info[_("Caps kicker")] = Anope::printf(_("%s (minimum %d/%d%%)"), enabled.c_str(), kd->capsmin, kd->capspercent);
- }
- else
- info[_("Caps kicker")] = disabled;
-
- if (kd && kd->colors)
- {
- if (kd->ttb[TTB_COLORS])
- info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_COLORS]);
- else
- info[_("Colors kicker")] = enabled;
- }
- else
- info[_("Colors kicker")] = disabled;
-
- if (kd && kd->flood)
- {
- if (kd->ttb[TTB_FLOOD])
- info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds)"), enabled.c_str(), kd->ttb[TTB_FLOOD], kd->floodlines, kd->floodsecs);
- else
- info[_("Flood kicker")] = Anope::printf(_("%s (%d lines in %ds)"), enabled.c_str(), kd->floodlines, kd->floodsecs);
- }
- else
- info[_("Flood kicker")] = disabled;
-
- if (kd && kd->repeat)
- {
- if (kd->ttb[TTB_REPEAT])
- info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), kd->ttb[TTB_REPEAT], kd->repeattimes);
- else
- info[_("Repeat kicker")] = Anope::printf(_("%s (%d times)"), enabled.c_str(), kd->repeattimes);
- }
- else
- info[_("Repeat kicker")] = disabled;
-
- if (kd && kd->reverses)
- {
- if (kd->ttb[TTB_REVERSES])
- info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_REVERSES]);
- else
- info[_("Reverses kicker")] = enabled;
- }
- else
- info[_("Reverses kicker")] = disabled;
-
- if (kd && kd->underlines)
- {
- if (kd->ttb[TTB_UNDERLINES])
- info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_UNDERLINES]);
- else
- info[_("Underlines kicker")] = enabled;
- }
- else
- info[_("Underlines kicker")] = disabled;
-
- if (kd && kd->italics)
- {
- if (kd->ttb[TTB_ITALICS])
- info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_ITALICS]);
- else
- info[_("Italics kicker")] = enabled;
- }
- else
- info[_("Italics kicker")] = disabled;
-
- if (kd && kd->amsgs)
- {
- if (kd->ttb[TTB_AMSGS])
- info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_AMSGS]);
- else
- info[_("AMSG kicker")] = enabled;
- }
- else
- info[_("AMSG kicker")] = disabled;
-
- if (kd && kd->dontkickops)
- info.AddOption(_("Ops protection"));
- if (kd && kd->dontkickvoices)
- info.AddOption(_("Voices protection"));
- }
-
- void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
- {
- /* Now we can make kicker stuff. We try to order the checks
- * from the fastest one to the slowest one, since there's
- * no need to process other kickers if a user is kicked before
- * the last kicker check.
- *
- * But FIRST we check whether the user is protected in any
- * way.
- */
- ChannelInfo *ci = c->ci;
- if (ci == NULL)
- return;
- KickerData *kd = kickerdata.Get(ci);
- if (kd == NULL)
- return;
-
- if (ci->AccessFor(u).HasPriv("NOKICK"))
- return;
- else if (kd->dontkickops && (c->HasUserStatus(u, "HALFOP") || c->HasUserStatus(u, "OP") || c->HasUserStatus(u, "PROTECT") || c->HasUserStatus(u, "OWNER")))
- return;
- else if (kd->dontkickvoices && c->HasUserStatus(u, "VOICE"))
- return;
-
- Anope::string realbuf = msg;
-
- /* If it's a /me, cut the CTCP part because the ACTION will cause
- * problems with the caps or badwords kicker
- */
- if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
- {
- realbuf.erase(0, 8);
- realbuf.erase(realbuf.length() - 1);
- }
-
- if (realbuf.empty())
- return;
-
- /* Bolds kicker */
- if (kd->bolds && realbuf.find(2) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_BOLDS);
- bot_kick(ci, u, _("Don't use bolds on this channel!"));
- return;
- }
-
- /* Color kicker */
- if (kd->colors && realbuf.find(3) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_COLORS);
- bot_kick(ci, u, _("Don't use colors on this channel!"));
- return;
- }
-
- /* Reverses kicker */
- if (kd->reverses && realbuf.find(22) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_REVERSES);
- bot_kick(ci, u, _("Don't use reverses on this channel!"));
- return;
- }
-
- /* Italics kicker */
- if (kd->italics && realbuf.find(29) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_ITALICS);
- bot_kick(ci, u, _("Don't use italics on this channel!"));
- return;
- }
-
- /* Underlines kicker */
- if (kd->underlines && realbuf.find(31) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_UNDERLINES);
- bot_kick(ci, u, _("Don't use underlines on this channel!"));
- return;
- }
-
- /* Caps kicker */
- if (kd->caps && realbuf.length() >= static_cast<unsigned>(kd->capsmin))
- {
- int i = 0, l = 0;
-
- for (unsigned j = 0, end = realbuf.length(); j < end; ++j)
- {
- if (isupper(realbuf[j]))
- ++i;
- else if (islower(realbuf[j]))
- ++l;
- }
-
- /* i counts uppercase chars, l counts lowercase chars. Only
- * alphabetic chars (so islower || isupper) qualify for the
- * percentage of caps to kick for; the rest is ignored. -GD
- */
-
- if ((i || l) && i >= kd->capsmin && i * 100 / (i + l) >= kd->capspercent)
- {
- check_ban(ci, u, kd, TTB_CAPS);
- bot_kick(ci, u, _("Turn caps lock OFF!"));
- return;
- }
- }
-
- /* Bad words kicker */
- if (kd->badwords)
- {
- bool mustkick = false;
- BadWords *badwords = ci->GetExt<BadWords>("badwords");
-
- /* Normalize the buffer */
- Anope::string nbuf = Anope::NormalizeBuffer(realbuf);
- bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
-
- /* Normalize can return an empty string if this only conains control codes etc */
- if (badwords && !nbuf.empty())
- for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
- {
- const BadWord *bw = badwords->GetBadWord(i);
-
- if (bw->word.empty())
- continue; // Shouldn't happen
-
- if (bw->word.length() > nbuf.length())
- continue; // This can't ever match
-
- if (bw->type == BW_ANY && ((casesensitive && nbuf.find(bw->word) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
- mustkick = true;
- else if (bw->type == BW_SINGLE)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf)))
- mustkick = true;
- else if (nbuf.find(' ') == len && ((casesensitive && bw->word.equals_cs(nbuf.substr(0, len))) || (!casesensitive && bw->word.equals_ci(nbuf.substr(0, len)))))
- mustkick = true;
- else
- {
- if (len < nbuf.length() && nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = " " + bw->word + " ";
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
- }
- else if (bw->type == BW_START)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->word)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = " " + bw->word;
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
- else if (bw->type == BW_END)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = bw->word + " ";
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
-
- if (mustkick)
- {
- check_ban(ci, u, kd, TTB_BADWORDS);
- if (Config->GetModule(me)->Get<bool>("gentlebadwordreason"))
- bot_kick(ci, u, _("Watch your language!"));
- else
- bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
-
- return;
- }
- } /* for */
- } /* if badwords */
-
- UserData *ud = GetUserData(u, c);
-
- if (ud)
- {
- /* Flood kicker */
- if (kd->flood)
- {
- if (Anope::CurTime - ud->last_start > kd->floodsecs)
- {
- ud->last_start = Anope::CurTime;
- ud->lines = 0;
- }
-
- ++ud->lines;
- if (ud->lines >= kd->floodlines)
- {
- check_ban(ci, u, kd, TTB_FLOOD);
- bot_kick(ci, u, _("Stop flooding!"));
- return;
- }
- }
-
- /* Repeat kicker */
- if (kd->repeat)
- {
- if (!ud->lastline.equals_ci(realbuf))
- ud->times = 0;
- else
- ++ud->times;
-
- if (ud->times >= kd->repeattimes)
- {
- check_ban(ci, u, kd, TTB_REPEAT);
- bot_kick(ci, u, _("Stop repeating yourself!"));
- return;
- }
- }
-
- if (ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
- {
- for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();)
- {
- Channel *chan = it->second->chan;
- ++it;
-
- if (chan->ci && kd->amsgs && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
- {
- check_ban(chan->ci, u, kd, TTB_AMSGS);
- bot_kick(chan->ci, u, _("Don't use AMSGs!"));
- }
- }
- }
-
- ud->lasttarget = ci->name;
- ud->lastline = realbuf;
- }
- }
-};
-
-MODULE_INIT(BSKick)
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
deleted file mode 100644
index 6e9b79c6a..000000000
--- a/modules/commands/cs_access.cpp
+++ /dev/null
@@ -1,904 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static std::map<Anope::string, int16_t, ci::less> defaultLevels;
-
-static inline void reset_levels(ChannelInfo *ci)
-{
- ci->ClearLevels();
- for (std::map<Anope::string, int16_t, ci::less>::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it)
- ci->SetLevel(it->first, it->second);
-}
-
-class AccessChanAccess : public ChanAccess
-{
- public:
- int level;
-
- AccessChanAccess(AccessProvider *p) : ChanAccess(p), level(0)
- {
- }
-
- bool HasPriv(const Anope::string &name) const anope_override
- {
- return this->ci->GetLevel(name) != ACCESS_INVALID && this->level >= this->ci->GetLevel(name);
- }
-
- Anope::string AccessSerialize() const
- {
- return stringify(this->level);
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- try
- {
- this->level = convertTo<int>(data);
- }
- catch (const ConvertException &)
- {
- }
- }
-
- bool operator>(const ChanAccess &other) const anope_override
- {
- if (this->provider != other.provider)
- return ChanAccess::operator>(other);
- else
- return this->level > anope_dynamic_static_cast<const AccessChanAccess *>(&other)->level;
- }
-
- bool operator<(const ChanAccess &other) const anope_override
- {
- if (this->provider != other.provider)
- return ChanAccess::operator<(other);
- else
- return this->level < anope_dynamic_static_cast<const AccessChanAccess *>(&other)->level;
- }
-};
-
-class AccessAccessProvider : public AccessProvider
-{
- public:
- static AccessAccessProvider *me;
-
- AccessAccessProvider(Module *o) : AccessProvider(o, "access/access")
- {
- me = this;
- }
-
- ChanAccess *Create() anope_override
- {
- return new AccessChanAccess(this);
- }
-};
-AccessAccessProvider* AccessAccessProvider::me;
-
-class CommandCSAccess : public Command
-{
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
- Privilege *p = NULL;
- int level = ACCESS_INVALID;
-
- try
- {
- level = convertTo<int>(params[3]);
- }
- catch (const ConvertException &)
- {
- p = PrivilegeManager::FindPrivilege(params[3]);
- if (p != NULL && defaultLevels[p->name])
- level = defaultLevels[p->name];
- }
-
- if (!level)
- {
- source.Reply(_("Access level must be non-zero."));
- return;
- }
- else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
- {
- source.Reply(CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
-
- AccessChanAccess tmp_access(AccessAccessProvider::me);
- tmp_access.ci = ci;
- tmp_access.level = level;
-
- bool override = false;
- const NickAlias *na = NULL;
-
- if ((!highest || *highest <= tmp_access) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
-
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- const ChanAccess *access = ci->GetAccess(i - 1);
- if ((na && na->nc == access->GetAccount()) || mask.equals_ci(access->Mask()))
- {
- /* Don't allow lowering from a level >= u_level */
- if ((!highest || *access >= *highest) && !u_access.founder && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- delete ci->EraseAccess(i - 1);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/access");
- if (!provider)
- return;
- AccessChanAccess *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create());
- access->SetMask(mask, ci);
- access->creator = source.GetNick();
- access->level = level;
- access->last_seen = 0;
- access->created = Anope::CurTime;
- ci->AddAccess(access);
-
- FOREACH_MOD(OnAccessAdd, (ci, source, access));
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level;
- if (p != NULL)
- source.Reply(_("\002%s\002 added to %s access list at privilege %s (level %d)"), access->Mask().c_str(), ci->name.c_str(), p->name.c_str(), level);
- else
- source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->Mask().c_str(), ci->name.c_str(), level);
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
-
- if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask))
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (!ci->GetAccessCount())
- 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)
- {
- class AccessDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- Anope::string Nicks;
- bool denied;
- bool override;
- public:
- AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), denied(false), override(false)
- {
- if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/access/modify"))
- this->override = true;
- }
-
- ~AccessDelCallback()
- {
- if (denied && !deleted)
- source.Reply(ACCESS_DENIED);
- else if (!deleted)
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << Nicks;
-
- if (deleted == 1)
- source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str());
- else
- source.Reply(_("Deleted %d entries from %s access list."), deleted, ci->name.c_str());
- }
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > ci->GetAccessCount())
- return;
-
- ChanAccess *access = ci->GetAccess(Number - 1);
-
- AccessGroup ag = source.AccessFor(ci);
- const ChanAccess *u_highest = ag.Highest();
-
- if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && access->GetAccount() != source.nc)
- {
- denied = true;
- return;
- }
-
- ++deleted;
- if (!Nicks.empty())
- Nicks += ", " + access->Mask();
- else
- Nicks = access->Mask();
-
- ci->EraseAccess(Number - 1);
-
- FOREACH_MOD(OnAccessDel, (ci, source, access));
- delete access;
- }
- }
- delcallback(source, ci, this, mask);
- delcallback.Process();
- }
- else
- {
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- ChanAccess *access = ci->GetAccess(i - 1);
- if (mask.equals_ci(access->Mask()))
- {
- if (access->GetAccount() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- source.Reply(_("\002%s\002 deleted from %s access list."), access->Mask().c_str(), ci->name.c_str());
- bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && access->GetAccount() != source.nc;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask();
-
- ci->EraseAccess(i - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, access));
- delete access;
- }
- return;
- }
- }
-
- source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
- }
-
- return;
- }
-
- void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- 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)
- {
- class AccessListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
-
- public:
- AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAccessCount())
- return;
-
- const ChanAccess *access = ci->GetAccess(number - 1);
-
- Anope::string timebuf;
- if (ci->c)
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- {
- ChannelInfo *p;
- if (access->Matches(cit->second->user, cit->second->user->Account(), p))
- timebuf = "Now";
- }
- if (timebuf.empty())
- {
- if (access->last_seen == 0)
- timebuf = "Never";
- else
- timebuf = Anope::strftime(access->last_seen, NULL, true);
- }
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->Mask();
- entry["By"] = access->creator;
- entry["Last seen"] = timebuf;
- this->list.AddEntry(entry);
- }
- }
- nl_list(list, ci, nick);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *access = ci->GetAccess(i);
-
- if (!nick.empty() && !Anope::Match(access->Mask(), nick))
- continue;
-
- Anope::string timebuf;
- if (ci->c)
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- {
- ChannelInfo *p;
- if (access->Matches(cit->second->user, cit->second->user->Account(), p))
- timebuf = "Now";
- }
- if (timebuf.empty())
- {
- if (access->last_seen == 0)
- timebuf = "Never";
- else
- timebuf = Anope::strftime(access->last_seen, NULL, true);
- }
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->Mask();
- entry["By"] = access->creator;
- entry["Last seen"] = timebuf;
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Access list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of access list"));
- }
-
- return;
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Last seen"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- ci->ClearAccess();
-
- source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
-
- bool override = !source.IsFounder(ci);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
- }
-
- return;
- }
-
- public:
- 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"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[1];
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
- const Anope::string &s = params.size() > 3 ? params[3] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(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");
- bool is_del = cmd.equals_ci("DEL");
-
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (is_list && source.AccessFor(ci).HasPriv("ACCESS_LIST"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("ACCESS_CHANGE"))
- has_access = true;
- else if (is_del)
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na && na->nc == source.GetAccount())
- has_access = true;
- }
-
- /* If LIST, we don't *require* any parameters, but we can take any.
- * If DEL, we require a nick and no level.
- * Else (ADD), we require a level (which implies a nick). */
- if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !is_list)
- source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
- else if (cmd.equals_ci("ADD"))
- this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("VIEW"))
- this->DoView(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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. Any registered user not on the access list has\n"
- "a user level of 0, and any unregistered user has a user level\n"
- "of -1."), source.service->nick.c_str());
- 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"
- "may be a numerical level or the name of a privilege (eg AUTOOP).\n"
- "When a user joins the channel the access they receive is from the\n"
- "highest level entry in the access list."));
- if (!Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- source.Reply(_("The given mask may also be a channel, which will use the\n"
- "access list from the other channel up to the given \037level\037."));
- 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."));
- 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"
- " \002ACCESS #channel LIST 2-5,7-9\002\n"
- " Lists access entries numbered 2 through 5 and\n"
- " 7 through 9.\n"
- " \n"
- "The \002ACCESS VIEW\002 command displays the access list similar\n"
- "to \002ACCESS LIST\002 but shows the creator and last used time.\n"
- " \n"
- "The \002ACCESS CLEAR\002 command clears all entries of the\n"
- "access list."));
- source.Reply(" ");
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/levels", bi, cmd))
- source.Reply(_("\002User access levels\002 can be seen by using the\n"
- "\002%s\002 command; type \002%s%s HELP LEVELS\002 for\n"
- "information."), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
- return true;
- }
-};
-
-class CommandCSLevels : public Command
-{
- void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &what = params[2];
- const Anope::string &lev = params[3];
-
- int level;
-
- if (lev.equals_ci("FOUNDER"))
- level = ACCESS_FOUNDER;
- else
- {
- try
- {
- level = convertTo<int>(lev);
- }
- catch (const ConvertException &)
- {
- this->OnSyntaxError(source, "SET");
- return;
- }
- }
-
- if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
- source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- else
- {
- Privilege *p = PrivilegeManager::FindPrivilege(what);
- if (p == NULL)
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << p->name << " to level " << level;
-
- ci->SetLevel(p->name, level);
- FOREACH_MOD(OnLevelChange, (source, ci, p->name, level));
-
- if (level == ACCESS_FOUNDER)
- source.Reply(_("Level for %s on channel %s changed to founder only."), p->name.c_str(), ci->name.c_str());
- else
- source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), p->name.c_str(), ci->name.c_str(), level);
- }
- }
- }
-
- void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &what = params[2];
-
- /* Don't allow disabling of the founder level. It would be hard to change it back if you don't have access to use this command */
- if (what.equals_ci("FOUNDER"))
- {
- source.Reply(_("You can not disable the founder privilege because it would be impossible to reenable it at a later time."));
- return;
- }
-
- Privilege *p = PrivilegeManager::FindPrivilege(what);
- if (p != NULL)
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable " << p->name;
-
- ci->SetLevel(p->name, ACCESS_INVALID);
- FOREACH_MOD(OnLevelChange, (source, ci, p->name, ACCESS_INVALID));
-
- source.Reply(_("\002%s\002 disabled on channel %s."), p->name.c_str(), ci->name.c_str());
- return;
- }
-
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci)
- {
- source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Level"));
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
-
- for (unsigned i = 0; i < privs.size(); ++i)
- {
- const Privilege &p = privs[i];
- int16_t j = ci->GetLevel(p.name);
-
- ListFormatter::ListEntry entry;
- entry["Name"] = p.name;
-
- if (j == ACCESS_INVALID)
- entry["Level"] = Language::Translate(source.GetAccount(), _("(disabled)"));
- else if (j == ACCESS_FOUNDER)
- entry["Level"] = Language::Translate(source.GetAccount(), _("(founder only)"));
- else
- entry["Level"] = stringify(j);
-
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- void DoReset(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to reset all levels";
-
- reset_levels(ci);
- FOREACH_MOD(OnLevelChange, (source, ci, "ALL", 0));
-
- source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
- return;
- }
-
- public:
- 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"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[1];
- const Anope::string &what = params.size() > 2 ? params[2] : "";
- const Anope::string &s = params.size() > 3 ? params[3] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (cmd.equals_ci("LIST") && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("FOUNDER"))
- has_access = true;
-
- /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
- * one; else, we want none.
- */
- if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !cmd.equals_ci("LIST"))
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("SET"))
- this->DoSet(source, ci, params);
- else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
- this->DoDisable(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci);
- else if (cmd.equals_ci("RESET"))
- this->DoReset(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (subcommand.equals_ci("DESC"))
- {
- source.Reply(_("The following feature/function names are available:"));
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Description"));
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = 0; i < privs.size(); ++i)
- {
- const Privilege &p = privs[i];
- ListFormatter::ListEntry entry;
- entry["Name"] = p.name;
- entry["Description"] = Language::Translate(source.nc, p.desc.c_str());
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- else
- {
- 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"
- "are always restricted to the channel founder.)\n"
- " \n"
- "\002LEVELS SET\002 allows the access level for a function or group of\n"
- "functions to be changed. \002LEVELS DISABLE\002 (or \002DIS\002 for short)\n"
- "disables an automatic feature or disallows access to a\n"
- "function by anyone, INCLUDING the founder (although, the founder\n"
- "can always reenable it). Use \002LEVELS SET founder\002 to make a level\n"
- "founder only.\n"
- " \n"
- "\002LEVELS LIST\002 shows the current levels for each function or\n"
- "group of functions. \002LEVELS RESET\002 resets the levels to the\n"
- "default levels of a newly-created channel.\n"
- " \n"
- "For a list of the features and functions whose levels can be\n"
- "set, see \002HELP LEVELS DESC\002."), source.service->nick.c_str());
- }
- return true;
- }
-};
-
-class CSAccess : public Module
-{
- AccessAccessProvider accessprovider;
- CommandCSAccess commandcsaccess;
- CommandCSLevels commandcslevels;
-
- public:
- CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsaccess(this), commandcslevels(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- defaultLevels.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *priv = conf->GetBlock("privilege", i);
-
- const Anope::string &pname = priv->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &value = priv->Get<const Anope::string>("level");
- if (value.empty())
- continue;
- else if (value.equals_ci("founder"))
- defaultLevels[p->name] = ACCESS_FOUNDER;
- else if (value.equals_ci("disabled"))
- defaultLevels[p->name] = ACCESS_INVALID;
- else
- defaultLevels[p->name] = priv->Get<int16_t>("level");
- }
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- reset_levels(ci);
- }
-
- EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) anope_override
- {
- if (group->ci == NULL)
- return EVENT_CONTINUE;
- /* Special case. Allows a level of -1 to match anyone, and a level of 0 to match anyone identified. */
- int16_t level = group->ci->GetLevel(priv);
- if (level == -1)
- return EVENT_ALLOW;
- else if (level == 0 && group->nc)
- return EVENT_ALLOW;
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSAccess)
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
deleted file mode 100644
index cb0a49ccb..000000000
--- a/modules/commands/cs_akick.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSAKick : public Command
-{
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
- Anope::string reason = params.size() > 3 ? params[3] : "";
- const NickAlias *na = NickAlias::Find(mask);
- NickCore *nc = NULL;
- const AutoKick *akick;
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
-
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- if (IRCD->IsExtbanValid(mask))
- ; /* If this is an extban don't try to complete the mask */
- else if (IRCD->IsChannelValid(mask))
- {
- /* Also don't try to complete the mask if this is a channel */
-
- if (mask.equals_ci(ci->name) && ci->HasExt("PEACE"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- else if (!na)
- {
- /* If the mask contains a realname the reason must be prepended with a : */
- if (mask.find('#') != Anope::string::npos)
- {
- size_t r = reason.find(':');
- if (r != Anope::string::npos)
- {
- mask += " " + reason.substr(0, r);
- mask.trim();
- reason = reason.substr(r + 1);
- reason.trim();
- }
- else
- {
- mask = mask + " " + reason;
- reason.clear();
- }
- }
-
- Entry e("", mask);
-
- mask = (e.nick.empty() ? "*" : e.nick) + "!"
- + (e.user.empty() ? "*" : e.user) + "@"
- + (e.host.empty() ? "*" : e.host);
- if (!e.real.empty())
- mask += "#" + e.real;
- }
- else
- nc = na->nc;
-
- /* Check excepts BEFORE we get this far */
- if (ci->c)
- {
- std::vector<Anope::string> modes = ci->c->GetModeList("EXCEPT");
- for (unsigned int i = 0; i < modes.size(); ++i)
- {
- if (Anope::Match(modes[i], mask))
- {
- source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
- return;
- }
- }
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- /* Opers overriding get to bypass PEACE */
- if (override)
- ;
- /* These peace checks are only for masks */
- else if (IRCD->IsChannelValid(mask))
- ;
- /* Check whether target nick has equal/higher access
- * or whether the mask matches a user with higher/equal access - Viper */
- else if (ci->HasExt("PEACE") && nc)
- {
- AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
- if (nc == ci->GetFounder() || nc_access >= u_access)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- else if (ci->HasExt("PEACE"))
- {
- /* Match against all currently online users with equal or
- * higher access. - Viper */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u2 = it->second;
-
- AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
- Entry entry_mask("", mask);
-
- if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- /* Match against the lastusermask of all nickalias's with equal
- * or higher access. - Viper */
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- {
- na = it->second;
-
- AccessGroup nc_access = ci->AccessFor(na->nc), u_access = source.AccessFor(ci);
- if (na->nc && (na->nc == ci->GetFounder() || nc_access >= u_access))
- {
- Anope::string buf = na->nick + "!" + na->last_usermask;
- if (Anope::Match(buf, mask))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- }
- }
-
- for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
- {
- akick = ci->GetAkick(j);
- if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
- {
- source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->nc ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
- return;
- }
- }
-
- if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax"))
- {
- source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax"));
- return;
- }
-
- if (nc)
- akick = ci->AddAkick(source.GetNick(), nc, reason);
- else
- akick = ci->AddAkick(source.GetNick(), mask, reason);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
-
- FOREACH_MOD(OnAkickAdd, (source, ci, akick));
-
- source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
-
- this->DoEnforce(source, ci);
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params[2];
- unsigned i, end;
-
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AkickDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- AccessGroup ag;
- public:
- AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), deleted(0), ag(source.AccessFor(ci))
- {
- }
-
- ~AkickDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
- else
- source.Reply(_("Deleted %d entries from %s autokick list."), deleted, ci->name.c_str());
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAkickCount())
- return;
-
- const AutoKick *akick = ci->GetAkick(number - 1);
-
- FOREACH_MOD(OnAkickDel, (source, ci, akick));
-
- bool override = !ag.HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << (akick->nc ? akick->nc->display : akick->mask);
-
- ++deleted;
- ci->EraseAkick(number - 1);
- }
- }
- delcallback(source, ci, this, mask);
- delcallback.Process();
- }
- else
- {
- const NickAlias *na = NickAlias::Find(mask);
- const NickCore *nc = na ? *na->nc : NULL;
-
- for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
-
- if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
- break;
- }
-
- if (i == ci->GetAkickCount())
- {
- source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
-
- FOREACH_MOD(OnAkickDel, (source, ci, ci->GetAkick(i)));
-
- ci->EraseAkick(i);
-
- source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
- }
- }
-
- void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 2 ? params[2] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AkickListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
-
- public:
- AkickListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAkickCount())
- return;
-
- const AutoKick *akick = ci->GetAkick(number - 1);
-
- Anope::string timebuf, lastused;
- if (akick->addtime)
- timebuf = Anope::strftime(akick->addtime, NULL, true);
- else
- timebuf = UNKNOWN;
- if (akick->last_used)
- lastused = Anope::strftime(akick->last_used, NULL, true);
- else
- lastused = UNKNOWN;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- if (akick->nc)
- entry["Mask"] = akick->nc->display;
- else
- entry["Mask"] = akick->mask;
- entry["Creator"] = akick->creator;
- entry["Created"] = timebuf;
- entry["Last used"] = lastused;
- entry["Reason"] = akick->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(list, ci, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
-
- if (!mask.empty())
- {
- if (!akick->nc && !Anope::Match(akick->mask, mask))
- continue;
- if (akick->nc && !Anope::Match(akick->nc->display, mask))
- continue;
- }
-
- Anope::string timebuf, lastused;
- if (akick->addtime)
- timebuf = Anope::strftime(akick->addtime, NULL, true);
- else
- timebuf = UNKNOWN;
- if (akick->last_used)
- lastused = Anope::strftime(akick->last_used, NULL, true);
- else
- lastused = UNKNOWN;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- if (akick->nc)
- entry["Mask"] = akick->nc->display;
- else
- entry["Mask"] = akick->mask;
- entry["Creator"] = akick->creator;
- entry["Created"] = timebuf;
- entry["Last used"] = lastused;
- entry["Reason"] = akick->reason;
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Autokick list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of autokick list"));
- }
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Last used")).AddColumn(_("Reason"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoEnforce(CommandSource &source, ChannelInfo *ci)
- {
- Channel *c = ci->c;
- int count = 0;
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- if (c->CheckKick(uc->user))
- ++count;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
-
- source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the akick list";
-
- ci->ClearAkick();
- source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
- }
-
- public:
- 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(_("\037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 ENFORCE"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string chan = params[0];
- Anope::string cmd = params[1];
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(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 has_access = false;
- if (source.AccessFor(ci).HasPriv("AKICK") || source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
-
- if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && Anope::ReadOnly)
- source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
- else if (cmd.equals_ci("ADD"))
- this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("VIEW"))
- this->DoView(source, ci, params);
- else if (cmd.equals_ci("ENFORCE"))
- this->DoEnforce(source, ci);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- BotInfo *bi = Config->GetClient("NickServ");
- 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"
- " \n"
- "The \002AKICK ADD\002 command adds the given nick or usermask\n"
- "to the AutoKick list. If a \037reason\037 is given with\n"
- "the command, that reason will be used when the user is\n"
- "kicked; if not, the default reason is \"User has been\n"
- "banned from the channel\".\n"
- "When akicking a \037registered nick\037 the %s account\n"
- "will be added to the akick list instead of the mask.\n"
- "All users within that nickgroup will then be akicked.\n"),
- source.service->nick.c_str(), bi ? bi->nick.c_str() : "NickServ");
- source.Reply(_(
- " \n"
- "The \002AKICK DEL\002 command removes the given nick or mask\n"
- "from the AutoKick list. It does not, however, remove any\n"
- "bans placed by an AutoKick; those must be removed\n"
- "manually.\n"
- " \n"
- "The \002AKICK LIST\002 command displays the AutoKick list, or\n"
- "optionally only those AutoKick entries which match the\n"
- "given mask.\n"
- " \n"
- "The \002AKICK VIEW\002 command is a more verbose version of the\n"
- "\002AKICK LIST\002 command.\n"
- " \n"
- "The \002AKICK ENFORCE\002 command causes %s to enforce the\n"
- "current AKICK list by removing those users who match an\n"
- "AKICK mask.\n"
- " \n"
- "The \002AKICK CLEAR\002 command clears all entries of the\n"
- "akick list."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CSAKick : public Module
-{
- CommandCSAKick commandcsakick;
-
- public:
- CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsakick(this)
- {
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (!c->ci || c->MatchesList(u, "EXCEPT"))
- return EVENT_CONTINUE;
-
- for (unsigned j = 0, end = c->ci->GetAkickCount(); j < end; ++j)
- {
- AutoKick *autokick = c->ci->GetAkick(j);
- bool kick = false;
-
- if (autokick->nc)
- kick = autokick->nc == u->Account();
- else if (IRCD->IsChannelValid(autokick->mask))
- {
- Channel *chan = Channel::Find(autokick->mask);
- kick = chan != NULL && chan->FindUser(u);
- }
- else
- kick = Entry("BAN", autokick->mask).Matches(u);
-
- if (kick)
- {
- Log(LOG_DEBUG_2) << u->nick << " matched akick " << (autokick->nc ? autokick->nc->display : autokick->mask);
- autokick->last_used = Anope::CurTime;
- if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos)
- mask = autokick->mask;
- reason = autokick->reason;
- if (reason.empty())
- {
- reason = Language::Translate(u, Config->GetModule(this)->Get<const Anope::string>("autokickreason").c_str());
- reason = reason.replace_all_cs("%n", u->nick)
- .replace_all_cs("%c", c->name);
- }
- if (reason.empty())
- reason = Language::Translate(u, _("User has been banned from the channel"));
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSAKick)
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
deleted file mode 100644
index 1cf316b88..000000000
--- a/modules/commands/cs_ban.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static Module *me;
-
-class TempBan : public Timer
-{
- private:
- Anope::string channel;
- Anope::string mask;
- Anope::string mode;
-
- public:
- TempBan(time_t seconds, Channel *c, const Anope::string &banmask, const Anope::string &mod) : Timer(me, seconds), channel(c->name), mask(banmask), mode(mod) { }
-
- void Tick(time_t ctime) anope_override
- {
- Channel *c = Channel::Find(this->channel);
- if (c)
- c->RemoveMode(NULL, mode, this->mask);
- }
-};
-
-class CommandCSBan : public Command
-{
- public:
- CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 4)
- {
- this->SetDesc(_("Bans a given nick or mask on a channel"));
- this->SetSyntax(_("\037channel\037 [+\037expiry\037] {\037nick\037 | \037mask\037} [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- Configuration::Block *block = Config->GetCommand(source);
- const Anope::string &mode = block->Get<Anope::string>("mode", "BAN");
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- Channel *c = ci->c;
- if (c == NULL)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
- else if (IRCD->GetMaxListFor(c) && c->HasMode(mode) >= IRCD->GetMaxListFor(c))
- {
- source.Reply(_("The %s list for %s is full."), mode.lower().c_str(), c->name.c_str());
- return;
- }
-
- Anope::string expiry, target, reason;
- time_t ban_time;
- if (params[1][0] == '+')
- {
- ban_time = Anope::DoTime(params[1]);
- if (ban_time == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- if (params.size() < 3)
- {
- this->SendSyntax(source);
- return;
- }
- target = params[2];
- reason = "Requested";
- if (params.size() > 3)
- reason = params[3];
- }
- else
- {
- ban_time = 0;
- target = params[1];
- reason = "Requested";
- if (params.size() > 2)
- reason = params[2];
- if (params.size() > 3)
- reason += " " + params[3];
- }
-
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
- signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
-
- User *u = source.GetUser();
- User *u2 = User::Find(target, true);
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (!u_access.HasPriv("BAN") && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2)
- {
- AccessGroup u2_access = ci->AccessFor(u2);
-
- if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- /*
- * Don't ban/kick the user on channels where he is excepted
- * to prevent services <-> server wars.
- */
- else if (c->MatchesList(u2, "EXCEPT"))
- source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
- else if (u2->IsProtected())
- source.Reply(ACCESS_DENIED);
- else
- {
- Anope::string mask = ci->GetIdealBan(u2);
-
- bool override = !u_access.HasPriv("BAN") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
-
- if (!c->HasMode(mode, mask))
- {
- c->SetMode(NULL, mode, mask);
- if (ban_time)
- {
- new TempBan(ban_time, c, mask, mode);
- source.Reply(_("Ban on \002%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
- }
- }
-
- /* We still allow host banning while not allowing to kick */
- if (!c->FindUser(u2))
- return;
-
- if (block->Get<bool>("kick", "yes"))
- {
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK")))
- {
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
- }
- }
- }
- else
- {
- bool founder = u_access.HasPriv("FOUNDER");
- bool override = !founder && !u_access.HasPriv("BAN");
-
- Anope::string mask = IRCD->NormalizeMask(target);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
-
- if (!c->HasMode(mode, mask))
- {
- c->SetMode(NULL, mode, mask);
- if (ban_time)
- {
- new TempBan(ban_time, c, mask, mode);
- source.Reply(_("Ban on \002%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
- }
- }
-
- int matched = 0, kicked = 0;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- Entry e(mode, mask);
- if (e.Matches(uc->user))
- {
- ++matched;
-
- AccessGroup u2_access = ci->AccessFor(uc->user);
-
- if (matched > 1 && !founder)
- continue;
- if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access)
- continue;
- else if (ci->c->MatchesList(uc->user, "EXCEPT"))
- continue;
- else if (uc->user->IsProtected())
- continue;
-
- if (block->Get<bool>("kick", "yes"))
- {
- ++kicked;
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- reason += " (Matches " + mask + ")";
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
- }
- }
- }
-
- if (matched)
- source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, mask.c_str(), c->name.c_str());
- else
- source.Reply(_("No users on %s match %s."), c->name.c_str(), mask.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Bans a given nick or mask on a channel. An optional expiry may\n"
- "be given to cause services to remove the ban after a set amount\n"
- "of time.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access\n"
- "and above on the channel. Channel founders may ban masks."));
- return true;
- }
-};
-
-class CSBan : public Module
-{
- CommandCSBan commandcsban;
-
- public:
- CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsban(this)
- {
- me = this;
- }
-};
-
-MODULE_INIT(CSBan)
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
deleted file mode 100644
index a4ec31c1e..000000000
--- a/modules/commands/cs_clone.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSClone : public Command
-{
- void CopySetting(ChannelInfo *ci, ChannelInfo *target_ci, const Anope::string &setting)
- {
- if (ci->HasExt(setting))
- target_ci->Extend<bool>(setting);
- }
-
- void CopyAccess(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- std::set<Anope::string> masks;
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- unsigned count = 0;
-
- for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
- masks.insert(target_ci->GetAccess(i)->Mask());
-
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- const ChanAccess *taccess = ci->GetAccess(i);
- AccessProvider *provider = taccess->provider;
-
- if (access_max && target_ci->GetDeepAccessCount() >= access_max)
- break;
-
- if (masks.count(taccess->Mask()))
- continue;
- masks.insert(taccess->Mask());
-
- ChanAccess *newaccess = provider->Create();
- newaccess->SetMask(taccess->Mask(), target_ci);
- newaccess->creator = taccess->creator;
- newaccess->last_seen = taccess->last_seen;
- newaccess->created = taccess->created;
- newaccess->AccessUnserialize(taccess->AccessSerialize());
-
- target_ci->AddAccess(newaccess);
-
- ++count;
- }
-
- source.Reply(_("%d access entries from \002%s\002 have been cloned to \002%s\002."), count, ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyAkick(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- target_ci->ClearAkick();
- for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
- if (akick->nc)
- target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
- else
- target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
- }
-
- source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyBadwords(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- BadWords *target_badwords = target_ci->Require<BadWords>("badwords"),
- *badwords = ci->Require<BadWords>("badwords");
-
- if (!target_badwords || !badwords)
- {
- source.Reply(ACCESS_DENIED); // BotServ doesn't exist/badwords isn't loaded
- return;
- }
-
- target_badwords->ClearBadWords();
-
- for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
- {
- const BadWord *bw = badwords->GetBadWord(i);
- target_badwords->AddBadWord(bw->word, bw->type);
- }
-
- badwords->Check();
- target_badwords->Check();
-
- source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyLevels(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- const Anope::map<int16_t> &cilevels = ci->GetLevelEntries();
-
- for (Anope::map<int16_t>::const_iterator it = cilevels.begin(); it != cilevels.end(); ++it)
- {
- target_ci->SetLevel(it->first, it->second);
- }
-
- source.Reply(_("All level entries from \002%s\002 have been cloned into \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
-public:
- 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 [\037what\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
- const Anope::string &target = params[1];
- Anope::string what = params.size() > 2 ? params[2] : "";
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- User *u = source.GetUser();
- ChannelInfo *ci = ChannelInfo::Find(channel);
- bool override = false;
-
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- return;
- }
-
- ChannelInfo *target_ci = ChannelInfo::Find(target);
- if (!target_ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- if (ci == target_ci)
- {
- source.Reply(_("Cannot clone channel \002%s\002 to itself!"), target.c_str());
- return;
- }
-
- if (!source.IsFounder(ci) || !source.IsFounder(target_ci))
- {
- if (!source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (what.equals_ci("ALL"))
- what.clear();
-
- if (what.empty())
- {
- delete target_ci;
- target_ci = new ChannelInfo(*ci);
- target_ci->name = target;
- target_ci->time_registered = Anope::CurTime;
- (*RegisteredChannelList)[target_ci->name] = target_ci;
- target_ci->c = Channel::Find(target_ci->name);
-
- target_ci->bi = NULL;
- if (ci->bi)
- ci->bi->Assign(u, target_ci);
-
- if (target_ci->c)
- {
- target_ci->c->ci = target_ci;
-
- target_ci->c->CheckModes();
-
- target_ci->c->SetCorrectModes(u, true);
- }
-
- if (target_ci->c && !target_ci->c->topic.empty())
- {
- target_ci->last_topic = target_ci->c->topic;
- target_ci->last_topic_setter = target_ci->c->topic_setter;
- target_ci->last_topic_time = target_ci->c->topic_time;
- }
- else
- target_ci->last_topic_setter = source.service->nick;
-
- const Anope::string settings[] = { "NOAUTOOP", "CS_KEEP_MODES", "PEACE", "PERSIST", "RESTRICTED",
- "CS_SECURE", "SECUREFOUNDER", "SECUREOPS", "SIGNKICK", "SIGNKICK_LEVEL", "CS_NO_EXPIRE" };
-
- for (unsigned int i = 0; i < sizeof(settings) / sizeof(Anope::string); ++i)
- CopySetting(ci, target_ci, settings[i]);
-
- CopyAccess(source, ci, target_ci);
- CopyAkick(source, ci, target_ci);
- CopyBadwords(source, ci, target_ci);
- CopyLevels(source, ci, target_ci);
-
- FOREACH_MOD(OnChanRegistered, (target_ci));
-
- source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
- else if (what.equals_ci("ACCESS"))
- {
- CopyAccess(source, ci, target_ci);
- }
- else if (what.equals_ci("AKICK"))
- {
- CopyAkick(source, ci, target_ci);
- }
- else if (what.equals_ci("BADWORDS"))
- {
- CopyBadwords(source, ci, target_ci);
- }
- else if (what.equals_ci("LEVELS"))
- {
- CopyLevels(source, ci, target_ci);
- }
- else
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Copies all settings, access, akicks, etc from \002channel\002 to the\n"
- "\002target\002 channel. If \037what\037 is \002ACCESS\002, \002AKICK\002, \002BADWORDS\002,\n"
- "or \002LEVELS\002 then only the respective settings are cloned.\n"
- "You must be the founder of \037channel\037 and \037target\037."));
- return true;
- }
-};
-
-class CSClone : public Module
-{
- CommandCSClone commandcsclone;
-
- public:
- CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsclone(this)
- {
-
- }
-};
-
-MODULE_INIT(CSClone)
diff --git a/modules/commands/cs_drop.cpp b/modules/commands/cs_drop.cpp
deleted file mode 100644
index 83299aee5..000000000
--- a/modules/commands/cs_drop.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSDrop : public Command
-{
- public:
- CommandCSDrop(Module *creator) : Command(creator, "chanserv/drop", 1, 2)
- {
- this->SetDesc(_("Cancel the registration of a channel"));
- this->SetSyntax(_("\037channel\037 \037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- if (Anope::ReadOnly && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (params.size() < 2 || !chan.equals_ci(params[1]))
- {
- source.Reply(_("You must enter the channel name twice as a confirmation that you wish to drop \002%s\002."), chan.c_str());
- return;
- }
-
- if ((ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnChanDrop, MOD_RESULT, (source, ci));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- bool override = (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"));
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->display : "none") << ")";
-
- Reference<Channel> c = ci->c;
- delete ci;
-
- source.Reply(_("Channel \002%s\002 has been dropped."), chan.c_str());
-
- if (c)
- c->CheckModes();
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- if (source.IsServicesOper())
- source.Reply(_("Unregisters the specified channel. Only \002Services Operators\002\n"
- "can drop a channel of which they are not the founder of."));
- else
- source.Reply(_("Unregisters the named channel. Can only be used by\n"
- "the \002channel founder\002."));
-
- return true;
- }
-};
-
-class CSDrop : public Module
-{
- CommandCSDrop commandcsdrop;
-
- public:
- CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsdrop(this)
- {
-
- }
-};
-
-MODULE_INIT(CSDrop)
diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp
deleted file mode 100644
index 796aa5148..000000000
--- a/modules/commands/cs_entrymsg.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_entrymsg.h"
-
-struct EntryMsgImpl : EntryMsg, Serializable
-{
- EntryMsgImpl() : Serializable("EntryMsg")
- {
- }
-
- EntryMsgImpl(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
- {
- this->chan = c->name;
- this->creator = cname;
- this->message = cmessage;
- this->when = ct;
- }
-
- ~EntryMsgImpl();
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["ci"] << this->chan;
- data["creator"] << this->creator;
- data["message"] << this->message;
- data.SetType("when", Serialize::Data::DT_INT); data["when"] << this->when;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct EntryMessageListImpl : EntryMessageList
-{
- EntryMessageListImpl(Extensible *) { }
-
- EntryMsg* Create() anope_override
- {
- return new EntryMsgImpl();
- }
-};
-
-EntryMsgImpl::~EntryMsgImpl()
-{
- ChannelInfo *ci = ChannelInfo::Find(this->chan);
- if (!ci)
- return;
-
- EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
- if (!messages)
- return;
-
- std::vector<EntryMsg *>::iterator it = std::find((*messages)->begin(), (*messages)->end(), this);
- if (it != (*messages)->end())
- (*messages)->erase(it);
-}
-
-
-Serializable* EntryMsgImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci, screator, smessage;
- time_t swhen;
-
- data["ci"] >> sci;
- data["creator"] >> screator;
- data["message"] >> smessage;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- if (obj)
- {
- EntryMsgImpl *msg = anope_dynamic_static_cast<EntryMsgImpl *>(obj);
- msg->chan = ci->name;
- data["creator"] >> msg->creator;
- data["message"] >> msg->message;
- data["when"] >> msg->when;
- return msg;
- }
-
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- data["when"] >> swhen;
-
- EntryMsgImpl *m = new EntryMsgImpl(ci, screator, smessage, swhen);
- (*messages)->push_back(m);
- return m;
-}
-
-class CommandEntryMessage : public Command
-{
- private:
- void DoList(CommandSource &source, ChannelInfo *ci)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if ((*messages)->empty())
- {
- source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
- return;
- }
-
- source.Reply(_("Entry message list for \002%s\002:"), ci->name.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Message"));
- for (unsigned i = 0; i < (*messages)->size(); ++i)
- {
- EntryMsg *msg = (*messages)->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Creator"] = msg->creator;
- entry["Created"] = Anope::strftime(msg->when, NULL, true);
- entry["Message"] = msg->message;
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of entry message list."));
- }
-
- void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries"))
- source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
- else
- {
- (*messages)->push_back(new EntryMsgImpl(ci, source.GetNick(), message));
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
- source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str());
- }
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if (!message.is_pos_number_only())
- source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
- else if ((*messages)->empty())
- source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
- else
- {
- try
- {
- unsigned i = convertTo<unsigned>(message);
- if (i > 0 && i <= (*messages)->size())
- {
- delete (*messages)->at(i - 1);
- if ((*messages)->empty())
- ci->Shrink<EntryMessageList>("entrymsg");
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
- source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str());
- }
- else
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
- }
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- ci->Shrink<EntryMessageList>("entrymsg");
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
- source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
- }
-
- public:
- CommandEntryMessage(Module *creator) : Command(creator, "chanserv/entrymsg", 2, 3)
- {
- this->SetDesc(_("Manage the channel's entry messages"));
- this->SetSyntax(_("\037channel\037 ADD \037message\037"));
- this->SetSyntax(_("\037channel\037 DEL \037num\037"));
- this->SetSyntax(_("\037channel\037 LIST"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (Anope::ReadOnly && !params[1].equals_ci("LIST"))
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("LIST"))
- this->DoList(source, ci);
- else if (params[1].equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else if (params.size() < 3)
- this->OnSyntaxError(source, "");
- else if (params[1].equals_ci("ADD"))
- this->DoAdd(source, ci, params[2]);
- else if (params[1].equals_ci("DEL"))
- this->DoDel(source, ci, params[2]);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Controls what messages will be sent to users when they join the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG ADD\002 command adds the given message to\n"
- "the list of messages shown to users when they join\n"
- "the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG DEL\002 command removes the specified message from\n"
- "the list of messages shown to users when they join\n"
- "the channel. You can remove a message by specifying its number\n"
- "which you can get by listing the messages as explained below."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG LIST\002 command displays a listing of messages\n"
- "shown to users when they join the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG CLEAR\002 command clears all entries from\n"
- "the list of messages shown to users when they join\n"
- "the channel, effectively disabling entry messages."));
- source.Reply(" ");
- source.Reply(_("Adding, deleting, or clearing entry messages requires the\n"
- "SET permission."));
- return true;
- }
-};
-
-class CSEntryMessage : public Module
-{
- CommandEntryMessage commandentrymsg;
- ExtensibleItem<EntryMessageListImpl> eml;
- Serialize::Type entrymsg_type;
-
- public:
- CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandentrymsg(this),
- eml(this, "entrymsg"), entrymsg_type("EntryMsg", EntryMsgImpl::Unserialize)
- {
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (u && c && c->ci && u->server->IsSynced())
- {
- EntryMessageList *messages = c->ci->GetExt<EntryMessageList>("entrymsg");
-
- if (messages != NULL)
- for (unsigned i = 0; i < (*messages)->size(); ++i)
- u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str());
- }
- }
-};
-
-MODULE_INIT(CSEntryMessage)
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
deleted file mode 100644
index 477cc2468..000000000
--- a/modules/commands/cs_flags.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static std::map<Anope::string, char> defaultFlags;
-
-class FlagsChanAccess : public ChanAccess
-{
- public:
- std::set<char> flags;
-
- FlagsChanAccess(AccessProvider *p) : ChanAccess(p)
- {
- }
-
- bool HasPriv(const Anope::string &priv) const anope_override
- {
- std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
- if (it != defaultFlags.end() && this->flags.count(it->second) > 0)
- return true;
- return false;
- }
-
- Anope::string AccessSerialize() const
- {
- return Anope::string(this->flags.begin(), this->flags.end());
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- for (unsigned i = data.length(); i > 0; --i)
- this->flags.insert(data[i - 1]);
- }
-
- static Anope::string DetermineFlags(const ChanAccess *access)
- {
- if (access->provider->name == "access/flags")
- return access->AccessSerialize();
-
- std::set<char> buffer;
-
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- if (access->HasPriv(it->first))
- buffer.insert(it->second);
-
- if (buffer.empty())
- return "(none)";
- else
- return Anope::string(buffer.begin(), buffer.end());
- }
-};
-
-class FlagsAccessProvider : public AccessProvider
-{
- public:
- static FlagsAccessProvider *ap;
-
- FlagsAccessProvider(Module *o) : AccessProvider(o, "access/flags")
- {
- ap = this;
- }
-
- ChanAccess *Create() anope_override
- {
- return new FlagsChanAccess(this);
- }
-};
-FlagsAccessProvider* FlagsAccessProvider::ap;
-
-class CommandCSFlags : public Command
-{
- void DoModify(CommandSource &source, ChannelInfo *ci, Anope::string mask, const Anope::string &flags)
- {
- if (flags.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
- const NickAlias *na = NULL;
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- ChanAccess *current = NULL;
- unsigned current_idx;
- std::set<char> current_flags;
- bool override = false;
- for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx)
- {
- ChanAccess *access = ci->GetAccess(current_idx - 1);
- if ((na && na->nc == access->GetAccount()) || mask.equals_ci(access->Mask()))
- {
- // Flags allows removing others that have the same access as you,
- // but no other access system does.
- if (highest && highest->provider != FlagsAccessProvider::ap && !u_access.founder)
- // operator<= on the non-me entry!
- if (*highest <= *access)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- current = access;
- Anope::string cur_flags = FlagsChanAccess::DetermineFlags(access);
- for (unsigned j = cur_flags.length(); j > 0; --j)
- current_flags.insert(cur_flags[j - 1]);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- Privilege *p = NULL;
- bool add = true;
- for (size_t i = 0; i < flags.length(); ++i)
- {
- char f = flags[i];
- switch (f)
- {
- case '+':
- add = true;
- break;
- case '-':
- add = false;
- break;
- case '*':
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- {
- bool has = current_flags.count(it->second);
- // If we are adding a flag they already have or removing one they don't have, don't bother
- if (add == has)
- continue;
-
- if (!u_access.HasPriv(it->first) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- continue;
- }
-
- if (add)
- current_flags.insert(it->second);
- else
- current_flags.erase(it->second);
- }
- break;
- default:
- p = PrivilegeManager::FindPrivilege(flags.substr(i));
- if (p != NULL && defaultFlags[p->name])
- {
- f = defaultFlags[p->name];
- i = flags.length();
- }
-
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- {
- if (f != it->second)
- continue;
- else if (!u_access.HasPriv(it->first) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(_("You cannot set the \002%c\002 flag."), f);
- break;
- }
- }
- if (add)
- current_flags.insert(f);
- else
- current_flags.erase(f);
- break;
- }
- }
- }
- if (current_flags.empty())
- {
- if (current != NULL)
- {
- ci->EraseAccess(current_idx - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, current));
- delete current;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
- source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str());
- }
- else
- {
- source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
- }
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/flags");
- if (!provider)
- return;
- FlagsChanAccess *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create());
- access->SetMask(mask, ci);
- access->creator = source.GetNick();
- access->last_seen = current ? current->last_seen : 0;
- access->created = Anope::CurTime;
- access->flags = current_flags;
-
- if (current != NULL)
- delete current;
-
- ci->AddAccess(access);
-
- FOREACH_MOD(OnAccessAdd, (ci, source, access));
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to modify " << mask << "'s flags to " << access->AccessSerialize();
- if (p != NULL)
- {
- if (add)
- source.Reply(_("Privilege \002%s\002 added to \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- else
- source.Reply(_("Privilege \002%s\002 removed from \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- }
- else
- source.Reply(_("Flags for \002%s\002 on %s set to +\002%s\002"), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &arg = params.size() > 2 ? params[2] : "";
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Flags")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- unsigned count = 0;
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *access = ci->GetAccess(i);
- const Anope::string &flags = FlagsChanAccess::DetermineFlags(access);
-
- if (!arg.empty())
- {
- if (arg[0] == '+')
- {
- bool pass = true;
- for (size_t j = 1; j < arg.length(); ++j)
- if (flags.find(arg[j]) == Anope::string::npos)
- pass = false;
- if (pass == false)
- continue;
- }
- else if (!Anope::Match(access->Mask(), arg))
- continue;
- }
-
- ListFormatter::ListEntry entry;
- ++count;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = access->Mask();
- entry["Flags"] = flags;
- entry["Creator"] = access->creator;
- entry["Created"] = Anope::strftime(access->created, source.nc, true);
- list.AddEntry(entry);
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Flags list for %s"), ci->name.c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- if (count == ci->GetAccessCount())
- source.Reply(_("End of access list."));
- else
- source.Reply(_("End of access list - %d/%d entries shown."), count, ci->GetAccessCount());
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- ci->ClearAccess();
-
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
-
- bool override = !source.IsFounder(ci);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
- }
-
- return;
- }
-
- public:
- CommandCSFlags(Module *creator) : Command(creator, "chanserv/flags", 1, 4)
- {
- this->SetDesc(_("Modify the list of privileged users"));
- this->SetSyntax(_("\037channel\037 [MODIFY] \037mask\037 \037changes\037"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | +\037flags\037]"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &cmd = params.size() > 1 ? params[1] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- bool is_list = cmd.empty() || cmd.equals_ci("LIST");
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (is_list && source.AccessFor(ci).HasPriv("ACCESS_LIST"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("ACCESS_CHANGE"))
- has_access = true;
-
- if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !is_list)
- source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
- else if (is_list)
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- {
- Anope::string mask, flags;
- if (cmd.equals_ci("MODIFY"))
- {
- mask = params.size() > 2 ? params[2] : "";
- flags = params.size() > 3 ? params[3] : "";
- }
- else
- {
- mask = cmd;
- flags = params.size() > 2 ? params[2] : "";
- }
-
- this->DoModify(source, ci, mask, flags);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("%s is another way to modify the channel access list, similar to\n"
- "the XOP and ACCESS methods."), source.command.c_str());
- source.Reply(" ");
- source.Reply(_("The \002MODIFY\002 command allows you to modify the access list. If the mask is\n"
- "not already on the access list it is added, then the changes are applied.\n"
- "If the mask has no more flags, then the mask is removed from the access list.\n"
- "Additionally, you may use +* or -* to add or remove all flags, respectively. You are\n"
- "only able to modify the access list if you have the proper permission on the channel,\n"
- "and even then you can only give other people access to the equivalent of what your access is."));
- source.Reply(" ");
- source.Reply(_("The \002LIST\002 command allows you to list existing entries on the channel access list.\n"
- "If a mask is given, the mask is wildcard matched against all existing entries on the\n"
- "access list, and only those entries are returned. If a set of flags is given, only those\n"
- "on the access list with the specified flags are returned."));
- source.Reply(" ");
- source.Reply(_("The \002CLEAR\002 command clears the channel access list. This requires channel founder access."));
- source.Reply(" ");
- source.Reply(_("The available flags are:"));
-
- typedef std::multimap<char, Anope::string, ci::less> reverse_map;
- reverse_map reverse;
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- reverse.insert(std::make_pair(it->second, it->first));
-
- for (reverse_map::iterator it = reverse.begin(), it_end = reverse.end(); it != it_end; ++it)
- {
- Privilege *p = PrivilegeManager::FindPrivilege(it->second);
- if (p == NULL)
- continue;
- source.Reply(" %c - %s", it->first, Language::Translate(source.nc, p->desc.c_str()));
- }
-
- return true;
- }
-};
-
-class CSFlags : public Module
-{
- FlagsAccessProvider accessprovider;
- CommandCSFlags commandcsflags;
-
- public:
- CSFlags(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsflags(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- defaultFlags.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *priv = conf->GetBlock("privilege", i);
-
- const Anope::string &pname = priv->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &value = priv->Get<const Anope::string>("flag");
- if (value.empty())
- continue;
-
- defaultFlags[p->name] = value[0];
- }
- }
-};
-
-MODULE_INIT(CSFlags)
diff --git a/modules/commands/cs_getkey.cpp b/modules/commands/cs_getkey.cpp
deleted file mode 100644
index b9d58393d..000000000
--- a/modules/commands/cs_getkey.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSGetKey : public Command
-{
- public:
- CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
- {
- this->SetDesc(_("Returns the key of the given channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- 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("GETKEY") && !source.HasCommand("chanserv/getkey"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Anope::string key;
- if (!ci->c || !ci->c->GetParam("KEY", key))
- {
- source.Reply(_("Channel \002%s\002 has no key."), chan.c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("GETKEY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
-
- source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the key of the given channel."));
- return true;
- }
-};
-
-class CSGetKey : public Module
-{
- CommandCSGetKey commandcsgetkey;
-
- public:
- CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsgetkey(this)
- {
-
- }
-};
-
-MODULE_INIT(CSGetKey)
diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp
deleted file mode 100644
index 8ebcc8e40..000000000
--- a/modules/commands/cs_info.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSInfo : public Command
-{
- public:
- CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
- {
- this->SetDesc(_("Lists information about the specified registered channel"));
- this->SetSyntax(_("\037channel\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- NickCore *nc = source.nc;
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool has_auspex = source.HasPriv("chanserv/auspex");
- bool show_all = false;
-
- /* Should we show all fields? Only for sadmins and identified users */
- if (source.AccessFor(ci).HasPriv("INFO") || has_auspex)
- show_all = true;
-
- InfoFormatter info(nc);
-
- source.Reply(CHAN_INFO_HEADER, chan.c_str());
- if (ci->GetFounder())
- info[_("Founder")] = ci->GetFounder()->display;
-
- if (show_all && ci->GetSuccessor())
- info[_("Successor")] = ci->GetSuccessor()->display;
-
- if (!ci->desc.empty())
- info[_("Description")] = ci->desc;
-
- info[_("Registered")] = Anope::strftime(ci->time_registered, source.GetAccount());
- info[_("Last used")] = Anope::strftime(ci->last_used, source.GetAccount());
-
- if (show_all)
- {
- info[_("Ban type")] = stringify(ci->bantype);
- }
-
- FOREACH_MOD(OnChanInfo, (source, ci, info, show_all));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists information about the specified registered channel,\n"
- "including its founder, time of registration, last\n"
- "time used, and description. If the user issuing the\n"
- "command has the appropriate access for it, then the\n"
- "successor, last topic set, settings and expiration\n"
- "time will also be displayed when applicable."));
- return true;
- }
-};
-
-class CSInfo : public Module
-{
- CommandCSInfo commandcsinfo;
-
- public:
- CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(CSInfo)
diff --git a/modules/commands/cs_invite.cpp b/modules/commands/cs_invite.cpp
deleted file mode 100644
index a95e25b30..000000000
--- a/modules/commands/cs_invite.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSInvite : public Command
-{
- public:
- CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
- {
- this->SetDesc(_("Invites you or an optionally specified nick into a channel"));
- this->SetSyntax(_("\037channel\037 [\037nick\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- User *u = source.GetUser();
- Channel *c = Channel::Find(chan);
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
-
- ChannelInfo *ci = c->ci;
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("INVITE") && !source.HasCommand("chanserv/invite"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- User *u2;
- if (params.size() == 1)
- u2 = u;
- else
- u2 = User::Find(params[1], true);
-
- if (!u2)
- {
- source.Reply(NICK_X_NOT_IN_USE, params.size() > 1 ? params[1].c_str() : source.GetNick().c_str());
- return;
- }
-
- if (c->FindUser(u2))
- {
- if (u2 == u)
- source.Reply(_("You are already in \002%s\002!"), c->name.c_str());
- else
- source.Reply(_("\002%s\002 is already in \002%s\002!"), u2->nick.c_str(), c->name.c_str());
- }
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("INVITE");
-
- IRCD->SendInvite(ci->WhoSends(), c, u2);
- if (u2 != u)
- {
- 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 by \002%s\002."), c->name.c_str(), source.GetNick().c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
- }
- else
- {
- u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells %s to invite you or an optionally specified\n"
- "nick into the given channel.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access and above\n"
- "on the channel."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CSInvite : public Module
-{
- CommandCSInvite commandcsinvite;
-
- public:
- CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsinvite(this)
- {
-
- }
-};
-
-MODULE_INIT(CSInvite)
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
deleted file mode 100644
index d552efb23..000000000
--- a/modules/commands/cs_kick.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSKick : public Command
-{
- public:
- CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
- {
- this->SetDesc(_("Kicks a specified nick from a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
- this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &target = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "Requested";
-
- User *u = source.GetUser();
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- Channel *c = Channel::Find(params[0]);
- User *u2 = User::Find(target, true);
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
- else if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
- signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2)
- {
- AccessGroup u2_access = ci->AccessFor(u2);
- if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2->IsProtected())
- source.Reply(ACCESS_DENIED);
- else if (!c->FindUser(u2))
- source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
- else
- {
- bool override = !u_access.HasPriv("KICK") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
-
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
- }
- }
- else if (u_access.HasPriv("FOUNDER"))
- {
- Anope::string mask = IRCD->NormalizeMask(target);
-
- Log(LOG_COMMAND, source, this, ci) << "for " << mask;
-
- int matched = 0, kicked = 0;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- Entry e("", mask);
- if (e.Matches(uc->user))
- {
- ++matched;
-
- AccessGroup u2_access = ci->AccessFor(uc->user);
- if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access)
- continue;
- else if (uc->user->IsProtected())
- continue;
-
- ++kicked;
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- reason += " (Matches " + mask + ")";
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
- }
- }
-
- if (matched)
- source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, mask.c_str(), c->name.c_str());
- else
- source.Reply(_("No users on %s match %s."), c->name.c_str(), mask.c_str());
- }
- else
- source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Kicks a specified nick from a channel.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access\n"
- "and above on the channel. Channel founders can also specify masks."));
- return true;
- }
-};
-
-class CSKick : public Module
-{
- CommandCSKick commandcskick;
-
- public:
- CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcskick(this)
- {
-
- }
-};
-
-MODULE_INIT(CSKick)
diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp
deleted file mode 100644
index bb2fd854d..000000000
--- a/modules/commands/cs_list.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-
-class CommandCSList : public Command
-{
- public:
- CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
- {
- this->SetDesc(_("Lists all registered channels matching the given pattern"));
- this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string pattern = params[0];
- unsigned nchans;
- bool is_servadmin = source.HasCommand("chanserv/list");
- int count = 0, from = 0, to = 0;
- bool suspended = false, channoexpire = false;
-
- if (pattern[0] == '#')
- {
- Anope::string n1, n2;
- sepstream(pattern.substr(1), '-').GetToken(n1, 0);
- sepstream(pattern, '-').GetToken(n2, 1);
-
- try
- {
- from = convertTo<int>(n1);
- to = convertTo<int>(n2);
- }
- catch (const ConvertException &)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- source.Reply(_("To search for channels starting with #, search for the channel\n"
- "name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
- return;
- }
-
- pattern = "*";
- }
-
- nchans = 0;
-
- if (is_servadmin && params.size() > 1)
- {
- Anope::string keyword;
- spacesepstream keywords(params[1]);
- while (keywords.GetToken(keyword))
- {
- if (keyword.equals_ci("SUSPENDED"))
- suspended = true;
- if (keyword.equals_ci("NOEXPIRE"))
- channoexpire = true;
- }
- }
-
- Anope::string spattern = "#" + pattern;
- unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
-
- source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Description"));
-
- Anope::map<ChannelInfo *> ordered_map;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- ordered_map[it->first] = it->second;
-
- for (Anope::map<ChannelInfo *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (!is_servadmin)
- {
- if (ci->HasExt("CS_PRIVATE") || ci->HasExt("CS_SUSPENDED"))
- continue;
- if (ci->c && ci->c->HasMode("SECRET"))
- continue;
-
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
- if (secret && secret->set)
- continue;
- }
-
- if (suspended && !ci->HasExt("CS_SUSPENDED"))
- continue;
-
- if (channoexpire && !ci->HasExt("CS_NO_EXPIRE"))
- continue;
-
- if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true) || Anope::Match(ci->desc, pattern, false, true) || Anope::Match(ci->last_topic, pattern, false, true))
- {
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
- {
- bool isnoexpire = false;
- if (is_servadmin && (ci->HasExt("CS_NO_EXPIRE")))
- isnoexpire = true;
-
- ListFormatter::ListEntry entry;
- entry["Name"] = (isnoexpire ? "!" : "") + ci->name;
- if (ci->HasExt("CS_SUSPENDED"))
- entry["Description"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
- else
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- }
- ++count;
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all registered channels matching the given pattern.\n"
- "Channels with the \002PRIVATE\002 option set will only be\n"
- "displayed to Services Operators with the proper access.\n"
- "Channels with the \002NOEXPIRE\002 option set will have\n"
- "a \002!\002 prefixed to the channel for Services Operators to see.\n"
- " \n"
- "Note that a preceding '#' specifies a range, channel names\n"
- "are to be written without '#'.\n"
- " \n"
- "If the SUSPENDED or NOEXPIRE options are given, only channels\n"
- "which, respectively, are SUSPENDED or have the NOEXPIRE\n"
- "flag set will be displayed. If multiple options are given,\n"
- "all channels matching at least one option will be displayed.\n"
- "Note that these options are limited to \037Services Operators\037.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002LIST *anope*\002\n"
- " Lists all registered channels with \002anope\002 in their\n"
- " names (case insensitive).\n"
- " \n"
- " \002LIST * NOEXPIRE\002\n"
- " Lists all registered channels which have been set to not expire.\n"
- " \n"
- " \002LIST #51-100\002\n"
- " Lists all registered channels within the given range (51-100)."));
-
- if (!Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const Anope::string>("regexengine").c_str());
- }
-
- return true;
- }
-};
-
-class CommandCSSetPrivate : public Command
-{
- public:
- CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Hide channel from the LIST command"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
- ci->Extend<bool>("CS_PRIVATE");
- source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
- ci->Shrink<bool>("CS_PRIVATE");
- source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PRIVATE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002private\002 option for a channel."));
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/list", bi, cmd))
- source.Reply(_("When \002private\002 is set, the channel will not appear in\n"
- "%s's %s command."), bi->nick.c_str(), cmd.c_str());
- return true;
- }
-};
-
-class CSList : public Module
-{
- CommandCSList commandcslist;
- CommandCSSetPrivate commandcssetprivate;
-
- SerializableExtensibleItem<bool> priv;
-
- public:
- CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcslist(this), commandcssetprivate(this), priv(this, "CS_PRIVATE")
- {
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (priv.HasExt(ci))
- info.AddOption(_("Private"));
- }
-};
-
-MODULE_INIT(CSList)
diff --git a/modules/commands/cs_log.cpp b/modules/commands/cs_log.cpp
deleted file mode 100644
index 8fd996f27..000000000
--- a/modules/commands/cs_log.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_log.h"
-
-struct LogSettingImpl : LogSetting, Serializable
-{
- LogSettingImpl() : Serializable("LogSetting")
- {
- }
-
- ~LogSettingImpl()
- {
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci)
- {
- LogSettings *ls = ci->GetExt<LogSettings>("logsettings");
- if (ls)
- {
- LogSettings::iterator it = std::find((*ls)->begin(), (*ls)->end(), this);
- if (it != (*ls)->end())
- (*ls)->erase(it);
- }
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["ci"] << chan;
- data["service_name"] << service_name;
- data["command_service"] << command_service;
- data["command_name"] << command_name;
- data["method"] << method;
- data["extra"] << extra;
- data["creator"] << creator;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string sci;
- data["ci"] >> sci;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (ci == NULL)
- return NULL;
-
- LogSettingImpl *ls;
- if (obj)
- ls = anope_dynamic_static_cast<LogSettingImpl *>(obj);
- else
- {
- LogSettings *lsettings = ci->Require<LogSettings>("logsettings");
- ls = new LogSettingImpl();
- (*lsettings)->push_back(ls);
- }
-
- ls->chan = ci->name;
- data["service_name"] >> ls->service_name;
- data["command_service"] >> ls->command_service;
- data["command_name"] >> ls->command_name;
- data["method"] >> ls->method;
- data["extra"] >> ls->extra;
- data["creator"] >> ls->creator;
- data["created"] >> ls->created;
-
- return ls;
- }
-};
-
-struct LogSettingsImpl : LogSettings
-{
- LogSettingsImpl(Extensible *) { }
-
- ~LogSettingsImpl()
- {
- for (iterator it = (*this)->begin(); it != (*this)->end();)
- {
- LogSetting *ls = *it;
- ++it;
- delete ls;
- }
- }
-
- LogSetting *Create() anope_override
- {
- return new LogSettingImpl();
- }
-};
-
-class CommandCSLog : public Command
-{
-public:
- CommandCSLog(Module *creator) : Command(creator, "chanserv/log", 1, 4)
- {
- this->SetDesc(_("Configures channel logging settings"));
- this->SetSyntax(_("\037channel\037"));
- this->SetSyntax(_("\037channel\037 \037command\037 \037method\037 [\037status\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
-
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else if (params.size() == 1)
- {
- LogSettings *ls = ci->Require<LogSettings>("logsettings");
- if (!ls || (*ls)->empty())
- source.Reply(_("There currently are no logging configurations for %s."), ci->name.c_str());
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Service")).AddColumn(_("Command")).AddColumn(_("Method")).AddColumn("");
-
- for (unsigned i = 0; i < (*ls)->size(); ++i)
- {
- const LogSetting *log = (*ls)->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Service"] = log->command_service;
- entry["Command"] = !log->command_name.empty() ? log->command_name : log->service_name;
- entry["Method"] = log->method;
- entry[""] = log->extra;
- list.AddEntry(entry);
- }
-
- source.Reply(_("Log list for %s:"), ci->name.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else if (params.size() > 2)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- LogSettings *ls = ci->Require<LogSettings>("logsettings");
- const Anope::string &command = params[1];
- const Anope::string &method = params[2];
- const Anope::string &extra = params.size() > 3 ? params[3] : "";
-
- size_t sl = command.find('/');
- if (sl == Anope::string::npos)
- {
- source.Reply(_("%s is not a valid command."), command.c_str());
- return;
- }
-
- Anope::string service = command.substr(0, sl),
- command_name = command.substr(sl + 1);
- BotInfo *bi = BotInfo::Find(service, true);
-
- Anope::string service_name;
-
- /* Allow either a command name or a service name. */
- if (bi && bi->commands.count(command_name))
- {
- /* Get service name from command */
- service_name = bi->commands[command_name].name;
- }
- else if (ServiceReference<Command>("Command", command.lower()))
- {
- /* This is the service name, don't use any specific command */
- service_name = command;
- bi = NULL;
- command_name.clear();
- }
- else
- {
- source.Reply(_("%s is not a valid command."), command.c_str());
- return;
- }
-
- if (!method.equals_ci("MESSAGE") && !method.equals_ci("NOTICE") && !method.equals_ci("MEMO"))
- {
- source.Reply(_("%s is not a valid logging method."), method.c_str());
- return;
- }
-
- for (unsigned i = 0; i < extra.length(); ++i)
- if (ModeManager::GetStatusChar(extra[i]) == 0)
- {
- source.Reply(_("%c is an unknown status mode."), extra[i]);
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("SET");
-
- for (unsigned i = (*ls)->size(); i > 0; --i)
- {
- LogSetting *log = (*ls)->at(i - 1);
-
- if (log->service_name == service_name && log->method.equals_ci(method) && command_name.equals_ci(log->command_name))
- {
- if (log->extra == extra)
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
- source.Reply(_("Logging for command %s on %s with log method %s%s%s has been removed."), !log->command_name.empty() ? log->command_name.c_str() : log->service_name.c_str(), !log->command_service.empty() ? log->command_service.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- delete log;
- }
- else
- {
- log->extra = extra;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change logging for " << command << " to method " << method << (extra == "" ? "" : " ") << extra;
- source.Reply(_("Logging changed for command %s on %s, now using log method %s%s%s."), !log->command_name.empty() ? log->command_name.c_str() : log->service_name.c_str(), !log->command_service.empty() ? log->command_service.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- }
- return;
- }
- }
-
- LogSetting *log = new LogSettingImpl();
- log->chan = ci->name;
- log->service_name = service_name;
- if (bi)
- log->command_service = bi->nick;
- log->command_name = command_name;
- log->method = method;
- log->extra = extra;
- log->created = Anope::CurTime;
- log->creator = source.GetNick();
-
- (*ls)->push_back(log);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to log " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
-
- source.Reply(_("Logging is now active for command %s on %s, using log method %s%s%s."), !command_name.empty() ? command_name.c_str() : service_name.c_str(), bi ? bi->nick.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The %s command allows users to configure logging settings\n"
- "for their channel. If no parameters are given this command\n"
- "lists the current logging methods in place for this channel.\n"
- " \n"
- "Otherwise, \037command\037 must be a command name, and \037method\037\n"
- "is one of the following logging methods:\n"
- " \n"
- " MESSAGE [status], NOTICE [status], MEMO\n"
- " \n"
- "Which are used to message, notice, and memo the channel respectively.\n"
- "With MESSAGE or NOTICE you must have a service bot assigned to and joined\n"
- "to your channel. Status may be a channel status such as @ or +.\n"
- " \n"
- "To remove a logging method use the same syntax as you would to add it.\n"
- " \n"
- "Example:\n"
- " %s #anope chanserv/access MESSAGE @\n"
- " Would message any channel operators whenever someone used the\n"
- " ACCESS command on ChanServ on the channel."),
- source.command.upper().c_str(), source.command.upper().c_str());
- return true;
- }
-};
-
-class CSLog : public Module
-{
- ServiceReference<MemoServService> MSService;
- CommandCSLog commandcslog;
- ExtensibleItem<LogSettingsImpl> logsettings;
- Serialize::Type logsetting_type;
-
- struct LogDefault
- {
- Anope::string service, command, method;
- };
-
- std::vector<LogDefault> defaults;
-
- public:
- CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- MSService("MemoServService", "MemoServ"), commandcslog(this),
- logsettings(this, "logsettings"), logsetting_type("LogSetting", LogSettingImpl::Unserialize)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- defaults.clear();
-
- for (int i = 0; i < block->CountBlock("default"); ++i)
- {
- Configuration::Block *def = block->GetBlock("default", i);
-
- LogDefault ld;
-
- ld.service = def->Get<const Anope::string>("service");
- ld.command = def->Get<const Anope::string>("command");
- ld.method = def->Get<const Anope::string>("method");
-
- defaults.push_back(ld);
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- if (defaults.empty())
- return;
-
- LogSettings *ls = logsettings.Require(ci);
- for (unsigned i = 0; i < defaults.size(); ++i)
- {
- LogDefault &d = defaults[i];
-
- LogSetting *log = new LogSettingImpl();
- log->chan = ci->name;
-
- if (!d.service.empty())
- {
- log->service_name = d.service.lower() + "/" + d.command.lower();
- log->command_service = d.service;
- log->command_name = d.command;
- }
- else
- log->service_name = d.command;
-
- spacesepstream sep(d.method);
- sep.GetToken(log->method);
- log->extra = sep.GetRemaining();
-
- log->created = Anope::CurTime;
- log->creator = ci->GetFounder() ? ci->GetFounder()->display : "(default)";
-
- (*ls)->push_back(log);
- }
- }
-
- void OnLog(Log *l) anope_override
- {
- if (l->type != LOG_COMMAND || l->u == NULL || l->c == NULL || l->ci == NULL || !Me || !Me->IsSynced())
- return;
-
- LogSettings *ls = logsettings.Get(l->ci);
- if (ls)
- for (unsigned i = 0; i < (*ls)->size(); ++i)
- {
- const LogSetting *log = (*ls)->at(i);
-
- /* wrong command */
- if (log->service_name != l->c->name)
- continue;
-
- /* if a command name is given check the service and the command */
- if (!log->command_name.empty())
- {
- /* wrong service (only check if not a fantasy command, though) */
- if (!l->source->c && log->command_service != l->source->service->nick)
- continue;
-
- if (!log->command_name.equals_ci(l->source->command))
- continue;
- }
-
- Anope::string buffer = l->u->nick + " used " + l->source->command.upper() + " " + l->buf.str();
-
- if (log->method.equals_ci("MEMO") && MSService && l->ci->WhoSends() != NULL)
- MSService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true);
- else if (l->source->c)
- /* Sending a channel message or notice in response to a fantasy command */;
- else if (log->method.equals_ci("MESSAGE") && l->ci->c)
- {
- IRCD->SendPrivmsg(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
- l->ci->WhoSends()->lastmsg = Anope::CurTime;
- }
- else if (log->method.equals_ci("NOTICE") && l->ci->c)
- IRCD->SendNotice(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
- }
- }
-};
-
-MODULE_INIT(CSLog)
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
deleted file mode 100644
index 2acef50f7..000000000
--- a/modules/commands/cs_mode.cpp
+++ /dev/null
@@ -1,1012 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-
-struct ModeLockImpl : ModeLock, Serializable
-{
- ModeLockImpl() : Serializable("ModeLock")
- {
- }
-
- ~ModeLockImpl()
- {
- ChannelInfo *chan = ChannelInfo::Find(ci);
- if (chan)
- {
- ModeLocks *ml = chan->GetExt<ModeLocks>("modelocks");
- if (ml)
- ml->RemoveMLock(this);
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct ModeLocksImpl : ModeLocks
-{
- Serialize::Reference<ChannelInfo> ci;
- Serialize::Checker<ModeList> mlocks;
-
- ModeLocksImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), mlocks("ModeLock")
- {
- }
-
- ~ModeLocksImpl()
- {
- ModeList modelist;
- mlocks->swap(modelist);
- for (ModeList::iterator it = modelist.begin(); it != modelist.end(); ++it)
- {
- ModeLock *ml = *it;
- delete ml;
- }
- }
-
- bool HasMLock(ChannelMode *mode, const Anope::string &param, bool status) const anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
-
- if (ml->name == mode->name && ml->set == status && ml->param == param)
- return true;
- }
-
- return false;
- }
-
- bool SetMLock(ChannelMode *mode, bool status, const Anope::string &param, Anope::string setter, time_t created = Anope::CurTime) anope_override
- {
- if (!mode)
- return false;
-
- RemoveMLock(mode, status, param);
-
- if (setter.empty())
- setter = ci->GetFounder() ? ci->GetFounder()->display : "Unknown";
-
- ModeLock *ml = new ModeLockImpl();
- ml->ci = ci->name;
- ml->set = status;
- ml->name = mode->name;
- ml->param = param;
- ml->setter = setter;
- ml->created = created;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnMLock, MOD_RESULT, (this->ci, ml));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete ml;
- return false;
- }
-
- this->mlocks->push_back(ml);
- return true;
- }
-
- bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string &param = "") anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mode->name)
- {
- // For list or status modes, we must check the parameter
- if (mode->type == MODE_LIST || mode->type == MODE_STATUS)
- if (m->param != param)
- continue;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this->ci, m));
- if (MOD_RESULT == EVENT_STOP)
- break;
-
- delete m;
- return true;
- }
- }
-
- return false;
- }
-
- void RemoveMLock(ModeLock *mlock) anope_override
- {
- ModeList::iterator it = std::find(this->mlocks->begin(), this->mlocks->end(), mlock);
- if (it != this->mlocks->end())
- this->mlocks->erase(it);
- }
-
- void ClearMLock() anope_override
- {
- ModeList ml;
- this->mlocks->swap(ml);
- for (unsigned i = 0; i < ml.size(); ++i)
- delete ml[i];
- }
-
- const ModeList &GetMLock() const anope_override
- {
- return this->mlocks;
- }
-
- std::list<ModeLock *> GetModeLockList(const Anope::string &name) anope_override
- {
- std::list<ModeLock *> mlist;
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
- if (m->name == name)
- mlist.push_back(m);
- }
- return mlist;
- }
-
- const ModeLock *GetMLock(const Anope::string &mname, const Anope::string &param = "") anope_override
- {
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mname && m->param == param)
- return m;
- }
-
- return NULL;
- }
-
- Anope::string GetMLockAsString(bool complete) const anope_override
- {
- Anope::string pos = "+", neg = "-", params;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
-
- if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
- continue;
-
- if (ml->set)
- pos += cm->mchar;
- else
- neg += cm->mchar;
-
- if (complete && ml->set && !ml->param.empty() && cm->type == MODE_PARAM)
- params += " " + ml->param;
- }
-
- if (pos.length() == 1)
- pos.clear();
- if (neg.length() == 1)
- neg.clear();
-
- return pos + neg + params;
- }
-
- void Check() anope_override
- {
- if (this->mlocks->empty())
- ci->Shrink<ModeLocks>("modelocks");
- }
-};
-
-void ModeLockImpl::Serialize(Serialize::Data &data) const
-{
- data["ci"] << this->ci;
- data["set"] << this->set;
- data["name"] << this->name;
- data["param"] << this->param;
- data["setter"] << this->setter;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
-}
-
-Serializable* ModeLockImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci;
-
- data["ci"] >> sci;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- ModeLockImpl *ml;
- if (obj)
- ml = anope_dynamic_static_cast<ModeLockImpl *>(obj);
- else
- {
- ml = new ModeLockImpl();
- ml->ci = ci->name;
- }
-
- data["set"] >> ml->set;
- data["created"] >> ml->created;
- data["setter"] >> ml->setter;
- data["name"] >> ml->name;
- data["param"] >> ml->param;
-
- if (!obj)
- ci->Require<ModeLocksImpl>("modelocks")->mlocks->push_back(ml);
-
- return ml;
-}
-
-class CommandCSMode : public Command
-{
- bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm, bool self)
- {
- if (!ci || !cm || cm->type != MODE_STATUS)
- return false;
-
- return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : ""));
- }
-
- void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
- const Anope::string &subcommand = params[2];
- const Anope::string &param = params.size() > 3 ? params[3] : "";
-
- bool override = !source.AccessFor(ci).HasPriv("MODE");
- ModeLocks *modelocks = ci->Require<ModeLocks>("modelocks");
-
- if (Anope::ReadOnly && !subcommand.equals_ci("LIST"))
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty())
- {
- /* If setting, remove the existing locks */
- if (subcommand.equals_ci("SET"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(); it != mlocks.end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (cm && cm->CanSet(source.GetUser()))
- modelocks->RemoveMLock(cm, ml->set, ml->param);
- }
- }
-
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- Anope::string pos = "+", neg = "-", pos_params, neg_params;
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (((cm->type == MODE_STATUS || cm->type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- else if (cm->type == MODE_LIST && ci->c && IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) >= IRCD->GetMaxListFor(ci->c))
- source.Reply(_("List for mode %c is full."), cm->mchar);
- else if (modelocks->GetMLock().size() >= Config->GetModule(this->owner)->Get<unsigned>("max", "32"))
- source.Reply(_("The mode lock list of \002%s\002 is full."), ci->name.c_str());
- else
- {
- modelocks->SetMLock(cm, adding, mode_param, source.GetNick());
-
- if (adding)
- {
- pos += cm->mchar;
- if (!mode_param.empty())
- pos_params += " " + mode_param;
- }
- else
- {
- neg += cm->mchar;
- if (!mode_param.empty())
- neg_params += " " + mode_param;
- }
- }
- }
- }
-
- if (pos == "+")
- pos.clear();
- if (neg == "-")
- neg.clear();
- Anope::string reply = pos + neg + pos_params + neg_params;
-
- if (!reply.empty())
- {
- source.Reply(_("%s locked on %s."), reply.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << reply;
- }
- else if (needreply)
- source.Reply(_("Nothing to do."));
-
- if (ci->c)
- ci->c->CheckModes();
- }
- else if (subcommand.equals_ci("DEL") && !param.empty())
- {
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (cm->type != MODE_REGULAR && !sep.GetToken(mode_param))
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- else
- {
- if (modelocks->RemoveMLock(cm, adding, mode_param))
- {
- if (!mode_param.empty())
- mode_param = " " + mode_param;
- source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->mchar, mode_param.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unlock " << (adding ? '+' : '-') << cm->mchar << mode_param;
- }
- else
- source.Reply(_("%c%c is not locked on %s."), adding == 1 ? '+' : '-', cm->mchar, ci->name.c_str());
- }
- }
- }
-
- if (needreply)
- source.Reply(_("Nothing to do."));
- }
- else if (subcommand.equals_ci("LIST"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- if (mlocks.empty())
- {
- source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
- }
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mode")).AddColumn(_("Param")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Mode"] = Anope::printf("%c%c", ml->set ? '+' : '-', cm->mchar);
- entry["Param"] = ml->param;
- entry["Creator"] = ml->setter;
- entry["Created"] = Anope::strftime(ml->created, NULL, true);
- list.AddEntry(entry);
- }
-
- source.Reply(_("Mode locks for %s:"), ci->name.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else
- this->OnSyntaxError(source, subcommand);
- }
-
- void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
-
- bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/administration");
- bool can_override = source.HasPriv("chanserv/administration");
-
- spacesepstream sep(params.size() > 3 ? params[3] : "");
- Anope::string modes = params[2], param;
-
- bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/administration");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2] << (params.size() > 3 ? " " + params[3] : "");
-
- int adding = -1;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- case '*':
- if (adding == -1 || !has_access)
- break;
- for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j)
- {
- ChannelMode *cm = ModeManager::GetChannelModes()[j];
-
- if (!u || cm->CanSet(u) || can_override)
- {
- if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM))
- {
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- }
- }
- }
- break;
- default:
- if (adding == -1)
- break;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm || (u && !cm->CanSet(u) && !can_override))
- continue;
- switch (cm->type)
- {
- case MODE_REGULAR:
- if (!has_access)
- break;
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_PARAM:
- if (!has_access)
- break;
- if (adding && !sep.GetToken(param))
- break;
- if (adding)
- ci->c->SetMode(NULL, cm, param);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_STATUS:
- {
- if (!sep.GetToken(param))
- param = source.GetNick();
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (param.find_first_of("*?") != Anope::string::npos)
- {
- if (!this->CanSet(source, ci, cm, false) && !can_override)
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
-
- for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- AccessGroup targ_access = ci->AccessFor(uc->user);
-
- if (uc->user->IsProtected() || (ci->HasExt("PEACE") && targ_access >= u_access && !can_override))
- {
- source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
- continue;
- }
-
- if (Anope::Match(uc->user->GetMask(), param))
- {
- if (adding)
- ci->c->SetMode(NULL, cm, uc->user->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, uc->user->GetUID());
- }
- }
- }
- else
- {
- User *target = User::Find(param, true);
- if (target == NULL)
- {
- source.Reply(NICK_X_NOT_IN_USE, param.c_str());
- break;
- }
-
- if (!this->CanSet(source, ci, cm, source.GetUser() == target) && !can_override)
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
-
- if (source.GetUser() != target)
- {
- AccessGroup targ_access = ci->AccessFor(target);
- if (ci->HasExt("PEACE") && targ_access >= u_access && !can_override)
- {
- source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
- break;
- }
- else if (target->IsProtected())
- {
- source.Reply(ACCESS_DENIED);
- break;
- }
- }
-
- if (adding)
- ci->c->SetMode(NULL, cm, target->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, target->GetUID());
- }
- break;
- }
- case MODE_LIST:
- if (!has_access)
- break;
- if (!sep.GetToken(param))
- break;
- if (adding)
- {
- if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
- ci->c->SetMode(NULL, cm, param);
- }
- else
- {
- std::vector<Anope::string> v = ci->c->GetModeList(cm->name);
- for (unsigned j = 0; j < v.size(); ++j)
- if (Anope::Match(v[j], param))
- ci->c->RemoveMode(NULL, cm, v[j]);
- }
- }
- }
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-*");
- this->DoSet(source, ci, new_params);
- return;
- }
-
- ChannelMode *cm;
- if (param.length() == 1)
- cm = ModeManager::FindChannelModeByChar(param[0]);
- else
- {
- cm = ModeManager::FindChannelModeByName(param.upper());
- if (!cm)
- cm = ModeManager::FindChannelModeByName(param.substr(0, param.length() - 1).upper());
- }
-
- if (!cm)
- {
- source.Reply(_("There is no such mode %s."), param.c_str());
- return;
- }
-
- if (cm->type != MODE_STATUS && cm->type != MODE_LIST)
- {
- source.Reply(_("Mode %s is not a status or list mode."), param.c_str());
- return;
- }
-
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-" + stringify(cm->mchar));
- new_params.push_back("*");
- this->DoSet(source, ci, new_params);
- }
-
- public:
- CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 2, 4)
- {
- this->SetDesc(_("Control modes and mode locks on a channel"));
- this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|SET|LIST} [\037what\037]"));
- this->SetSyntax(_("\037channel\037 SET \037modes\037"));
- this->SetSyntax(_("\037channel\037 CLEAR [\037what\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcommand = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!ci)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (subcommand.equals_ci("LOCK") && params.size() > 2)
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoLock(source, ci, params);
- }
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (subcommand.equals_ci("SET") && params.size() > 2)
- this->DoSet(source, ci, params);
- else if (subcommand.equals_ci("CLEAR"))
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoClear(source, ci, params);
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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 \002%s LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
- "If a mode is locked on or off, services will not allow that mode to be changed. The \002SET\002\n"
- "command will clear all existing mode locks and set the new one given, while \002ADD\002 and \002DEL\002\n"
- "modify the existing mode lock.\n"
- "Example:\n"
- " \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n"
- " \n"
- "The \002%s SET\002 command allows you to set modes through services. Wildcards * and ? may\n"
- "be given as parameters for list and status modes.\n"
- "Example:\n"
- " \002MODE #channel SET +v *\002\n"
- " Sets voice status to all users in the channel.\n"
- " \n"
- " \002MODE #channel SET -b ~c:*\n"
- " Clears all extended bans that start with ~c:\n"
- " \n"
- "The \002%s CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be\n"
- "any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If \037what\037\n"
- "is not given then all basic modes are removed."),
- source.command.upper().c_str(), source.command.upper().c_str(), source.command.upper().c_str());
- return true;
- }
-};
-
-static Anope::map<std::pair<bool, Anope::string> > modes;
-
-class CommandCSModes : public Command
-{
- public:
- CommandCSModes(Module *creator) : Command(creator, "chanserv/modes", 1, 2)
- {
- this->SetSyntax(_("\037channel\037 [\037user\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser(),
- *targ = params.size() > 1 ? User::Find(params[1], true) : u;
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!targ)
- {
- if (params.size() > 1)
- source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
- return;
- }
-
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
- else if (!ci->c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci), targ_access = ci->AccessFor(targ);
- const std::pair<bool, Anope::string> &m = modes[source.command];
-
- bool can_override = source.HasPriv("chanserv/administration");
- bool override = false;
-
- if (m.second.empty())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (u == targ ? !u_access.HasPriv(m.second + "ME") : !u_access.HasPriv(m.second))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!override && !m.first && u != targ && (targ->IsProtected() || (ci->HasExt("PEACE") && targ_access >= u_access)))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!ci->c->FindUser(targ))
- {
- source.Reply(NICK_X_NOT_ON_CHAN, targ->nick.c_str(), ci->name.c_str());
- return;
- }
-
- if (m.first)
- ci->c->SetMode(NULL, m.second, targ->GetUID());
- else
- ci->c->RemoveMode(NULL, m.second, targ->GetUID());
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "on " << targ->nick;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (!m.second.empty())
- {
- if (m.first)
- return Anope::printf(Language::Translate(source.GetAccount(), _("Gives you or the specified nick %s status on a channel")), m.second.c_str());
- else
- return Anope::printf(Language::Translate(source.GetAccount(), _("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
- }
- else
- return "";
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (m.second.empty())
- return false;
-
- this->SendSyntax(source);
- source.Reply(" ");
- if (m.first)
- source.Reply(_("Gives %s status to the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will %s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- else
- source.Reply(_("Removes %s status from the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will de%s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- source.Reply(" ");
- source.Reply(_("You must have the %s(ME) privilege on the channel to use this command."), m.second.upper().c_str());
-
- return true;
- }
-};
-
-class CSMode : public Module
-{
- CommandCSMode commandcsmode;
- CommandCSModes commandcsmodes;
- ExtensibleItem<ModeLocksImpl> modelocks;
- Serialize::Type modelocks_type;
-
- public:
- CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsmode(this), commandcsmodes(this),
- modelocks(this, "modelocks"),
- modelocks_type("ModeLock", ModeLockImpl::Unserialize)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- modes.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- const Anope::string &cname = block->Get<const Anope::string>("name"),
- &cmd = block->Get<const Anope::string>("command");
-
- if (cname.empty() || cmd != "chanserv/modes")
- continue;
-
- const Anope::string &set = block->Get<const Anope::string>("set"),
- &unset = block->Get<const Anope::string>("unset");
-
- if (set.empty() && unset.empty())
- continue;
-
- modes[cname] = std::make_pair(!set.empty(), !set.empty() ? set : unset);
- }
- }
-
- void OnCheckModes(Reference<Channel> &c) anope_override
- {
- if (!c || !c->ci)
- return;
-
- ModeLocks *locks = modelocks.Get(c->ci);
- if (locks)
- for (ModeLocks::ModeList::const_iterator it = locks->GetMLock().begin(), it_end = locks->GetMLock().end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- if (cm->type == MODE_REGULAR)
- {
- if (!c->HasMode(cm->name) && ml->set)
- c->SetMode(NULL, cm, "", false);
- else if (c->HasMode(cm->name) && !ml->set)
- c->RemoveMode(NULL, cm, "", false);
- }
- else if (cm->type == MODE_PARAM)
- {
- /* If the channel doesn't have the mode, or it does and it isn't set correctly */
- if (ml->set)
- {
- Anope::string param;
- c->GetParam(cm->name, param);
-
- if (!c->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
- c->SetMode(NULL, cm, ml->param, false);
- }
- else
- {
- if (c->HasMode(cm->name))
- c->RemoveMode(NULL, cm, "", false);
- }
-
- }
- else if (cm->type == MODE_LIST || cm->type == MODE_STATUS)
- {
- if (ml->set)
- c->SetMode(NULL, cm, ml->param, false);
- else
- c->RemoveMode(NULL, cm, ml->param, false);
- }
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- ModeLocks *ml = modelocks.Require(ci);
- Anope::string mlock;
- spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nt"));
- if (sep.GetToken(mlock))
- {
- bool add = true;
- for (unsigned i = 0; i < mlock.length(); ++i)
- {
- if (mlock[i] == '+')
- {
- add = true;
- continue;
- }
-
- if (mlock[i] == '-')
- {
- add = false;
- continue;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
- if (!cm)
- continue;
-
- Anope::string param;
- if (cm->type == MODE_PARAM)
- {
- ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
- if (add || !cmp->minus_no_arg)
- {
- sep.GetToken(param);
- if (param.empty() || !cmp->IsValid(param))
- continue;
- }
- }
- else if (cm->type != MODE_REGULAR)
- {
- sep.GetToken(param);
- if (param.empty())
- continue;
- }
-
- ml->SetMLock(cm, add, param);
- }
- }
- ml->Check();
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!show_hidden)
- return;
-
- ModeLocks *ml = modelocks.Get(ci);
- if (ml)
- info[_("Mode lock")] = ml->GetMLockAsString(true);
- }
-};
-
-MODULE_INIT(CSMode)
diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp
deleted file mode 100644
index 8b73c9f06..000000000
--- a/modules/commands/cs_register.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSRegister : public Command
-{
- public:
- CommandCSRegister(Module *creator) : Command(creator, "chanserv/register", 1, 2)
- {
- this->SetDesc(_("Register a channel"));
- this->SetSyntax(_("\037channel\037 [\037description\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
- unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
-
- User *u = source.GetUser();
- NickCore *nc = source.nc;
- Channel *c = Channel::Find(params[0]);
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (Anope::ReadOnly)
- source.Reply(_("Sorry, channel registration is temporarily disabled."));
- else if (nc->HasExt("UNCONFIRMED"))
- source.Reply(_("You must confirm your account before you can register a channel."));
- else if (chan[0] == '&')
- source.Reply(_("Local channels cannot be registered."));
- else if (chan[0] != '#')
- source.Reply(CHAN_SYMBOL_REQUIRED);
- else if (!IRCD->IsChannelValid(chan))
- source.Reply(CHAN_X_INVALID, chan.c_str());
- else if (!c && u)
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- else if (ci)
- source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
- else if (c && u && !c->HasUserStatus(u, "OP"))
- source.Reply(_("You must be a channel operator to register the channel."));
- else if (maxregistered && nc->channelcount >= maxregistered && !source.HasPriv("chanserv/no-register-limit"))
- source.Reply(nc->channelcount > maxregistered ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, maxregistered);
- else
- {
- ci = new ChannelInfo(chan);
- ci->SetFounder(nc);
- ci->desc = chdesc;
-
- if (c && !c->topic.empty())
- {
- ci->last_topic = c->topic;
- ci->last_topic_setter = c->topic_setter;
- ci->last_topic_time = c->topic_time;
- }
- else
- ci->last_topic_setter = source.service->nick;
-
- Log(LOG_COMMAND, source, this, ci);
- source.Reply(_("Channel \002%s\002 registered under your account: %s"), chan.c_str(), nc->display.c_str());
-
- FOREACH_MOD(OnChanRegistered, (ci));
-
- /* Implement new mode lock */
- if (c)
- {
- c->CheckModes();
- if (u)
- c->SetCorrectModes(u, true);
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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 is optional, is a\n"
- "general description of the channel's purpose.\n"
- " \n"
- "When you register a channel, you are recorded as the\n"
- "\"founder\" of the channel. The channel founder is allowed\n"
- "to change all of the channel settings for the channel;\n"
- "%s will also automatically give the founder\n"
- "channel-operator privileges when s/he enters the channel."),
- source.service->nick.c_str(), source.service->nick.c_str());
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/access", bi, cmd))
- source.Reply(_(" \n"
- "See the \002%s\002 command (\002%s%s HELP ACCESS\002) for\n"
- "information on giving a subset of these privileges to\n"
- "other channel users.\n"), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
- source.Reply(_(" \n"
- "NOTICE: In order to register a channel, you must have\n"
- "first registered your nickname."));
- return true;
- }
-};
-
-
-class CSRegister : public Module
-{
- CommandCSRegister commandcsregister;
-
- public:
- CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsregister(this)
- {
- }
-};
-
-MODULE_INIT(CSRegister)
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
deleted file mode 100644
index fb58f9efd..000000000
--- a/modules/commands/cs_set.cpp
+++ /dev/null
@@ -1,1356 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-
-class CommandCSSet : public Command
-{
- public:
- CommandCSSet(Module *creator) : Command(creator, "chanserv/set", 2, 3)
- {
- this->SetDesc(_("Set channel options and information"));
- this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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;
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> c("Command", info.name);
-
- // XXX dup
- if (!c)
- continue;
- else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
- continue;
- else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- source.command = it->first;
- c->OnServHelp(source);
- }
- }
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
- return true;
- }
-};
-
-class CommandCSSetAutoOp : public Command
-{
- public:
- CommandCSSetAutoOp(Module *creator, const Anope::string &cname = "chanserv/set/autoop") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Should services automatically give status to users"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable autoop";
- ci->Shrink<bool>("NOAUTOOP");
- source.Reply(_("Services will now automatically give modes to users in \002%s\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable autoop";
- ci->Extend<bool>("NOAUTOOP");
- source.Reply(_("Services will no longer automatically give modes to users in \002%s\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "AUTOOP");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables %s's autoop feature for a\n"
- "channel. When disabled, users who join the channel will\n"
- "not automatically gain any status from %s."), source.service->nick.c_str(),
- source.service->nick.c_str(), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetBanType : public Command
-{
- public:
- CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set how Services make bans on the channel"));
- this->SetSyntax(_("\037channel\037 \037bantype\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- try
- {
- int16_t new_type = convertTo<int16_t>(params[1]);
- if (new_type < 0 || new_type > 3)
- throw ConvertException("Invalid range");
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the ban type to " << new_type;
- ci->bantype = new_type;
- source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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"
- " \n"
- "0: ban in the form *!user@host\n"
- "1: ban in the form *!*user@host\n"
- "2: ban in the form *!*@host\n"
- "3: ban in the form *!*user@*.domain"), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetDescription : public Command
-{
- public:
- CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description") : Command(creator, cname, 1, 2)
- {
- this->SetDesc(_("Set the channel description"));
- this->SetSyntax(_("\037channel\037 [\037description\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!param.empty())
- {
- ci->desc = param;
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the description to " << ci->desc;
- source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
- }
- else
- {
- ci->desc.clear();
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset the description";
- source.Reply(_("Description of %s unset."), ci->name.c_str());
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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;
- }
-};
-
-class CommandCSSetFounder : public Command
-{
- public:
- CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set the founder of a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(params[1]);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
- return;
- }
-
- NickCore *nc = na->nc;
- unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
- if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit"))
- {
- source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
- return;
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display;
-
- ci->SetFounder(nc);
-
- source.Reply(_("Founder of \002%s\002 changed to \002%s\002."), ci->name.c_str(), na->nick.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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;
- }
-};
-
-class CommandCSSetKeepModes : public Command
-{
- public:
- CommandCSSetKeepModes(Module *creator, const Anope::string &cname = "chanserv/set/keepmodes") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Retain modes when channel is not in use"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keep modes";
- ci->Extend<bool>("CS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002on\002."), ci->name.c_str());
- if (ci->c)
- ci->last_modes = ci->c->GetModes();
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keep modes";
- ci->Shrink<bool>("CS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002off\002."), ci->name.c_str());
- ci->last_modes.clear();
- }
- else
- this->OnSyntaxError(source, "KEEPMODES");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for the given channel. If keep\n"
- "modes is enabled, services will remember modes set on the channel\n"
- "and attempt to re-set them the next time the channel is created."));
- return true;
- }
-};
-
-class CommandCSSetPeace : public Command
-{
- public:
- CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Regulate the use of critical commands"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable peace";
- ci->Extend<bool>("PEACE");
- source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable peace";
- ci->Shrink<bool>("PEACE");
- source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PEACE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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."), source.service->nick.c_str());
- return true;
- }
-};
-
-inline static Anope::string BotModes()
-{
- return Config->GetModule("botserv")->Get<Anope::string>("botmodes",
- Config->GetModule("chanserv")->Get<Anope::string>("botmodes", "o")
- );
-}
-
-class CommandCSSetPersist : public Command
-{
- public:
- CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set the channel as permanent"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
-
- if (params[1].equals_ci("ON"))
- {
- if (!ci->HasExt("PERSIST"))
- {
- ci->Extend<bool>("PERSIST");
-
- /* Channel doesn't exist, create it */
- if (!ci->c)
- {
- bool created;
- Channel *c = Channel::FindOrCreate(ci->name, created);
- if (ci->bi)
- {
- ChannelStatus status(BotModes());
- ci->bi->Join(c, &status);
- }
- if (created)
- c->Sync();
- }
-
- /* Set the perm mode */
- if (cm)
- {
- if (ci->c && !ci->c->HasMode("PERM"))
- ci->c->SetMode(NULL, cm);
- /* Add it to the channels mlock */
- ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
- if (ml)
- ml->SetMLock(cm, true, "", source.GetNick());
- }
- /* No botserv bot, no channel mode, give them ChanServ.
- * Yes, this works fine with no BotServ.
- */
- else if (!ci->bi)
- {
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- if (!ChanServ)
- {
- source.Reply(_("ChanServ is required to enable persist on this network."));
- return;
- }
-
- ChanServ->Assign(NULL, ci);
- if (!ci->c->FindUser(ChanServ))
- {
- ChannelStatus status(BotModes());
- ChanServ->Join(ci->c, &status);
- }
- }
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable persist";
- source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- if (ci->HasExt("PERSIST"))
- {
- ci->Shrink<bool>("PERSIST");
-
- BotInfo *ChanServ = Config->GetClient("ChanServ"),
- *BotServ = Config->GetClient("BotServ");
-
- /* Unset perm mode */
- if (cm)
- {
- if (ci->c && ci->c->HasMode("PERM"))
- ci->c->RemoveMode(NULL, cm);
- /* Remove from mlock */
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- if (ml)
- ml->RemoveMLock(cm, true);
- }
- /* No channel mode, no BotServ, but using ChanServ as the botserv bot
- * which was assigned when persist was set on
- */
- else if (!cm && !BotServ && ci->bi)
- {
- if (!ChanServ)
- {
- source.Reply(_("ChanServ is required to enable persist on this network."));
- return;
- }
-
- /* Unassign bot */
- ChanServ->UnAssign(NULL, ci);
- }
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable persist";
- source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PERSIST");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *BotServ = Config->GetClient("BotServ");
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the persistent channel setting.\n"
- "When persistent is set, the service bot will remain\n"
- "in the channel when it has emptied of users.\n"
- " \n"
- "If your IRCd does not have a permanent (persistent) channel\n"
- "mode you must have a service bot in your channel to\n"
- "set persist on, and it can not be unassigned while persist\n"
- "is on.\n"
- " \n"
- "If this network does not have %s enabled and does\n"
- "not have a permanent channel mode, %s will\n"
- "join your channel when you set persist on (and leave when\n"
- "it has been set off).\n"
- " \n"
- "If your IRCd has a permanent (persistent) channel mode\n"
- "and it is set or unset (for any reason, including MODE LOCK),\n"
- "persist is automatically set and unset for the channel as well.\n"
- "Additionally, services will set or unset this mode when you\n"
- "set persist on or off."), BotServ ? BotServ->nick.c_str() : "BotServ",
- ChanServ ? ChanServ->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandCSSetRestricted : public Command
-{
- public:
- CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Restrict access to the channel"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable restricted";
- ci->Extend<bool>("RESTRICTED");
- source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable restricted";
- ci->Shrink<bool>("RESTRICTED");
- source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "RESTRICTED");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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."));
- return true;
- }
-};
-
-class CommandCSSetSecure : public Command
-{
- public:
- CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Activate security features"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure";
- ci->Extend<bool>("CS_SECURE");
- source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure";
- ci->Shrink<bool>("CS_SECURE");
- source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECURE");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables security features for a\n"
- "channel. When \002SECURE\002 is set, only users who have\n"
- "identified to services, and are not only recognized, will be\n"
- "given access to channels from account-based access entries."));
- return true;
- }
-};
-
-class CommandCSSetSecureFounder : public Command
-{
- public:
- CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Stricter control of channel founder status"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure founder";
- ci->Extend<bool>("SECUREFOUNDER");
- source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure founder";
- ci->Shrink<bool>("SECUREFOUNDER");
- source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECUREFOUNDER");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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 founder and its successor,\n"
- "and not those who have founder level access through\n"
- "the access/qop command."));
- return true;
- }
-};
-
-class CommandCSSetSecureOps : public Command
-{
- public:
- CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Stricter control of chanop status"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure ops";
- ci->Extend<bool>("SECUREOPS");
- source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure ops";
- ci->Shrink<bool>("SECUREOPS");
- source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECUREOPS");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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 access list\n"
- "will not be allowed channel operator status."));
- return true;
- }
-};
-
-class CommandCSSetSignKick : public Command
-{
- public:
- CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Sign kicks that are done with the KICK command"));
- this->SetSyntax(_("\037channel\037 {ON | LEVEL | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- ci->Extend<bool>("SIGNKICK");
- ci->Shrink<bool>("SIGNKICK_LEVEL");
- source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick";
- }
- else if (params[1].equals_ci("LEVEL"))
- {
- ci->Extend<bool>("SIGNKICK_LEVEL");
- ci->Shrink<bool>("SIGNKICK");
- source.Reply(_("Signed kick option for %s is now \002on\002, but depends of the\n"
- "level of the user that is using the command."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick level";
- }
- else if (params[1].equals_ci("OFF"))
- {
- ci->Shrink<bool>("SIGNKICK");
- ci->Shrink<bool>("SIGNKICK_LEVEL");
- source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable sign kick";
- }
- else
- this->OnSyntaxError(source, "SIGNKICK");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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"
- "the \002KICK\002 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."));
- return true;
- }
-};
-
-class CommandCSSetSuccessor : public Command
-{
- public:
- CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor") : Command(creator, cname, 1, 2)
- {
- this->SetDesc(_("Set the successor for a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- NickCore *nc;
-
- if (!param.empty())
- {
- const NickAlias *na = NickAlias::Find(param);
-
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, param.c_str());
- return;
- }
- if (na->nc == ci->GetFounder())
- {
- source.Reply(_("%s cannot be the successor on channel %s as they are the founder."), na->nick.c_str(), ci->name.c_str());
- return;
- }
- nc = na->nc;
- }
- else
- nc = NULL;
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the successor from " << (ci->GetSuccessor() ? ci->GetSuccessor()->display : "(none)") << " to " << (nc ? nc->display : "(none)");
-
- ci->SetSuccessor(nc);
-
- if (nc)
- source.Reply(_("Successor for \002%s\002 changed to \002%s\002."), ci->name.c_str(), nc->display.c_str());
- else
- source.Reply(_("Successor for \002%s\002 unset."), ci->name.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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. The new nickname must be a registered one."));
- unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
- if (max_reg)
- source.Reply(_("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."), max_reg);
- return true;
- }
-};
-
-class CommandCSSetNoexpire : public Command
-{
- public:
- CommandCSSetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2)
- {
- this->SetDesc(_("Prevent the channel from expiring"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (source.permission.empty() && !source.AccessFor(ci).HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to enable noexpire";
- ci->Extend<bool>("CS_NO_EXPIRE");
- source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to disable noexpire";
- ci->Shrink<bool>("CS_NO_EXPIRE");
- source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "NOEXPIRE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- 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;
- }
-};
-
-class CSSet : public Module
-{
- SerializableExtensibleItem<bool> noautoop, peace, securefounder,
- restricted, secure, secureops, signkick, signkick_level, noexpire;
-
- struct KeepModes : SerializableExtensibleItem<bool>
- {
- KeepModes(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleSerialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(s);
- Anope::string modes;
- for (Channel::ModeList::const_iterator it = ci->last_modes.begin(); it != ci->last_modes.end(); ++it)
- {
- if (!modes.empty())
- modes += " ";
- modes += it->first;
- if (!it->second.empty())
- modes += "," + it->second;
- }
- data["last_modes"] << modes;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
- Anope::string modes;
- data["last_modes"] >> modes;
- for (spacesepstream sep(modes); sep.GetToken(modes);)
- {
- size_t c = modes.find(',');
- if (c == Anope::string::npos)
- ci->last_modes.insert(std::make_pair(modes, ""));
- else
- ci->last_modes.insert(std::make_pair(modes.substr(0, c), modes.substr(c + 1)));
- }
- }
- } keep_modes;
-
- struct Persist : SerializableExtensibleItem<bool>
- {
- Persist(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo" || !this->HasExt(e))
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
- if (ci->c)
- return;
-
- bool created;
- Channel *c = Channel::FindOrCreate(ci->name, created);
-
- ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
- if (cm)
- {
- c->SetMode(NULL, cm);
- }
- /* on startup we might not know mode availibity here */
- else if (Me && Me->IsSynced())
- {
- if (!ci->bi)
- {
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- if (ChanServ)
- ChanServ->Assign(NULL, ci);
- }
-
- if (ci->bi && !c->FindUser(ci->bi))
- {
- ChannelStatus status(BotModes());
- ci->bi->Join(c, &status);
- }
- }
-
- if (created)
- c->Sync();
- }
- } persist;
-
- CommandCSSet commandcsset;
- CommandCSSetAutoOp commandcssetautoop;
- CommandCSSetBanType commandcssetbantype;
- CommandCSSetDescription commandcssetdescription;
- CommandCSSetFounder commandcssetfounder;
- CommandCSSetKeepModes commandcssetkeepmodes;
- CommandCSSetPeace commandcssetpeace;
- CommandCSSetPersist commandcssetpersist;
- CommandCSSetRestricted commandcssetrestricted;
- CommandCSSetSecure commandcssetsecure;
- CommandCSSetSecureFounder commandcssetsecurefounder;
- CommandCSSetSecureOps commandcssetsecureops;
- CommandCSSetSignKick commandcssetsignkick;
- CommandCSSetSuccessor commandcssetsuccessor;
- CommandCSSetNoexpire commandcssetnoexpire;
-
- ExtensibleRef<bool> inhabit;
-
- bool persist_lower_ts;
-
- public:
- CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- noautoop(this, "NOAUTOOP"), peace(this, "PEACE"),
- securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
- secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
- signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
- keep_modes(this, "CS_KEEP_MODES"), persist(this, "PERSIST"),
-
- commandcsset(this), commandcssetautoop(this), commandcssetbantype(this),
- commandcssetdescription(this), commandcssetfounder(this), commandcssetkeepmodes(this),
- commandcssetpeace(this), commandcssetpersist(this), commandcssetrestricted(this),
- commandcssetsecure(this), commandcssetsecurefounder(this), commandcssetsecureops(this), commandcssetsignkick(this),
- commandcssetsuccessor(this), commandcssetnoexpire(this),
-
- inhabit("inhabit")
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- persist_lower_ts = conf->GetModule(this)->Get<bool>("persist_lower_ts");
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2");
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (c->ci && keep_modes.HasExt(c->ci))
- {
- Channel::ModeList ml = c->ci->last_modes;
- for (Channel::ModeList::iterator it = ml.begin(); it != ml.end(); ++it)
- c->SetMode(c->ci->WhoSends(), it->first, it->second);
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
- return EVENT_CONTINUE;
-
- if (c->ci->AccessFor(u).empty() && (!c->ci->GetFounder() || u->Account() != c->ci->GetFounder()))
- return EVENT_STOP;
-
- return EVENT_CONTINUE;
- }
-
- void OnDelChan(ChannelInfo *ci) anope_override
- {
- if (ci->c && persist.HasExt(ci))
- ci->c->RemoveMode(ci->WhoSends(), "PERM", "", false);
- persist.Unset(ci);
- }
-
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (c->ci)
- {
- /* Channel mode +P or so was set, mark this channel as persistent */
- if (mode->name == "PERM")
- persist.Set(c->ci, true);
-
- if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
- c->ci->last_modes = c->GetModes();
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (mode->name == "PERM")
- {
- if (c->ci)
- persist.Unset(c->ci);
- }
-
- if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
- c->ci->last_modes = c->GetModes();
-
- return EVENT_CONTINUE;
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->time_registered)
- {
- Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
- c->creation_time = c->ci->time_registered;
- IRCD->SendChannel(c);
- c->Reset();
- }
- }
-
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
- {
- if (chan->ci)
- {
- if (noautoop.HasExt(chan->ci))
- give_modes = false;
- if (secureops.HasExt(chan->ci))
- // This overrides what chanserv does because it is loaded after chanserv
- take_modes = true;
- }
- }
-
- void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
- {
- if (noexpire.HasExt(ci))
- expire = false;
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (peace.HasExt(ci))
- info.AddOption(_("Peace"));
- if (restricted.HasExt(ci))
- info.AddOption(_("Restricted access"));
- if (secure.HasExt(ci))
- info.AddOption(_("Security"));
- if (securefounder.HasExt(ci))
- info.AddOption(_("Secure founder"));
- if (secureops.HasExt(ci))
- info.AddOption(_("Secure ops"));
- if (signkick.HasExt(ci) || signkick_level.HasExt(ci))
- info.AddOption(_("Signed kicks"));
- if (persist.HasExt(ci))
- info.AddOption(_("Persistent"));
- if (noexpire.HasExt(ci))
- info.AddOption(_("No expire"));
- if (keep_modes.HasExt(ci))
- info.AddOption(_("Keep modes"));
- if (noautoop.HasExt(ci))
- info.AddOption(_("No auto-op"));
- }
-};
-
-MODULE_INIT(CSSet)
diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp
deleted file mode 100644
index 038bd7cb5..000000000
--- a/modules/commands/cs_set_misc.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- *
- * (C) 2003-2016 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/set_misc.h"
-
-static Module *me;
-
-static Anope::map<Anope::string> descriptions;
-
-struct CSMiscData;
-static Anope::map<ExtensibleItem<CSMiscData> *> items;
-
-static ExtensibleItem<CSMiscData> *GetItem(const Anope::string &name)
-{
- ExtensibleItem<CSMiscData>* &it = items[name];
- if (!it)
- try
- {
- it = new ExtensibleItem<CSMiscData>(me, name);
- }
- catch (const ModuleException &) { }
- return it;
-}
-
-struct CSMiscData : MiscData, Serializable
-{
- CSMiscData(Extensible *obj) : Serializable("CSMiscData") { }
-
- CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : Serializable("CSMiscData")
- {
- object = c->name;
- name = n;
- data = d;
- }
-
- void Serialize(Serialize::Data &sdata) const anope_override
- {
- sdata["ci"] << this->object;
- sdata["name"] << this->name;
- sdata["data"] << this->data;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string sci, sname, sdata;
-
- data["ci"] >> sci;
- data["name"] >> sname;
- data["data"] >> sdata;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (ci == NULL)
- return NULL;
-
- CSMiscData *d = NULL;
- if (obj)
- {
- d = anope_dynamic_static_cast<CSMiscData *>(obj);
- d->object = ci->name;
- data["name"] >> d->name;
- data["data"] >> d->data;
- }
- else
- {
- ExtensibleItem<CSMiscData> *item = GetItem(sname);
- if (item)
- d = item->Set(ci, CSMiscData(ci, sname, sdata));
- }
-
- return d;
- }
-};
-
-static Anope::string GetAttribute(const Anope::string &command)
-{
- size_t sp = command.rfind(' ');
- if (sp != Anope::string::npos)
- return command.substr(sp + 1);
- return command;
-}
-
-class CommandCSSetMisc : public Command
-{
- public:
- CommandCSSetMisc(Module *creator, const Anope::string &cname = "chanserv/set/misc") : Command(creator, cname, 1, 2)
- {
- this->SetSyntax(_("\037channel\037 [\037parameters\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Anope::string scommand = GetAttribute(source.command);
- Anope::string key = "cs_set_misc:" + scommand;
- ExtensibleItem<CSMiscData> *item = GetItem(key);
- if (item == NULL)
- return;
-
- if (!param.empty())
- {
- item->Set(ci, CSMiscData(ci, key, param));
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change it to " << param;
- source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str());
- }
- else
- {
- item->Unset(ci);
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset it";
- source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str());
- }
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (descriptions.count(source.command))
- {
- this->SetDesc(descriptions[source.command]);
- Command::OnServHelp(source);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (descriptions.count(source.command))
- {
- source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
- return true;
- }
- return false;
- }
-};
-
-class CSSetMisc : public Module
-{
- CommandCSSetMisc commandcssetmisc;
- Serialize::Type csmiscdata_type;
-
- public:
- CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssetmisc(this), csmiscdata_type("CSMiscData", CSMiscData::Unserialize)
- {
- me = this;
- }
-
- ~CSSetMisc()
- {
- for (Anope::map<ExtensibleItem<CSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- delete it->second;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- descriptions.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- if (block->Get<const Anope::string>("command") != "chanserv/set/misc")
- continue;
-
- Anope::string cname = block->Get<const Anope::string>("name");
- Anope::string desc = block->Get<const Anope::string>("misc_description");
-
- if (cname.empty() || desc.empty())
- continue;
-
- descriptions[cname] = desc;
- }
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool) anope_override
- {
- for (Anope::map<ExtensibleItem<CSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- {
- ExtensibleItem<CSMiscData> *e = it->second;
- MiscData *data = e->Get(ci);
-
- if (data != NULL)
- info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
- }
- }
-};
-
-MODULE_INIT(CSSetMisc)
diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp
deleted file mode 100644
index b984d5952..000000000
--- a/modules/commands/cs_status.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 CommandCSStatus : public Command
-{
-public:
- CommandCSStatus(Module *creator) : Command(creator, "chanserv/status", 1, 2)
- {
- this->SetDesc(_("Find a user's status on a channel"));
- this->SetSyntax(_("\037channel\037 [\037user\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
-
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- else if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/auspex"))
- source.Reply(ACCESS_DENIED);
- else
- {
- Anope::string nick = source.GetNick();
- if (params.size() > 1)
- nick = params[1];
-
- AccessGroup ag;
- User *u = User::Find(nick, true);
- NickAlias *na = NULL;
- if (u != NULL)
- ag = ci->AccessFor(u);
- else
- {
- na = NickAlias::Find(nick);
- if (na != NULL)
- ag = ci->AccessFor(na->nc);
- }
-
- if (ag.super_admin)
- source.Reply(_("\002%s\002 is a super administrator."), nick.c_str());
- else if (ag.founder)
- source.Reply(_("\002%s\002 is the founder of \002%s\002."), nick.c_str(), ci->name.c_str());
- else if (ag.empty())
- source.Reply(_("\002%s\002 has no access on \002%s\002."), nick.c_str(), ci->name.c_str());
- else
- {
- source.Reply(_("Access for \002%s\002 on \002%s\002:"), nick.c_str(), ci->name.c_str());
-
- for (unsigned i = 0; i < ag.paths.size(); ++i)
- {
- ChanAccess::Path &p = ag.paths[i];
-
- if (p.empty())
- continue;
-
- if (p.size() == 1)
- {
- ChanAccess *acc = p[0];
-
- source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->Mask().c_str(), acc->AccessSerialize().c_str());
- }
- else
- {
- ChanAccess *first = p[0];
- ChanAccess *acc = p[p.size() - 1];
-
- source.Reply(_("\002%s\002 matches access entry %s (from entry %s), which has privilege %s."), nick.c_str(), acc->Mask().c_str(), first->Mask().c_str(), acc->AccessSerialize().c_str());
- }
- }
- }
-
- for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
- {
- AutoKick *autokick = ci->GetAkick(j);
-
- if (autokick->nc)
- {
- if (na && *autokick->nc == na->nc)
- source.Reply(_("\002%s\002 is on the auto kick list of \002%s\002 (%s)."), na->nc->display.c_str(), ci->name.c_str(), autokick->reason.c_str());
- }
- else if (u != NULL)
- {
- Entry akick_mask("", autokick->mask);
- if (akick_mask.Matches(u))
- source.Reply(_("\002%s\002 matches auto kick entry %s on \002%s\002 (%s)."), u->nick.c_str(), autokick->mask.c_str(), ci->name.c_str(), autokick->reason.c_str());
- }
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command tells you what a users access is on a channel\n"
- "and what access entries, if any, they match. Additionally it\n"
- "will tell you of any auto kick entries they match. Usage of\n"
- "this command is limited to users who have the ability to modify\n"
- "access entries on the channel."));
- return true;
- }
-};
-
-class CSStatus : public Module
-{
- CommandCSStatus commandcsstatus;
-
- public:
- CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsstatus(this)
- {
- }
-};
-
-MODULE_INIT(CSStatus)
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp
deleted file mode 100644
index 6bab44207..000000000
--- a/modules/commands/cs_suspend.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/suspend.h"
-
-struct CSSuspendInfo : SuspendInfo, Serializable
-{
- CSSuspendInfo(Extensible *) : Serializable("CSSuspendInfo") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["chan"] << what;
- data["by"] << by;
- data["reason"] << reason;
- data["time"] << when;
- data["expires"] << expires;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string schan;
- data["chan"] >> schan;
-
- CSSuspendInfo *si;
- if (obj)
- si = anope_dynamic_static_cast<CSSuspendInfo *>(obj);
- else
- {
- ChannelInfo *ci = ChannelInfo::Find(schan);
- if (!ci)
- return NULL;
- si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
- data["chan"] >> si->what;
- }
-
- data["by"] >> si->by;
- data["reason"] >> si->reason;
- data["time"] >> si->when;
- data["expires"] >> si->expires;
- return si;
- }
-};
-
-class CommandCSSuspend : public Command
-{
- public:
- CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 2, 3)
- {
- this->SetDesc(_("Prevent a channel from being used preserving channel data and settings"));
- this->SetSyntax(_("\037channel\037 [+\037expiry\037] [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- Anope::string expiry = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire");
-
- if (!expiry.empty() && expiry[0] != '+')
- {
- reason = expiry + " " + reason;
- reason.trim();
- expiry.clear();
- }
- else
- {
- expiry_secs = Anope::DoTime(expiry);
- if (expiry_secs == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- if (ci->HasExt("CS_SUSPENDED"))
- {
- source.Reply(_("\002%s\002 is already suspended."), ci->name.c_str());
- return;
- }
-
- CSSuspendInfo *si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
- si->what = ci->name;
- si->by = source.GetNick();
- si->reason = reason;
- si->when = Anope::CurTime;
- si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
-
- if (ci->c)
- {
- std::vector<User *> users;
-
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
- if (!user->HasMode("OPER") && user->server != Me)
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- ci->c->Kick(NULL, users[i], "%s", !reason.empty() ? reason.c_str() : Language::Translate(users[i], _("This channel has been suspended.")));
- }
-
- Log(LOG_ADMIN, source, this, ci) << "(" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
- source.Reply(_("Channel \002%s\002 is now suspended."), ci->name.c_str());
-
- FOREACH_MOD(OnChanSuspend, (ci));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Disallows anyone from using the given channel.\n"
- "May be cancelled by using the \002UNSUSPEND\002\n"
- "command to preserve all previous channel data/settings.\n"
- "If an expiry is given the channel will be unsuspended after\n"
- "that period of time, else the default expiry from the\n"
- "configuration is used.\n"
- " \n"
- "Reason may be required on certain networks."));
- return true;
- }
-};
-
-class CommandCSUnSuspend : public Command
-{
- public:
- CommandCSUnSuspend(Module *creator) : Command(creator, "chanserv/unsuspend", 1, 1)
- {
- this->SetDesc(_("Releases a suspended channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- /* Only UNSUSPEND already suspended channels */
- CSSuspendInfo *si = ci->GetExt<CSSuspendInfo>("CS_SUSPENDED");
- if (!si)
- {
- source.Reply(_("Channel \002%s\002 isn't suspended."), ci->name.c_str());
- return;
- }
-
- Log(LOG_ADMIN, source, this, ci) << "which was suspended by " << si->by << " for: " << (!si->reason.empty() ? si->reason : "No reason");
-
- ci->Shrink<CSSuspendInfo>("CS_SUSPENDED");
-
- source.Reply(_("Channel \002%s\002 is now released."), ci->name.c_str());
-
- FOREACH_MOD(OnChanUnsuspend, (ci));
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Releases a suspended channel. All data and settings\n"
- "are preserved from before the suspension."));
- return true;
- }
-};
-
-class CSSuspend : public Module
-{
- CommandCSSuspend commandcssuspend;
- CommandCSUnSuspend commandcsunsuspend;
- ExtensibleItem<CSSuspendInfo> suspend;
- Serialize::Type suspend_type;
- std::vector<Anope::string> show;
-
- struct trim
- {
- Anope::string operator()(Anope::string s) const
- {
- return s.trim();
- }
- };
-
- bool Show(CommandSource &source, const Anope::string &what) const
- {
- return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
- }
-
- public:
- CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssuspend(this), commandcsunsuspend(this), suspend(this, "CS_SUSPENDED"),
- suspend_type("CSSuspendInfo", CSSuspendInfo::Unserialize)
- {
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (!si)
- return;
-
- if (show_hidden || Show(source, "suspended"))
- info[_("Suspended")] = _("This channel is \002suspended\002.");
- if (!si->by.empty() && (show_hidden || Show(source, "by")))
- info[_("Suspended by")] = si->by;
- if (!si->reason.empty() && (show_hidden || Show(source, "reason")))
- info[_("Suspend reason")] = si->reason;
- if (si->when && (show_hidden || Show(source, "on")))
- info[_("Suspended on")] = Anope::strftime(si->when, source.GetAccount());
- if (si->expires && (show_hidden || Show(source, "expires")))
- info[_("Suspension expires")] = Anope::strftime(si->expires, source.GetAccount());
- }
-
- void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (!si)
- return;
-
- expire = false;
-
- if (!si->expires)
- return;
-
- if (si->expires < Anope::CurTime)
- {
- ci->last_used = Anope::CurTime;
- suspend.Unset(ci);
-
- Log(this) << "Expiring suspend for " << ci->name;
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (u->HasMode("OPER") || !c->ci || !suspend.HasExt(c->ci))
- return EVENT_CONTINUE;
-
- reason = Language::Translate(u, _("This channel may not be used."));
- return EVENT_STOP;
- }
-
- EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (si && !source.HasCommand("chanserv/drop"))
- {
- source.Reply(CHAN_X_SUSPENDED, ci->name.c_str());
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSSuspend)
diff --git a/modules/commands/cs_sync.cpp b/modules/commands/cs_sync.cpp
deleted file mode 100644
index a60e24cab..000000000
--- a/modules/commands/cs_sync.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 CommandCSSync : public Command
-{
- public:
- CommandCSSync(Module *creator) : Command(creator, "chanserv/sync", 1, 1)
- {
- this->SetDesc(_("Sync users channel modes"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (ci->c == NULL)
- source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/administration");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
-
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- ci->c->SetCorrectModes(it->second->user, true);
-
- source.Reply(_("All user modes on \002%s\002 have been synced."), ci->name.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &params) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Syncs all modes set on users on the channel with the modes\n"
- "they should have based on their access."));
- return true;
- }
-};
-
-class CSSync : public Module
-{
- CommandCSSync commandcssync;
- public:
- CSSync(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssync(this)
- {
-
- }
-};
-
-MODULE_INIT(CSSync)
diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp
deleted file mode 100644
index 2db37a456..000000000
--- a/modules/commands/cs_topic.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-
-class CommandCSSetKeepTopic : public Command
-{
- public:
- CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Retain topic when channel is not in use"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic";
- ci->Extend<bool>("KEEPTOPIC");
- source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic";
- ci->Shrink<bool>("KEEPTOPIC");
- source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "KEEPTOPIC");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002topic retention\002 option for a\n"
- "channel. When \002%s\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."), source.command.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandCSTopic : public Command
-{
- ExtensibleRef<bool> topiclock;
-
- void Lock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, "topiclock on"));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- topiclock->Set(ci, true);
- source.Reply(_("Topic lock option for %s is now \002on\002."), ci->name.c_str());
- }
-
- void Unlock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, "topiclock off"));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- topiclock->Unset(ci);
- source.Reply(_("Topic lock option for %s is now \002off\002."), ci->name.c_str());
- }
-
- void Set(CommandSource &source, ChannelInfo *ci, const Anope::string &topic)
- {
- bool has_topiclock = topiclock->HasExt(ci);
- topiclock->Unset(ci);
- ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime);
- if (has_topiclock)
- topiclock->Set(ci);
-
- bool override = !source.AccessFor(ci).HasPriv("TOPIC");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : "");
- }
-
- void Append(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &topic = params[2];
-
- Anope::string new_topic;
- if (!ci->c->topic.empty())
- {
- new_topic = ci->c->topic + " " + topic;
- ci->last_topic.clear();
- }
- else
- new_topic = topic;
-
- this->Set(source, ci, new_topic);
- }
-
- public:
- CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3),
- topiclock("TOPICLOCK")
- {
- this->SetDesc(_("Manipulate the topic of the specified channel"));
- this->SetSyntax(_("\037channel\037 [SET] [\037topic\037]"));
- this->SetSyntax(_("\037channel\037 APPEND \037topic\037"));
- this->SetSyntax(_("\037channel\037 [UNLOCK|LOCK]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcmd = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (!source.AccessFor(ci).HasPriv("TOPIC") && !source.HasCommand("chanserv/topic"))
- source.Reply(ACCESS_DENIED);
- else if (subcmd.equals_ci("LOCK"))
- this->Lock(source, ci, params);
- else if (subcmd.equals_ci("UNLOCK"))
- this->Unlock(source, ci, params);
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- else if (subcmd.equals_ci("APPEND") && params.size() > 2)
- this->Append(source, ci, params);
- else
- {
- Anope::string topic;
- if (subcmd.equals_ci("SET"))
- {
- topic = params.size() > 2 ? params[2] : "";
- }
- else
- {
- topic = subcmd;
- if (params.size() > 2)
- topic += " " + params[2];
- }
- this->Set(source, ci, topic);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows manipulating the topic of the specified channel.\n"
- "The \002SET\002 command changes the topic of the channel to the given topic\n"
- "or unsets the topic if no topic is given. The \002APPEND\002 command appends\n"
- "the given topic to the existing topic.\n"
- " \n"
- "\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock. When\n"
- "topic lock is set, the channel topic will be unchangeable by users who do not have\n"
- "the \002TOPIC\002 privilege."));
- return true;
- }
-};
-
-class CSTopic : public Module
-{
- CommandCSTopic commandcstopic;
- CommandCSSetKeepTopic commandcssetkeeptopic;
-
- SerializableExtensibleItem<bool> topiclock, keeptopic;
-
- public:
- CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcstopic(this), commandcssetkeeptopic(this), topiclock(this, "TOPICLOCK"), keeptopic(this, "KEEPTOPIC")
- {
-
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (c->ci)
- {
- /* Update channel topic */
- if ((topiclock.HasExt(c->ci) || keeptopic.HasExt(c->ci)) && c->ci->last_topic != c->topic)
- {
- c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime);
- }
- }
- }
-
- void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
- {
- if (!c->ci)
- return;
-
- /* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
- * allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
- * This desyncs what is really set with what we have stored, and we end up resetting the topic often when
- * it is not required
- */
- if (topiclock.HasExt(c->ci) && c->ci->last_topic != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC")))
- {
- c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time);
- }
- else
- {
- c->ci->last_topic = c->topic;
- c->ci->last_topic_setter = c->topic_setter;
- c->ci->last_topic_time = c->topic_ts;
- }
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (keeptopic.HasExt(ci))
- info.AddOption(_("Topic retention"));
- if (topiclock.HasExt(ci))
- info.AddOption(_("Topic lock"));
-
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
- if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode("SECRET")))))
- {
- info[_("Last topic")] = ci->last_topic;
- info[_("Topic set by")] = ci->last_topic_setter;
- }
- }
-};
-
-MODULE_INIT(CSTopic)
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
deleted file mode 100644
index 3a6c4d484..000000000
--- a/modules/commands/cs_xop.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- std::vector<Anope::string> order;
- std::map<Anope::string, std::vector<Anope::string> > permissions;
-}
-
-class XOPChanAccess : public ChanAccess
-{
- public:
- Anope::string type;
-
- XOPChanAccess(AccessProvider *p) : ChanAccess(p)
- {
- }
-
- bool HasPriv(const Anope::string &priv) const anope_override
- {
- for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it)
- {
- const std::vector<Anope::string> &privs = permissions[*it];
- if (std::find(privs.begin(), privs.end(), priv) != privs.end())
- return true;
- }
- return false;
- }
-
- Anope::string AccessSerialize() const
- {
- return this->type;
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- this->type = data;
- }
-
- static Anope::string DetermineLevel(const ChanAccess *access)
- {
- if (access->provider->name == "access/xop")
- {
- const XOPChanAccess *xaccess = anope_dynamic_static_cast<const XOPChanAccess *>(access);
- return xaccess->type;
- }
- else
- {
- std::map<Anope::string, int> count;
-
- for (std::map<Anope::string, std::vector<Anope::string> >::const_iterator it = permissions.begin(), it_end = permissions.end(); it != it_end; ++it)
- {
- int &c = count[it->first];
- const std::vector<Anope::string> &perms = it->second;
- for (unsigned i = 0; i < perms.size(); ++i)
- if (access->HasPriv(perms[i]))
- ++c;
- }
-
- Anope::string max;
- int maxn = 0;
- for (std::map<Anope::string, int>::iterator it = count.begin(), it_end = count.end(); it != it_end; ++it)
- if (it->second > maxn)
- {
- maxn = it->second;
- max = it->first;
- }
-
- return max;
- }
- }
-};
-
-class XOPAccessProvider : public AccessProvider
-{
- public:
- XOPAccessProvider(Module *o) : AccessProvider(o, "access/xop")
- {
- }
-
- ChanAccess *Create() anope_override
- {
- return new XOPChanAccess(this);
- }
-};
-
-class CommandCSXOP : public Command
-{
- private:
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- XOPChanAccess tmp_access(NULL);
- tmp_access.ci = ci;
- tmp_access.type = source.command.upper();
-
- AccessGroup access = source.AccessFor(ci);
- const ChanAccess *highest = access.Highest();
- bool override = false;
- const NickAlias *na = NULL;
-
- std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
- access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
-
- if (!access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- const ChanAccess *a = ci->GetAccess(i);
-
- if ((na && na->nc == a->GetAccount()) || mask.equals_ci(a->Mask()))
- {
- if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- delete ci->EraseAccess(i);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/xop");
- if (!provider)
- return;
- XOPChanAccess *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create());
- acc->SetMask(mask, ci);
- acc->creator = source.GetNick();
- acc->type = source.command.upper();
- acc->last_seen = 0;
- acc->created = Anope::CurTime;
- ci->AddAccess(acc);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
-
- FOREACH_MOD(OnAccessAdd, (ci, source, acc));
- source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask().c_str(), ci->name.c_str(), source.command.c_str());
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- NickCore *nc = source.nc;
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- XOPChanAccess tmp_access(NULL);
- tmp_access.ci = ci;
- tmp_access.type = source.command.upper();
-
- AccessGroup access = source.AccessFor(ci);
- const ChanAccess *highest = access.Highest();
- bool override = false;
-
- if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask))
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
- access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
-
- if (!mask.equals_ci(nc->display) && !access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class XOPDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- Anope::string nicks;
- bool override;
- public:
- 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."), ci->name.c_str(), source.command.c_str());
- else
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << nicks;
-
- if (deleted == 1)
- source.Reply(_("Deleted one entry from %s %s list."), ci->name.c_str(), source.command.c_str());
- else
- source.Reply(_("Deleted %d entries from %s %s list."), deleted, ci->name.c_str(), source.command.c_str());
- }
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAccessCount())
- return;
-
- ChanAccess *caccess = ci->GetAccess(number - 1);
-
- if (caccess->provider->name != "access/xop" || this->source.command.upper() != caccess->AccessSerialize())
- return;
-
- ++deleted;
- if (!nicks.empty())
- nicks += ", " + caccess->Mask();
- else
- nicks = caccess->Mask();
-
- ci->EraseAccess(number - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, caccess));
- delete caccess;
- }
- }
- delcallback(source, ci, this, override, mask);
- delcallback.Process();
- }
- else
- {
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- ChanAccess *a = ci->GetAccess(i);
-
- if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
- continue;
-
- if (a->Mask().equals_ci(mask))
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask();
-
- source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.c_str());
-
- ci->EraseAccess(i);
- FOREACH_MOD(OnAccessDel, (ci, source, a));
- delete a;
-
- return;
- }
- }
-
- source.Reply(_("\002%s\002 not found on %s %s list."), mask.c_str(), ci->name.c_str(), source.command.c_str());
- }
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
-
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
-
- AccessGroup access = source.AccessFor(ci);
-
- if (!access.HasPriv("ACCESS_LIST") && !source.HasPriv("chanserv/access/list"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask"));
-
- if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class XOPListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
- CommandSource &source;
- public:
- XOPListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, CommandSource &src) : NumberList(numlist, false), list(_list), ci(_ci), source(src)
- {
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > ci->GetAccessCount())
- return;
-
- const ChanAccess *a = ci->GetAccess(Number - 1);
-
- if (a->provider->name != "access/xop" || this->source.command.upper() != a->AccessSerialize())
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
- entry["Mask"] = a->Mask();
- this->list.AddEntry(entry);
- }
- } nl_list(list, ci, nick, source);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *a = ci->GetAccess(i);
-
- if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
- continue;
- else if (!nick.empty() && !Anope::Match(a->Mask(), nick))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = a->Mask();
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("%s list for %s"), source.command.c_str(), ci->name.c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- const ChanAccess *access = ci->GetAccess(i - 1);
-
- if (access->provider->name != "access/xop" || source.command.upper() != access->AccessSerialize())
- continue;
-
- delete ci->EraseAccess(i - 1);
- }
-
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- source.Reply(_("Channel %s %s list has been cleared."), ci->name.c_str(), source.command.c_str());
- }
-
- public:
- CommandCSXOP(Module *modname) : Command(modname, "chanserv/xop", 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"));
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Modify the list of %s users")), source.command.upper().c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- const Anope::string &cmd = params[1];
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
- }
-
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- const Anope::string &cmd = source.command.upper();
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Maintains the \002%s list\002 for a channel. Users who match an access entry\n"
- "on the %s list receive the following privileges:\n"
- " "), cmd.c_str(), cmd.c_str());
-
- Anope::string buf;
- for (unsigned i = 0; i < permissions[cmd].size(); ++i)
- {
- buf += ", " + permissions[cmd][i];
- if (buf.length() > 75)
- {
- source.Reply(" %s\n", buf.substr(2).c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply(" %s\n", buf.substr(2).c_str());
- buf.clear();
- }
-
- source.Reply(_(" \n"
- "The \002%s ADD\002 command adds the given nickname to the\n"
- "%s list.\n"
- " \n"
- "The \002%s DEL\002 command removes the given nick from the\n"
- "%s list. If a list of entry numbers is given, those\n"
- "entries are deleted. (See the example for LIST below.)\n"
- " \n"
- "The \002%s LIST\002 command displays the %s 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%s #channel LIST 2-5,7-9\002\n"
- " Lists %s entries numbered 2 through 5 and\n"
- " 7 through 9.\n"
- " \n"
- "The \002%s CLEAR\002 command clears all entries of the\n"
- "%s list."), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(),
- cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str());
- BotInfo *access_bi, *flags_bi;
- Anope::string access_cmd, flags_cmd;
- Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
- Command::FindCommandFromService("chanserv/flags", flags_bi, access_cmd);
- if (!access_cmd.empty() || !flags_cmd.empty())
- {
- source.Reply(_("Alternative methods of modifying channel access lists are\n"
- "available. "));
- if (!access_cmd.empty())
- source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
- "about the access list."), Config->StrictPrivmsg.c_str(), access_bi->nick.c_str(), access_cmd.c_str());
- if (!flags_cmd.empty())
- source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
- "about the flags system."), Config->StrictPrivmsg.c_str(), flags_bi->nick.c_str(), flags_cmd.c_str());
- }
- return true;
- }
-};
-
-class CSXOP : public Module
-{
- XOPAccessProvider accessprovider;
- CommandCSXOP commandcsxop;
-
- public:
- CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsxop(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- order.clear();
- permissions.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("privilege", i);
- const Anope::string &pname = block->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &xop = block->Get<const Anope::string>("xop");
- if (pname.empty() || xop.empty())
- continue;
-
- permissions[xop].push_back(pname);
- }
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
- const Anope::string &cname = block->Get<const Anope::string>("name"),
- &cserv = block->Get<const Anope::string>("command");
- if (cname.empty() || cserv != "chanserv/xop")
- continue;
-
- order.push_back(cname);
- }
- }
-};
-
-MODULE_INIT(CSXOP)
diff --git a/modules/commands/gl_global.cpp b/modules/commands/gl_global.cpp
deleted file mode 100644
index dcc7c4780..000000000
--- a/modules/commands/gl_global.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Global core functions
- *
- * (C) 2003-2016 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 CommandGLGlobal : public Command
-{
- ServiceReference<GlobalService> GService;
-
- public:
- CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1), GService("GlobalService", "Global")
- {
- this->SetDesc(_("Send a message to all users"));
- this->SetSyntax(_("\037message\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &msg = params[0];
-
- if (!GService)
- source.Reply("No global reference, is global loaded?");
- else
- {
- Log(LOG_ADMIN, source, this);
- GService->SendGlobal(NULL, source.GetNick(), msg);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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.service->nick.c_str());
- return true;
- }
-};
-
-class GLGlobal : public Module
-{
- CommandGLGlobal commandglglobal;
-
- public:
- GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandglglobal(this)
- {
-
- }
-};
-
-MODULE_INIT(GLGlobal)
diff --git a/modules/commands/greet.cpp b/modules/commands/greet.cpp
deleted file mode 100644
index 0f61a1a6e..000000000
--- a/modules/commands/greet.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 CommandBSSetGreet : public Command
-{
- public:
- CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("Enable greet messages"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &value = params[1];
-
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (value.equals_ci("ON"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets";
-
- ci->Extend<bool>("BS_GREET");
- source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
- }
- else if (value.equals_ci("OFF"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets";
-
- ci->Shrink<bool>("BS_GREET");
- source.Reply(_("Greet 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 &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002greet\002 mode on a channel.\n"
- "When it is enabled, the bot will display greet\n"
- "messages of users joining the channel, provided\n"
- "they have enough access to the channel."));
- return true;
- }
-};
-
-class CommandNSSetGreet : public Command
-{
- public:
- CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Associate a greet message with your nickname"));
- this->SetSyntax(_("\037message\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (!param.empty())
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->display;
- nc->Extend<Anope::string>("greet", param);
- source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
- }
- else
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->display;
- nc->Shrink<Anope::string>("greet");
- source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str());
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params.size() > 0 ? params[0] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the given message the greet of your nickname, that\n"
- "will be displayed when joining a channel that has GREET\n"
- "option enabled, provided that you have the necessary\n"
- "access on it."));
- return true;
- }
-};
-
-class CommandNSSASetGreet : public CommandNSSetGreet
-{
- public:
- CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037message\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the given message the greet of the nickname, that\n"
- "will be displayed when joining a channel that has GREET\n"
- "option enabled, provided that the user has the necessary\n"
- "access on it."));
- return true;
- }
-};
-
-class Greet : public Module
-{
- /* channel setting for whether or not greet should be shown */
- SerializableExtensibleItem<bool> bs_greet;
- /* user greets */
- SerializableExtensibleItem<Anope::string> ns_greet;
-
- CommandBSSetGreet commandbssetgreet;
- CommandNSSetGreet commandnssetgreet;
- CommandNSSASetGreet commandnssasetgreet;
-
- public:
- Greet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- bs_greet(this, "BS_GREET"),
- ns_greet(this, "greet"),
- commandbssetgreet(this),
- commandnssetgreet(this), commandnssasetgreet(this)
- {
- }
-
- void OnJoinChannel(User *user, Channel *c) anope_override
- {
- /* 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->ci || !c->ci->bi || !user->server->IsSynced() || !user->Account())
- return;
-
- Anope::string *greet = ns_greet.Get(user->Account());
- if (bs_greet.HasExt(c->ci) && greet != NULL && !greet->empty() && c->FindUser(c->ci->bi) && c->ci->AccessFor(user).HasPriv("GREET"))
- {
- IRCD->SendPrivmsg(*c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), greet->c_str());
- c->ci->bi->lastmsg = Anope::CurTime;
- }
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- Anope::string *greet = ns_greet.Get(na->nc);
- if (greet != NULL)
- info[_("Greet")] = *greet;
- }
-
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
- {
- if (bs_greet.HasExt(ci))
- info.AddOption(_("Greet"));
- }
-};
-
-MODULE_INIT(Greet)
diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp
deleted file mode 100644
index 02b2a1324..000000000
--- a/modules/commands/hs_del.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 CommandHSDel : public Command
-{
- public:
- CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 1)
- {
- this->SetDesc(_("Delete the vhost of another user"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- NickAlias *na = NickAlias::Find(nick);
- if (na)
- {
- Log(LOG_ADMIN, source, this) << "for user " << na->nick;
- FOREACH_MOD(OnDeleteVhost, (na));
- na->RemoveVhost();
- source.Reply(_("Vhost for \002%s\002 removed."), nick.c_str());
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Deletes the vhost assigned to the given nick from the\n"
- "database."));
- return true;
- }
-};
-
-class CommandHSDelAll : public Command
-{
- public:
- CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1)
- {
- this->SetDesc(_("Deletes the vhost for all nicks in a group"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- NickAlias *na = NickAlias::Find(nick);
- if (na)
- {
- FOREACH_MOD(OnDeleteVhost, (na));
- const NickCore *nc = na->nc;
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- na = nc->aliases->at(i);
- na->RemoveVhost();
- }
- Log(LOG_ADMIN, source, 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) anope_override
- {
- 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, VENDOR),
- commandhsdel(this), commandhsdelall(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSDel)
diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp
deleted file mode 100644
index e6211b118..000000000
--- a/modules/commands/hs_group.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 CommandHSGroup : public Command
-{
- bool setting;
-
- public:
- void Sync(const NickAlias *na)
- {
- if (setting)
- return;
-
- if (!na || !na->HasVhost())
- return;
-
- setting = true;
- for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
- {
- NickAlias *nick = na->nc->aliases->at(i);
- if (nick)
- {
- nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
- FOREACH_MOD(OnSetVhost, (nick));
- }
- }
- setting = false;
- }
-
- CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0), setting(false)
- {
- this->SetDesc(_("Syncs the vhost for all nicks in a group"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (na && source.GetAccount() == na->nc && na->HasVhost())
- {
- this->Sync(na);
- if (!na->GetVhostIdent().empty())
- source.Reply(_("All vhosts in the group \002%s\002 have been set to \002%s\002@\002%s\002."), source.nc->display.c_str(), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- source.Reply(_("All vhosts in the group \002%s\002 have been set to \002%s\002."), source.nc->display.c_str(), na->GetVhostHost().c_str());
- }
- else
- source.Reply(HOST_NOT_ASSIGNED);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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;
- }
-};
-
-class HSGroup : public Module
-{
- CommandHSGroup commandhsgroup;
- bool syncongroup;
- bool synconset;
-
- public:
- HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsgroup(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-
- void OnSetVhost(NickAlias *na) anope_override
- {
- if (!synconset)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnNickGroup(User *u, NickAlias *na) anope_override
- {
- if (!syncongroup)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- syncongroup = block->Get<bool>("syncongroup");
- synconset = block->Get<bool>("synconset");
- }
-};
-
-MODULE_INIT(HSGroup)
diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp
deleted file mode 100644
index 75c8cf62a..000000000
--- a/modules/commands/hs_off.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 CommandHSOff : public Command
-{
- public:
- CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0)
- {
- this->SetDesc(_("Deactivates your assigned vhost"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- const NickAlias *na = NickAlias::Find(u->nick);
- if (!na || na->nc != u->Account() || !na->HasVhost())
- na = NickAlias::Find(u->Account()->display);
-
- if (!na || !na->HasVhost())
- source.Reply(HOST_NOT_ASSIGNED);
- else
- {
- u->vhost.clear();
- IRCD->SendVhostDel(u);
- u->UpdateHost();
- Log(LOG_COMMAND, source, this) << "to disable their vhost";
- source.Reply(_("Your vhost was removed and the normal cloaking restored."));
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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 host/IP address."));
- return true;
- }
-};
-
-class HSOff : public Module
-{
- CommandHSOff commandhsoff;
-
- public:
- HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsoff(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSOff)
diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp
deleted file mode 100644
index 5aa20380c..000000000
--- a/modules/commands/hs_on.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 CommandHSOn : public Command
-{
- public:
- CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0)
- {
- this->SetDesc(_("Activates your assigned vhost"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!IRCD->CanSetVHost)
- return; // HostServ wouldn't even be loaded at this point
-
- User *u = source.GetUser();
- const NickAlias *na = NickAlias::Find(u->nick);
- if (!na || na->nc != u->Account() || !na->HasVhost())
- na = NickAlias::Find(u->Account()->display);
- if (na && u->Account() == na->nc && na->HasVhost())
- {
- if (!na->GetVhostIdent().empty())
- source.Reply(_("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- source.Reply(_("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
- Log(LOG_COMMAND, source, this) << "to enable their vhost of " << (!na->GetVhostIdent().empty() ? na->GetVhostIdent() + "@" : "") << na->GetVhostHost();
- IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
- u->vhost = na->GetVhostHost();
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- u->SetVIdent(na->GetVhostIdent());
- u->UpdateHost();
- }
- else
- source.Reply(HOST_NOT_ASSIGNED);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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 host/IP address."));
- return true;
- }
-};
-
-class HSOn : public Module
-{
- CommandHSOn commandhson;
-
- public:
- HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhson(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSOn)
diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp
deleted file mode 100644
index 12979e804..000000000
--- a/modules/commands/hs_request.cpp
+++ /dev/null
@@ -1,394 +0,0 @@
-/* hs_request.c - Add request and activate functionality to HostServ
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Based on the original module by Rob <rob@anope.org>
- * Included in the Anope module pack since Anope 1.7.11
- * Anope Coder: GeniusDex <geniusdex@anope.org>
- *
- * Please read COPYING and README for further details.
- *
- * Send bug reports to the Anope Coder instead of the module
- * author, because any changes since the inclusion into anope
- * are not supported by the original author.
- */
-
-#include "module.h"
-
-static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-
-static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
-
-struct HostRequest : Serializable
-{
- Anope::string nick;
- Anope::string ident;
- Anope::string host;
- time_t time;
-
- HostRequest(Extensible *) : Serializable("HostRequest") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["nick"] << this->nick;
- data["ident"] << this->ident;
- data["host"] << this->host;
- data.SetType("time", Serialize::Data::DT_INT); data["time"] << this->time;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snick;
- data["nick"] >> snick;
-
- NickAlias *na = NickAlias::Find(snick);
- if (na == NULL)
- return NULL;
-
- HostRequest *req;
- if (obj)
- req = anope_dynamic_static_cast<HostRequest *>(obj);
- else
- req = na->Extend<HostRequest>("hostrequest");
- if (req)
- {
- req->nick = na->nick;
- data["ident"] >> req->ident;
- data["host"] >> req->host;
- data["time"] >> req->time;
- }
-
- return req;
- }
-};
-
-class CommandHSRequest : public Command
-{
- bool isvalidchar(char c)
- {
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
- return true;
- return false;
- }
-
- public:
- CommandHSRequest(Module *creator) : Command(creator, "hostserv/request", 1, 1)
- {
- this->SetDesc(_("Request a vHost for your nick"));
- this->SetSyntax(_("vhost"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (!na || na->nc != source.GetAccount())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (source.GetAccount()->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You must confirm your account before you may request a vhost."));
- return;
- }
-
- Anope::string rawhostmask = params[0];
-
- 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->GetBlock("networkinfo")->Get<unsigned>("userlen"))
- {
- source.Reply(HOST_SET_IDENTTOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("userlen"));
- return;
- }
- else if (!IRCD->CanSetVIdent)
- {
- 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->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
- if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
- {
- source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay);
- u->lastmemosend = Anope::CurTime;
- return;
- }
-
- HostRequest req(na);
- req.nick = source.GetNick();
- req.ident = user;
- req.host = host;
- req.time = Anope::CurTime;
- na->Extend<HostRequest>("hostrequest", req);
-
- source.Reply(_("Your vHost has been requested."));
- req_send_memos(owner, source, user, host);
- Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Request the given vHost to be activated for your nick by the\n"
- "network administrators. Please be patient while your request\n"
- "is being considered."));
- return true;
- }
-};
-
-class CommandHSActivate : public Command
-{
- public:
- CommandHSActivate(Module *creator) : Command(creator, "hostserv/activate", 1, 1)
- {
- this->SetDesc(_("Approve the requested vHost of a user"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
-
- NickAlias *na = NickAlias::Find(nick);
- HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
- if (req)
- {
- na->SetVhost(req->ident, req->host, source.GetNick(), req->time);
- FOREACH_MOD(OnSetVhost, (na));
-
- if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
- memoserv->Send(source.service->nick, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
-
- source.Reply(_("vHost for %s has been activated."), na->nick.c_str());
- Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
- na->Shrink<HostRequest>("hostrequest");
- }
- else
- source.Reply(_("No request for nick %s found."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Activate the requested vHost for the given nick."));
- if (Config->GetModule(this->owner)->Get<bool>("memouser"))
- source.Reply(_("A memo informing the user will also be sent."));
-
- return true;
- }
-};
-
-class CommandHSReject : public Command
-{
- public:
- CommandHSReject(Module *creator) : Command(creator, "hostserv/reject", 1, 2)
- {
- this->SetDesc(_("Reject the requested vHost of a user"));
- this->SetSyntax(_("\037nick\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- const Anope::string &reason = params.size() > 1 ? params[1] : "";
-
- NickAlias *na = NickAlias::Find(nick);
- HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
- if (req)
- {
- na->Shrink<HostRequest>("hostrequest");
-
- if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
- {
- Anope::string message;
- if (!reason.empty())
- message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
- else
- message = _("[auto memo] Your requested vHost has been rejected.");
-
- memoserv->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true);
- }
-
- source.Reply(_("vHost for %s has been rejected."), nick.c_str());
- Log(LOG_COMMAND, source, this) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "no reason") << ")";
- }
- else
- source.Reply(_("No request for nick %s found."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Reject the requested vHost for the given nick."));
- if (Config->GetModule(this->owner)->Get<bool>("memouser"))
- source.Reply(_("A memo informing the user will also be sent, which includes the reason for the rejection if supplied."));
-
- return true;
- }
-};
-
-class CommandHSWaiting : public Command
-{
- public:
- CommandHSWaiting(Module *creator) : Command(creator, "hostserv/waiting", 0, 0)
- {
- this->SetDesc(_("Retrieves the vhost requests"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned counter = 0;
- unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Created"));
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- {
- const NickAlias *na = it->second;
- HostRequest *hr = na->GetExt<HostRequest>("hostrequest");
- if (!hr)
- continue;
-
- if (!listmax || display_counter < listmax)
- {
- ++display_counter;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(display_counter);
- entry["Nick"] = it->first;
- if (!hr->ident.empty())
- entry["Vhost"] = hr->ident + "@" + hr->host;
- else
- entry["Vhost"] = hr->host;
- entry["Created"] = Anope::strftime(hr->time, NULL, true);
- list.AddEntry(entry);
- }
- ++counter;
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("Displayed \002%d\002 records (\002%d\002 total)."), display_counter, counter);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command retrieves the vhost requests."));
-
- return true;
- }
-};
-
-class HSRequest : public Module
-{
- CommandHSRequest commandhsrequest;
- CommandHSActivate commandhsactive;
- CommandHSReject commandhsreject;
- CommandHSWaiting commandhswaiting;
- ExtensibleItem<HostRequest> hostrequest;
- Serialize::Type request_type;
-
- public:
- HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsrequest(this), commandhsactive(this),
- commandhsreject(this), commandhswaiting(this), hostrequest(this, "hostrequest"), request_type("HostRequest", HostRequest::Unserialize)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
-{
- Anope::string host;
- std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end;
-
- if (!vIdent.empty())
- host = vIdent + "@" + vHost;
- else
- host = vHost;
-
- if (Config->GetModule(me)->Get<bool>("memooper") && memoserv)
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- const NickAlias *na = NickAlias::Find(o->name);
- if (!na)
- continue;
-
- Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str());
-
- memoserv->Send(source.service->nick, na->nick, message, true);
- }
-}
-
-MODULE_INIT(HSRequest)
diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp
deleted file mode 100644
index 4c736a77d..000000000
--- a/modules/commands/hs_set.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 CommandHSSet : public Command
-{
- public:
- CommandHSSet(Module *creator) : Command(creator, "hostserv/set", 2, 2)
- {
- this->SetDesc(_("Set the vhost of another user"));
- this->SetSyntax(_("\037nick\037 \037hostmask\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
-
- NickAlias *na = NickAlias::Find(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 (!IRCD->CanSetVIdent)
- {
- source.Reply(HOST_NO_VIDENT);
- return;
- }
- else if (!IRCD->IsIdentValid(user))
- {
- source.Reply(HOST_SET_IDENT_ERROR);
- return;
- }
- }
-
- if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
-
- na->SetVhost(user, host, source.GetNick());
- FOREACH_MOD(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());
- else
- 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) anope_override
- {
- 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;
- }
-};
-
-class CommandHSSetAll : public Command
-{
- void Sync(const NickAlias *na)
- {
- if (!na || !na->HasVhost())
- return;
-
- for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
- {
- NickAlias *nick = na->nc->aliases->at(i);
- if (nick)
- nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
- }
- }
-
- public:
- CommandHSSetAll(Module *creator) : Command(creator, "hostserv/setall", 2, 2)
- {
- 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) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- Anope::string nick = params[0];
-
- NickAlias *na = NickAlias::Find(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 (!IRCD->CanSetVIdent)
- {
- source.Reply(HOST_NO_VIDENT);
- return;
- }
- else if (!IRCD->IsIdentValid(user))
- {
- source.Reply(HOST_SET_IDENT_ERROR);
- return;
- }
- }
-
- if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
-
- na->SetVhost(user, host, source.GetNick());
- this->Sync(na);
- FOREACH_MOD(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) anope_override
- {
- 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, VENDOR), commandhsset(this), commandhssetall(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSSet)
diff --git a/modules/commands/ms_cancel.cpp b/modules/commands/ms_cancel.cpp
deleted file mode 100644
index 9e6f0ce63..000000000
--- a/modules/commands/ms_cancel.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSCancel : public Command
-{
- public:
- CommandMSCancel(Module *creator) : Command(creator, "memoserv/cancel", 1, 1)
- {
- this->SetDesc(_("Cancel the last memo you sent"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nname = params[0];
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(nname, ischan);
-
- if (mi == NULL)
- source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), nname.c_str());
- else
- {
- ChannelInfo *ci = NULL;
- NickAlias *na = NULL;
- if (ischan)
- ci = ChannelInfo::Find(nname);
- else
- na = NickAlias::Find(nname);
- for (int i = mi->memos->size() - 1; i >= 0; --i)
- if (mi->GetMemo(i)->unread && source.nc->display.equals_ci(mi->GetMemo(i)->sender))
- {
- FOREACH_MOD(OnMemoDel, (ischan ? ci->name : na->nc->display, mi, mi->GetMemo(i)));
- mi->Del(i);
- source.Reply(_("Last memo to \002%s\002 has been cancelled."), nname.c_str());
- return;
- }
-
- source.Reply(_("No memo was cancelable."));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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;
- }
-};
-
-class MSCancel : public Module
-{
- CommandMSCancel commandmscancel;
-
- public:
- MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmscancel(this)
- {
- }
-};
-
-MODULE_INIT(MSCancel)
diff --git a/modules/commands/ms_check.cpp b/modules/commands/ms_check.cpp
deleted file mode 100644
index 707da95cd..000000000
--- a/modules/commands/ms_check.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSCheck : public Command
-{
- public:
- CommandMSCheck(Module *creator) : Command(creator, "memoserv/check", 1, 1)
- {
- this->SetDesc(_("Checks if last memo to a nick was read"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &recipient = params[0];
-
- bool found = false;
-
- const NickAlias *na = NickAlias::Find(recipient);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, recipient.c_str());
- return;
- }
-
- MemoInfo *mi = &na->nc->memos;
-
- /* Okay, I know this looks strange but we want to get the LAST memo, so we
- have to loop backwards */
-
- for (unsigned i = mi->memos->size(); i > 0; --i)
- {
- Memo *m = mi->GetMemo(i - 1);
- NickAlias *na2 = NickAlias::Find(m->sender);
-
- if (na2 != NULL && na2->nc == source.GetAccount())
- {
- found = true; /* Yes, we've found the memo */
-
- if (m->unread)
- source.Reply(_("The last memo you sent to %s (sent on %s) has not yet been read."), na->nick.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- else
- source.Reply(_("The last memo you sent to %s (sent on %s) has been read."), na->nick.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- break;
- }
- }
-
- if (!found)
- source.Reply(_("Nick %s doesn't have a memo from you."), na->nick.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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 only works with nicks, not with channels."));
- return true;
- }
-};
-
-class MSCheck : public Module
-{
- CommandMSCheck commandmscheck;
-
- public:
- MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmscheck(this)
- {
-
- }
-};
-
-MODULE_INIT(MSCheck)
diff --git a/modules/commands/ms_del.cpp b/modules/commands/ms_del.cpp
deleted file mode 100644
index bc496d72e..000000000
--- a/modules/commands/ms_del.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 MemoDelCallback : public NumberList
-{
- CommandSource &source;
- ChannelInfo *ci;
- MemoInfo *mi;
- public:
- MemoDelCallback(CommandSource &_source, ChannelInfo *_ci, MemoInfo *_mi, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), mi(_mi)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(number - 1)));
-
- mi->Del(number - 1);
- source.Reply(_("Memo %d has been deleted."), number);
- }
-};
-
-class CommandMSDel : public Command
-{
- public:
- 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}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- MemoInfo *mi;
- ChannelInfo *ci = NULL;
- Anope::string numstr = !params.empty() ? params[0] : "", chan;
-
- if (!numstr.empty() && numstr[0] == '#')
- {
- chan = numstr;
- numstr = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
- if (numstr.empty() || (!isdigit(numstr[0]) && !numstr.equals_ci("ALL") && !numstr.equals_ci("LAST")))
- this->OnSyntaxError(source, numstr);
- else if (mi->memos->empty())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- if (isdigit(numstr[0]))
- {
- MemoDelCallback list(source, ci, mi, numstr);
- list.Process();
- }
- else if (numstr.equals_ci("LAST"))
- {
- /* Delete last memo. */
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(mi->memos->size() - 1)));
- mi->Del(mi->memos->size() - 1);
- source.Reply(_("Memo %d has been deleted."), mi->memos->size() + 1);
- }
- else
- {
- /* Delete all memos. */
- for (unsigned i = mi->memos->size(); i > 0; --i)
- {
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(i)));
- mi->Del(i - 1);
- }
- if (!chan.empty())
- source.Reply(_("All memos for channel %s have been deleted."), chan.c_str());
- else
- source.Reply(_("All of your memos have been deleted."));
- }
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- 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"
- "If \002LAST\002 is given, the last memo will be deleted.\n"
- "If \002ALL\002 is given, deletes all of your memos.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002DEL 1\002\n"
- " Deletes your first memo.\n"
- " \n"
- " \002DEL 2-5,7-9\002\n"
- " Deletes memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSDel : public Module
-{
- CommandMSDel commandmsdel;
-
- public:
- MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsdel(this)
- {
-
- }
-};
-
-MODULE_INIT(MSDel)
diff --git a/modules/commands/ms_ignore.cpp b/modules/commands/ms_ignore.cpp
deleted file mode 100644
index 6a2fa01cf..000000000
--- a/modules/commands/ms_ignore.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSIgnore : public Command
-{
- public:
- CommandMSIgnore(Module *creator) : Command(creator, "memoserv/ignore", 1, 3)
- {
- this->SetDesc(_("Manage the memo ignore list"));
- this->SetSyntax(_("[\037channel\037] ADD \037entry\037"));
- this->SetSyntax(_("[\037channel\037] DEL \037entry\037"));
- this->SetSyntax(_("[\037channel\037] LIST"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- Anope::string channel = params[0];
- Anope::string command = (params.size() > 1 ? params[1] : "");
- Anope::string param = (params.size() > 2 ? params[2] : "");
-
- if (channel[0] != '#')
- {
- param = command;
- command = channel;
- channel = source.GetNick();
- }
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(channel, ischan);
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (!mi)
- source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), channel.c_str());
- else if (ischan && !source.AccessFor(ci).HasPriv("MEMO"))
- source.Reply(ACCESS_DENIED);
- else if (command.equals_ci("ADD") && !param.empty())
- {
- if (mi->ignores.size() >= Config->GetModule(this->owner)->Get<unsigned>("max", "32"))
- {
- source.Reply(_("Sorry, the memo ignore list for \002%s\002 is full."), channel.c_str());
- return;
- }
-
- if (std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str()) == mi->ignores.end())
- {
- mi->ignores.push_back(param.ci_str());
- source.Reply(_("\002%s\002 added to ignore list."), param.c_str());
- }
- else
- source.Reply(_("\002%s\002 is already on the ignore list."), param.c_str());
- }
- else if (command.equals_ci("DEL") && !param.empty())
- {
- std::vector<Anope::string>::iterator it = std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str());
-
- if (it != mi->ignores.end())
- {
- mi->ignores.erase(it);
- source.Reply(_("\002%s\002 removed from the ignore list."), param.c_str());
- }
- else
- source.Reply(_("\002%s\002 is not on the ignore list."), param.c_str());
- }
- else if (command.equals_ci("LIST"))
- {
- if (mi->ignores.empty())
- source.Reply(_("Memo ignore list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask"));
- for (unsigned i = 0; i < mi->ignores.size(); ++i)
- {
- ListFormatter::ListEntry entry;
- entry["Mask"] = mi->ignores[i];
- list.AddEntry(entry);
- }
-
- source.Reply(_("Ignore list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to ignore users by nick or host from memoing\n"
- "you or a channel. If someone on the memo ignore list tries\n"
- "to memo you or a channel, they will not be told that you have\n"
- "them ignored."));
- return true;
- }
-};
-
-class MSIgnore : public Module
-{
- CommandMSIgnore commandmsignore;
-
- public:
- MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsignore(this)
- {
- }
-};
-
-MODULE_INIT(MSIgnore)
diff --git a/modules/commands/ms_info.cpp b/modules/commands/ms_info.cpp
deleted file mode 100644
index 8f99557bf..000000000
--- a/modules/commands/ms_info.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSInfo : public Command
-{
- public:
- CommandMSInfo(Module *creator) : Command(creator, "memoserv/info", 0, 1)
- {
- this->SetDesc(_("Displays information about your memos"));
- this->SetSyntax(_("[\037nick\037 | \037channel\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- NickCore *nc = source.nc;
- const MemoInfo *mi;
- const NickAlias *na = NULL;
- ChannelInfo *ci = NULL;
- const Anope::string &nname = !params.empty() ? params[0] : "";
- bool hardmax;
-
- if (!nname.empty() && nname[0] != '#' && source.HasPriv("memoserv/info"))
- {
- na = NickAlias::Find(nname);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nname.c_str());
- return;
- }
- mi = &na->nc->memos;
- hardmax = na->nc->HasExt("MEMO_HARDMAX");
- }
- else if (!nname.empty() && nname[0] == '#')
- {
- ci = ChannelInfo::Find(nname);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, nname.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- hardmax = ci->HasExt("MEMO_HARDMAX");
- }
- else if (!nname.empty()) /* It's not a chan and we aren't services admin */
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- {
- mi = &nc->memos;
- hardmax = nc->HasExt("MEMO_HARDMAX");
- }
-
- if (!nname.empty() && (ci || na->nc != nc))
- {
- if (mi->memos->empty())
- source.Reply(_("%s currently has no memos."), nname.c_str());
- else if (mi->memos->size() == 1)
- {
- if (mi->GetMemo(0)->unread)
- source.Reply(_("%s currently has \0021\002 memo, and it has not yet been read."), nname.c_str());
- else
- source.Reply(_("%s currently has \0021\002 memo."), nname.c_str());
- }
- else
- {
- unsigned count = 0, i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- ++count;
- if (count == mi->memos->size())
- source.Reply(_("%s currently has \002%d\002 memos; all of them are unread."), nname.c_str(), count);
- else if (!count)
- source.Reply(_("%s currently has \002%d\002 memos."), nname.c_str(), mi->memos->size());
- else if (count == 1)
- source.Reply(_("%s currently has \002%d\002 memos, of which \0021\002 is unread."), nname.c_str(), mi->memos->size());
- else
- source.Reply(_("%s currently has \002%d\002 memos, of which \002%d\002 are unread."), nname.c_str(), mi->memos->size(), count);
- }
- if (!mi->memomax)
- {
- if (hardmax)
- source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
- else
- source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
- }
- else if (mi->memomax > 0)
- {
- if (hardmax)
- source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
- else
- source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
- }
- else
- source.Reply(_("%s has no memo limit."), nname.c_str());
-
- /* I ripped this code out of ircservices 4.4.5, since I didn't want
- to rewrite the whole thing (it pisses me off). */
- if (na)
- {
- if (na->nc->HasExt("MEMO_RECEIVE") && na->nc->HasExt("MEMO_SIGNON"))
- source.Reply(_("%s is notified of new memos at logon and when they arrive."), nname.c_str());
- else if (na->nc->HasExt("MEMO_RECEIVE"))
- source.Reply(_("%s is notified when new memos arrive."), nname.c_str());
- else if (na->nc->HasExt("MEMO_SIGNON"))
- source.Reply(_("%s is notified of news memos at logon."), nname.c_str());
- else
- source.Reply(_("%s is not notified of new memos."), nname.c_str());
- }
- }
- else /* !nname || (!ci || na->nc == nc) */
- {
- if (mi->memos->empty())
- source.Reply(_("You currently have no memos."));
- else if (mi->memos->size() == 1)
- {
- if (mi->GetMemo(0)->unread)
- source.Reply(_("You currently have \0021\002 memo, and it has not yet been read."));
- else
- source.Reply(_("You currently have \0021\002 memo."));
- }
- else
- {
- unsigned count = 0, i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- ++count;
- if (count == mi->memos->size())
- source.Reply(_("You currently have \002%d\002 memos; all of them are unread."), count);
- else if (!count)
- source.Reply(_("You currently have \002%d\002 memos."), mi->memos->size());
- else if (count == 1)
- source.Reply(_("You currently have \002%d\002 memos, of which \0021\002 is unread."), mi->memos->size());
- else
- source.Reply(_("You currently have \002%d\002 memos, of which \002%d\002 are unread."), mi->memos->size(), count);
- }
-
- if (!mi->memomax)
- {
- if (!source.IsServicesOper() && hardmax)
- source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit."));
- else
- source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos."));
- }
- else if (mi->memomax > 0)
- {
- if (!source.IsServicesOper() && hardmax)
- source.Reply(_("Your memo limit is \002%d\002, and may not be changed."), mi->memomax);
- else
- source.Reply(_("Your memo limit is \002%d\002."), mi->memomax);
- }
- else
- source.Reply(_("You have no limit on the number of memos you may keep."));
-
- bool memo_mail = nc->HasExt("MEMO_MAIL");
- if (nc->HasExt("MEMO_RECEIVE") && nc->HasExt("MEMO_SIGNON"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified of new memos at logon and when they arrive, and by mail when they arrive."));
- else
- source.Reply(_("You will be notified of new memos at logon and when they arrive."));
- }
- else if (nc->HasExt("MEMO_RECEIVE"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified by message and by mail when new memos arrive."));
- else
- source.Reply(_("You will be notified when new memos arrive."));
- }
- else if (nc->HasExt("MEMO_SIGNON"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified of new memos at logon, and by mail when they arrive."));
- else
- source.Reply(_("You will be notified of new memos at logon."));
- }
- else
- {
- source.Reply(_("You will not be notified of new memos."));
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without a parameter, displays information on the number of\n"
- "memos you have, how many of them are unread, and how many\n"
- "total memos you can receive.\n"
- " \n"
- "With a channel parameter, displays the same information for\n"
- "the given channel.\n"
- " \n"
- "With a nickname parameter, displays the same information\n"
- "for the given nickname. This is limited to \002Services\002\n"
- "\002Operators\002."));
-
- return true;
- }
-};
-
-class MSInfo : public Module
-{
- CommandMSInfo commandmsinfo;
-
- public:
- MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(MSInfo)
diff --git a/modules/commands/ms_list.cpp b/modules/commands/ms_list.cpp
deleted file mode 100644
index c386be81d..000000000
--- a/modules/commands/ms_list.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSList : public Command
-{
- public:
- CommandMSList(Module *creator) : Command(creator, "memoserv/list", 0, 2)
- {
- this->SetDesc(_("List your memos"));
- this->SetSyntax(_("[\037channel\037] [\037list\037 | NEW]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- Anope::string param = !params.empty() ? params[0] : "", chan;
- ChannelInfo *ci = NULL;
- const MemoInfo *mi;
-
- if (!param.empty() && param[0] == '#')
- {
- chan = param;
- param = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
-
- if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW"))
- this->OnSyntaxError(source, param);
- else if (!mi->memos->size())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time"));
-
- if (!param.empty() && isdigit(param[0]))
- {
- class MemoListCallback : public NumberList
- {
- ListFormatter &list;
- CommandSource &source;
- const MemoInfo *mi;
- public:
- MemoListCallback(ListFormatter &_list, CommandSource &_source, const MemoInfo *_mi, const Anope::string &numlist) : NumberList(numlist, false), list(_list), source(_source), mi(_mi)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- const Memo *m = mi->GetMemo(number - 1);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = (m->unread ? "* " : " ") + stringify(number);
- entry["Sender"] = m->sender;
- entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
- this->list.AddEntry(entry);
- }
- }
- mlc(list, source, mi, param);
- mlc.Process();
- }
- else
- {
- if (!param.empty())
- {
- unsigned i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- break;
- if (i == end)
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
- return;
- }
- }
-
- for (unsigned i = 0, end = mi->memos->size(); i < end; ++i)
- {
- if (!param.empty() && !mi->GetMemo(i)->unread)
- continue;
-
- const Memo *m = mi->GetMemo(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = (m->unread ? "* " : " ") + stringify(i + 1);
- entry["Sender"] = m->sender;
- entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Memos for %s:"), ci ? ci->name.c_str() : source.GetNick().c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists any memos you currently have. With \002NEW\002, lists only\n"
- "new (unread) memos. Unread memos are marked with a \"*\"\n"
- "to the left of the memo number. You can also specify a list\n"
- "of numbers, as in the example below:\n"
- " \002LIST 2-5,7-9\002\n"
- " Lists memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSList : public Module
-{
- CommandMSList commandmslist;
-
- public:
- MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmslist(this)
- {
-
- }
-};
-
-MODULE_INIT(MSList)
diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp
deleted file mode 100644
index 96103d30b..000000000
--- a/modules/commands/ms_read.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ");
-
-static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ)
-{
- /* Only send receipt if memos are allowed */
- if (MemoServService && !Anope::ReadOnly)
- {
- /* Get nick alias for sender */
- const NickAlias *na = NickAlias::Find(m->sender);
-
- if (!na)
- return;
-
- /* Get nick core for sender */
- const NickCore *nc = na->nc;
-
- if (!nc)
- return;
-
- /* Text of the memo varies if the recipient was a
- nick or channel */
- Anope::string text = Anope::printf(Language::Translate(na->nc, _("\002[auto-memo]\002 The memo you sent to %s has been viewed.")), targ.c_str());
-
- /* Send notification */
- MemoServService->Send(source.GetNick(), m->sender, text, true);
-
- /* Notify recipient of the memo that a notification has
- been sent to the sender */
- source.Reply(_("A notification memo has been sent to %s informing him/her you have\n"
- "read his/her memo."), nc->display.c_str());
- }
-
- /* Remove receipt flag from the original memo */
- m->receipt = false;
-}
-
-class MemoListCallback : public NumberList
-{
- CommandSource &source;
- MemoInfo *mi;
- const ChannelInfo *ci;
- bool found;
- public:
- MemoListCallback(CommandSource &_source, MemoInfo *_mi, const ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), mi(_mi), ci(_ci)
- {
- found = false;
- }
-
- ~MemoListCallback()
- {
- if (!found)
- source.Reply(_("No memos to display."));
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- MemoListCallback::DoRead(source, mi, ci, number - 1);
- found = true;
- }
-
- static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index)
- {
- Memo *m = mi->GetMemo(index);
- if (!m)
- return;
-
- if (ci)
- source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- else
- source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("memoserv/del", bi, cmd))
- {
- if (ci)
- source.Reply(_("To delete, type: \002%s%s %s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), ci->name.c_str(), index + 1);
- else
- source.Reply(_("To delete, type: \002%s%s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), index + 1);
- }
-
- source.Reply("%s", m->text.c_str());
- m->unread = false;
-
- /* Check if a receipt notification was requested */
- if (m->receipt)
- rsend_notify(source, mi, m, ci ? ci->name : source.GetNick());
- }
-};
-
-class CommandMSRead : public Command
-{
- public:
- CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2)
- {
- this->SetDesc(_("Read a memo or memos"));
- this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- MemoInfo *mi;
- ChannelInfo *ci = NULL;
- Anope::string numstr = params[0], chan;
-
- if (!numstr.empty() && numstr[0] == '#')
- {
- chan = numstr;
- numstr = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
-
- if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && numstr.find_first_not_of("0123456789.,-") != Anope::string::npos))
- this->OnSyntaxError(source, numstr);
- else if (mi->memos->empty())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- int i, end;
-
- if (numstr.equals_ci("NEW"))
- {
- int readcount = 0;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- {
- MemoListCallback::DoRead(source, mi, ci, i);
- ++readcount;
- }
- if (!readcount)
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
- }
- }
- else if (numstr.equals_ci("LAST"))
- {
- for (i = 0, end = mi->memos->size() - 1; i < end; ++i);
- MemoListCallback::DoRead(source, mi, ci, i);
- }
- else /* number[s] */
- {
- MemoListCallback list(source, mi, ci, numstr);
- list.Process();
- }
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends you the text of the memos specified. If LAST is\n"
- "given, sends you the memo you most recently received. If\n"
- "NEW is given, sends you all of your new memos. Otherwise,\n"
- "sends you memo number \037num\037. You can also give a list of\n"
- "numbers, as in this example:\n"
- " \n"
- " \002READ 2-5,7-9\002\n"
- " Displays memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSRead : public Module
-{
- CommandMSRead commandmsread;
-
- public:
- MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsread(this)
- {
-
- }
-};
-
-MODULE_INIT(MSRead)
diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp
deleted file mode 100644
index b7744131a..000000000
--- a/modules/commands/ms_rsend.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSRSend : public Command
-{
- public:
- CommandMSRSend(Module *creator) : Command(creator, "memoserv/rsend", 2, 2)
- {
- this->SetDesc(_("Sends a memo and requests a read receipt"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- if (Anope::ReadOnly && !source.IsOper())
- {
- source.Reply(MEMO_SEND_DISABLED);
- return;
- }
-
- const Anope::string &nick = params[0];
- const Anope::string &text = params[1];
- const NickAlias *na = NULL;
-
- /* prevent user from rsend to themselves */
- if ((na = NickAlias::Find(nick)) && na->nc == source.GetAccount())
- {
- source.Reply(_("You can not request a receipt when sending a memo to yourself."));
- return;
- }
-
- if (Config->GetModule(this->owner)->Get<bool>("operonly") && !source.IsServicesOper())
- source.Reply(ACCESS_DENIED);
- else
- {
- MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text);
- if (result == MemoServService::MEMO_INVALID_TARGET)
- source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
- else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
- else if (result == MemoServService::MEMO_TARGET_FULL)
- source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
- else
- {
- source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(nick, ischan);
- if (mi == NULL)
- throw CoreException("NULL mi in ms_rsend");
- Memo *m = (mi->memos->size() ? mi->GetMemo(mi->memos->size() - 1) : NULL);
- if (m != NULL)
- m->receipt = true;
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends the named \037nick\037 or \037channel\037 a memo containing\n"
- "\037memo-text\037. When sending to a nickname, the recipient will\n"
- "receive a notice that he/she has a new memo. The target\n"
- "nickname/channel must be registered.\n"
- "Once the memo is read by its recipient, an automatic notification\n"
- "memo will be sent to the sender informing him/her that the memo\n"
- "has been read."));
- return true;
- }
-};
-
-class MSRSend : public Module
-{
- CommandMSRSend commandmsrsend;
-
- public:
- MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsrsend(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSRSend)
diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp
deleted file mode 100644
index b028706d3..000000000
--- a/modules/commands/ms_send.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSSend : public Command
-{
- public:
- CommandMSSend(Module *creator) : Command(creator, "memoserv/send", 2, 2)
- {
- this->SetDesc(_("Send a memo to a nick or channel"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &nick = params[0];
- const Anope::string &text = params[1];
-
- if (Anope::ReadOnly && !source.IsOper())
- {
- source.Reply(MEMO_SEND_DISABLED);
- return;
- }
-
- if (source.GetAccount()->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You must confirm your account before you may send a memo."));
- return;
- }
-
- MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text);
- if (result == MemoServService::MEMO_SUCCESS)
- {
- source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
- Log(LOG_COMMAND, source, this) << "to send a memo to " << nick;
- }
- else if (result == MemoServService::MEMO_INVALID_TARGET)
- source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
- else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
- else if (result == MemoServService::MEMO_TARGET_FULL)
- source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends the named \037nick\037 or \037channel\037 a memo containing\n"
- "\037memo-text\037. When sending to a nickname, the recipient will\n"
- "receive a notice that he/she has a new memo. The target\n"
- "nickname/channel must be registered."));
- return true;
- }
-};
-
-class MSSend : public Module
-{
- CommandMSSend commandmssend;
-
- public:
- MSSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmssend(this)
- {
-
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSSend)
diff --git a/modules/commands/ms_sendall.cpp b/modules/commands/ms_sendall.cpp
deleted file mode 100644
index 4cc0f350c..000000000
--- a/modules/commands/ms_sendall.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSSendAll : public Command
-{
- public:
- CommandMSSendAll(Module *creator) : Command(creator, "memoserv/sendall", 1, 1)
- {
- this->SetDesc(_("Send a memo to all registered users"));
- this->SetSyntax(_("\037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &text = params[0];
-
- Log(LOG_ADMIN, source, this) << "to send " << text;
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (nc != source.nc)
- memoserv->Send(source.GetNick(), nc->display, text);
- }
-
- source.Reply(_("A massmemo has been sent to all registered users."));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends all registered users a memo containing \037memo-text\037."));
- return true;
- }
-};
-
-class MSSendAll : public Module
-{
- CommandMSSendAll commandmssendall;
-
- public:
- MSSendAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmssendall(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSSendAll)
diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp
deleted file mode 100644
index d407132c7..000000000
--- a/modules/commands/ms_set.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 CommandMSSet : public Command
-{
- private:
- void DoNotify(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
- {
- const Anope::string &param = params[1];
- NickCore *nc = source.nc;
- BotInfo *MemoServ = Config->GetClient("MemoServ");
-
- if (!MemoServ)
- return;
-
- if (param.equals_ci("ON"))
- {
- nc->Extend<bool>("MEMO_SIGNON");
- nc->Extend<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("LOGON"))
- {
- nc->Extend<bool>("MEMO_SIGNON");
- nc->Shrink<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("NEW"))
- {
- nc->Shrink<bool>("MEMO_SIGNON");
- nc->Extend<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("MAIL"))
- {
- if (!nc->email.empty())
- {
- nc->Extend<bool>("MEMO_MAIL");
- source.Reply(_("You will now be informed about new memos via email."));
- }
- else
- source.Reply(_("There's no email address set for your nick."));
- }
- else if (param.equals_ci("NOMAIL"))
- {
- nc->Shrink<bool>("MEMO_MAIL");
- source.Reply(_("You will no longer be informed via email."));
- }
- else if (param.equals_ci("OFF"))
- {
- nc->Shrink<bool>("MEMO_SIGNON");
- nc->Shrink<bool>("MEMO_RECEIVE");
- nc->Shrink<bool>("MEMO_MAIL");
- source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- void DoLimit(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
- {
-
- Anope::string p1 = params[1];
- Anope::string p2 = params.size() > 2 ? params[2] : "";
- Anope::string p3 = params.size() > 3 ? params[3] : "";
- Anope::string user, chan;
- int16_t limit;
- NickCore *nc = source.nc;
- ChannelInfo *ci = NULL;
- bool is_servadmin = source.HasPriv("memoserv/set-limit");
-
- if (p1[0] == '#')
- {
- chan = p1;
- p1 = p2;
- p2 = p3;
- p3 = params.size() > 4 ? params[4] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!is_servadmin && !source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- if (is_servadmin)
- {
- if (!p2.empty() && !p2.equals_ci("HARD") && chan.empty())
- {
- const NickAlias *na;
- if (!(na = NickAlias::Find(p1)))
- {
- source.Reply(NICK_X_NOT_REGISTERED, p1.c_str());
- return;
- }
- user = p1;
- mi = &na->nc->memos;
- nc = na->nc;
- p1 = p2;
- p2 = p3;
- }
- else if (p1.empty() || (!p1.is_pos_number_only() && !p1.equals_ci("NONE")) || (!p2.empty() && !p2.equals_ci("HARD")))
- {
- this->OnSyntaxError(source, "");
- return;
- }
- if (!chan.empty())
- {
- if (!p2.empty())
- ci->Extend<bool>("MEMO_HARDMAX");
- else
- ci->Shrink<bool>("MEMO_HARDMAX");
- }
- else
- {
- if (!p2.empty())
- nc->Extend<bool>("MEMO_HARDMAX");
- else
- nc->Shrink<bool>("MEMO_HARDMAX");
- }
- limit = -1;
- try
- {
- limit = convertTo<int16_t>(p1);
- }
- catch (const ConvertException &) { }
- }
- else
- {
- if (p1.empty() || !p2.empty() || !isdigit(p1[0]))
- {
- this->OnSyntaxError(source, "");
- return;
- }
- if (!chan.empty() && ci->HasExt("MEMO_HARDMAX"))
- {
- source.Reply(_("The memo limit for %s may not be changed."), chan.c_str());
- return;
- }
- else if (chan.empty() && nc->HasExt("MEMO_HARDMAX"))
- {
- source.Reply(_("You are not permitted to change your memo limit."));
- return;
- }
- int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
- limit = -1;
- try
- {
- limit = convertTo<int16_t>(p1);
- }
- catch (const ConvertException &) { }
- /* The first character is a digit, but we could still go negative
- * from overflow... watch out! */
- if (limit < 0 || (max_memos > 0 && limit > max_memos))
- {
- if (!chan.empty())
- source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos);
- else
- source.Reply(_("You cannot set your memo limit higher than %d."), max_memos);
- return;
- }
- }
- mi->memomax = limit;
- if (limit > 0)
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("Your memo limit has been set to \002%d\002."), limit);
- else
- source.Reply(_("Memo limit for %s set to \002%d\002."), !chan.empty() ? chan.c_str() : user.c_str(), limit);
- }
- else if (!limit)
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("You will no longer be able to receive memos."));
- else
- source.Reply(_("Memo limit for %s set to \0020\002."), !chan.empty() ? chan.c_str() : user.c_str());
- }
- else
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("Your memo limit has been disabled."));
- else
- source.Reply(_("Memo limit \002disabled\002 for %s."), !chan.empty() ? chan.c_str() : user.c_str());
- }
- return;
- }
- public:
- CommandMSSet(Module *creator) : Command(creator, "memoserv/set", 2, 5)
- {
- this->SetDesc(_("Set options related to memos"));
- this->SetSyntax(_("\037option\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- MemoInfo *mi = &source.nc->memos;
-
- if (Anope::ReadOnly)
- source.Reply(_("Sorry, memo option setting is temporarily disabled."));
- else if (cmd.equals_ci("NOTIFY"))
- return this->DoNotify(source, params, mi);
- else if (cmd.equals_ci("LIMIT"))
- return this->DoLimit(source, params, mi);
- else
- {
- this->OnSyntaxError(source, "");
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (subcommand.empty())
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various memo options. \037option\037 can be one of:\n"
- " \n"
- " NOTIFY Changes when you will be notified about\n"
- " new memos (only for nicknames)\n"
- " LIMIT Sets the maximum number of memos you can\n"
- " receive\n"
- " \n"
- "Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
- }
- else if (subcommand.equals_ci("NOTIFY"))
- source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
- " \n"
- "Changes when you will be notified about new memos:\n"
- " \n"
- " ON You will be notified of memos when you log on,\n"
- " when you unset /AWAY, and when they are sent\n"
- " to you.\n"
- " LOGON You will only be notified of memos when you log\n"
- " on or when you unset /AWAY.\n"
- " NEW You will only be notified of memos when they\n"
- " are sent to you.\n"
- " MAIL You will be notified of memos by email as well as\n"
- " any other settings you have.\n"
- " NOMAIL You will not be notified of memos by email.\n"
- " OFF You will not receive any notification of memos.\n"
- " \n"
- "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
- else if (subcommand.equals_ci("LIMIT"))
- {
- int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
- if (source.IsServicesOper())
- source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
- " \n"
- "Sets the maximum number of memos a user or channel is\n"
- "allowed to have. Setting the limit to 0 prevents the user\n"
- "from receiving any memos; setting it to \002NONE\002 allows the\n"
- "user to receive and keep as many memos as they want. If\n"
- "you do not give a nickname or channel, your own limit is\n"
- "set.\n"
- " \n"
- "Adding \002HARD\002 prevents the user from changing the limit. Not\n"
- "adding \002HARD\002 has the opposite effect, allowing the user to\n"
- "change the limit (even if a previous limit was set with\n"
- "\002HARD\002).\n"
- " \n"
- "This use of the \002SET LIMIT\002 command is limited to \002Services\002\n"
- "\002Operators\002. Other users may only enter a limit for themselves\n"
- "or a channel on which they have such privileges, may not\n"
- "remove their limit, may not set a limit above %d, and may\n"
- "not set a hard limit."), max_memos);
- else
- source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
- " \n"
- "Sets the maximum number of memos you (or the given channel)\n"
- "are allowed to have. If you set this to 0, no one will be\n"
- "able to send any memos to you. However, you cannot set\n"
- "this any higher than %d."), max_memos);
- }
- else
- return false;
-
- return true;
- }
-};
-
-class MSSet : public Module
-{
- CommandMSSet commandmsset;
- SerializableExtensibleItem<bool> memo_signon, memo_receive, memo_mail, memo_hardmax;
-
- public:
- MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsset(this), memo_signon(this, "MEMO_SIGNON"), memo_receive(this, "MEMO_RECEIVE"), memo_mail(this, "MEMO_MAIL"),
- memo_hardmax(this, "MEMO_HARDMAX")
- {
-
- }
-};
-
-MODULE_INIT(MSSet)
diff --git a/modules/commands/ms_staff.cpp b/modules/commands/ms_staff.cpp
deleted file mode 100644
index b3554fab8..000000000
--- a/modules/commands/ms_staff.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSStaff : public Command
-{
- public:
- CommandMSStaff(Module *creator) : Command(creator, "memoserv/staff", 1, 1)
- {
- this->SetDesc(_("Send a memo to all opers/admins"));
- this->SetSyntax(_("\037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &text = params[0];
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (source.nc != nc && nc->IsServicesOper())
- memoserv->Send(source.GetNick(), nc->display, text, true);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends all services staff a memo containing \037memo-text\037."));
-
- return true;
- }
-};
-
-class MSStaff : public Module
-{
- CommandMSStaff commandmsstaff;
-
- public:
- MSStaff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsstaff(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSStaff)
diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp
deleted file mode 100644
index e54252c65..000000000
--- a/modules/commands/ns_access.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSAccess : public Command
-{
- private:
- void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- if (mask.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "32"))
- {
- source.Reply(_("Sorry, the maximum of %d access entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
- return;
- }
-
- if (nc->FindAccess(mask))
- {
- source.Reply(_("Mask \002%s\002 already present on %s's access list."), mask.c_str(), nc->display.c_str());
- return;
- }
-
- nc->AddAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->display;
- source.Reply(_("\002%s\002 added to %s's access list."), mask.c_str(), nc->display.c_str());
-
- return;
- }
-
- void DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (!nc->FindAccess(mask))
- {
- source.Reply(_("\002%s\002 not found on %s's access list."), mask.c_str(), nc->display.c_str());
- return;
- }
-
- nc->EraseAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->display;
- source.Reply(_("\002%s\002 deleted from %s's access list."), mask.c_str(), nc->display.c_str());
-
- return;
- }
-
- void DoList(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- unsigned i, end;
-
- if (nc->access.empty())
- {
- source.Reply(_("%s's access list is empty."), nc->display.c_str());
- return;
- }
-
- source.Reply(_("Access list for %s:"), nc->display.c_str());
- for (i = 0, end = nc->access.size(); i < end; ++i)
- {
- Anope::string access = nc->GetAccess(i);
- if (!mask.empty() && !Anope::Match(access, mask))
- continue;
- source.Reply(" %s", access.c_str());
- }
-
- return;
- }
- public:
- CommandNSAccess(Module *creator) : Command(creator, "nickserv/access", 1, 3)
- {
- this->SetDesc(_("Modify the list of authorized addresses"));
- this->SetSyntax(_("ADD [\037nickname\037] \037mask\037"));
- this->SetSyntax(_("DEL [\037nickname\037] \037mask\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, mask;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- {
- nick = params.size() == 3 ? params[1] : "";
- mask = params.size() > 1 ? params[params.size() - 1] : "";
- }
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/access"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
- {
- source.Reply(_("You may view but not modify the access list of other Services Operators."));
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.nc;
-
- if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos))
- {
- source.Reply(BAD_USERHOST_MASK);
- source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
- }
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc, mask);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, mask);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, mask);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Modifies or displays the access list for your nick. This\n"
- "is the list of addresses which will be automatically\n"
- "recognized by %s as allowed to use the nick. If\n"
- "you want to use the nick from a different address, you\n"
- "need to send an \002IDENTIFY\002 command to make %s\n"
- "recognize you. Services Operators may provide a nick\n"
- "to modify other users' access lists.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002ACCESS ADD anyone@*.bepeg.com\002\n"
- " Allows access to user \002anyone\002 from any machine in\n"
- " the \002bepeg.com\002 domain.\n"
- " \n"
- " \002ACCESS DEL anyone@*.bepeg.com\002\n"
- " Reverses the previous command.\n"
- " \n"
- " \002ACCESS LIST\002\n"
- " Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSAccess : public Module
-{
- CommandNSAccess commandnsaccess;
-
- public:
- NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsaccess(this)
- {
- }
-
- void OnNickRegister(User *u, NickAlias *na, const Anope::string &) anope_override
- {
- if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
- na->nc->AddAccess(u->Mask());
- }
-};
-
-MODULE_INIT(NSAccess)
diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp
deleted file mode 100644
index b62029fad..000000000
--- a/modules/commands/ns_ajoin.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-struct AJoinEntry;
-
-struct AJoinList : Serialize::Checker<std::vector<AJoinEntry *> >
-{
- AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
- ~AJoinList();
-};
-
-struct AJoinEntry : Serializable
-{
- Serialize::Reference<NickCore> owner;
- Anope::string channel;
- Anope::string key;
-
- AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
-
- ~AJoinEntry()
- {
- AJoinList *channels = owner->GetExt<AJoinList>("ajoinlist");
- if (channels)
- {
- std::vector<AJoinEntry *>::iterator it = std::find((*channels)->begin(), (*channels)->end(), this);
- if (it != (*channels)->end())
- (*channels)->erase(it);
- }
- }
-
- void Serialize(Serialize::Data &sd) const anope_override
- {
- if (!this->owner)
- return;
-
- sd["owner"] << this->owner->display;
- sd["channel"] << this->channel;
- sd["key"] << this->key;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &sd)
- {
- Anope::string sowner;
-
- sd["owner"] >> sowner;
-
- NickCore *nc = NickCore::Find(sowner);
- if (nc == NULL)
- return NULL;
-
- AJoinEntry *aj;
- if (obj)
- aj = anope_dynamic_static_cast<AJoinEntry *>(obj);
- else
- {
- aj = new AJoinEntry(nc);
- aj->owner = nc;
- }
-
- sd["channel"] >> aj->channel;
- sd["key"] >> aj->key;
-
- if (!obj)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
- (*channels)->push_back(aj);
- }
-
- return aj;
- }
-};
-
-AJoinList::~AJoinList()
-{
- for (unsigned i = 0; i < (*this)->size(); ++i)
- delete (*this)->at(i);
-}
-
-class CommandNSAJoin : public Command
-{
- void DoList(CommandSource &source, NickCore *nc)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
-
- if ((*channels)->empty())
- source.Reply(_("%s's auto join list is empty."), nc->display.c_str());
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Key"));
- for (unsigned i = 0; i < (*channels)->size(); ++i)
- {
- AJoinEntry *aj = (*channels)->at(i);
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Channel"] = aj->channel;
- entry["Key"] = aj->key;
- list.AddEntry(entry);
- }
-
- source.Reply(_("%s's auto join list:"), nc->display.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chans, const Anope::string &keys)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
-
- Anope::string addedchans;
- Anope::string alreadyadded;
- Anope::string invalidkey;
- commasepstream ksep(keys, true);
- commasepstream csep(chans);
- for (Anope::string chan, key; csep.GetToken(chan);)
- {
- ksep.GetToken(key);
-
- unsigned i = 0;
- for (; i < (*channels)->size(); ++i)
- if ((*channels)->at(i)->channel.equals_ci(chan))
- break;
-
- if ((*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"))
- {
- source.Reply(_("Sorry, the maximum of %d auto join entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"));
- return;
- }
- else if (i != (*channels)->size())
- alreadyadded += chan + ", ";
- else if (IRCD->IsChannelValid(chan) == false)
- source.Reply(CHAN_X_INVALID, chan.c_str());
- else
- {
- Channel *c = Channel::Find(chan);
- Anope::string k;
- if (c && c->GetParam("KEY", k) && key != k)
- {
- invalidkey += chan + ", ";
- continue;
- }
-
- AJoinEntry *entry = new AJoinEntry(nc);
- entry->owner = nc;
- entry->channel = chan;
- entry->key = key;
- (*channels)->push_back(entry);
- addedchans += chan + ", ";
- }
- }
-
- if (!alreadyadded.empty())
- {
- alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2);
- source.Reply(_("%s is already on %s's auto join list."), alreadyadded.c_str(), nc->display.c_str());
- }
-
- if (!invalidkey.empty())
- {
- invalidkey = invalidkey.substr(0, invalidkey.length() - 2);
- source.Reply(_("%s had an invalid key specified, and was thus ignored."), invalidkey.c_str());
- }
-
- if (addedchans.empty())
- return;
-
- addedchans = addedchans.substr(0, addedchans.length() - 2);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->display;
- source.Reply(_("%s added to %s's auto join list."), addedchans.c_str(), nc->display.c_str());
- }
-
- void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chans)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
- Anope::string delchans;
- Anope::string notfoundchans;
- commasepstream sep(chans);
-
- for (Anope::string chan; sep.GetToken(chan);)
- {
- unsigned i = 0;
- for (; i < (*channels)->size(); ++i)
- if ((*channels)->at(i)->channel.equals_ci(chan))
- break;
-
- if (i == (*channels)->size())
- notfoundchans += chan + ", ";
- else
- {
- delete (*channels)->at(i);
- delchans += chan + ", ";
- }
- }
-
- if (!notfoundchans.empty())
- {
- notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2);
- source.Reply(_("%s was not found on %s's auto join list."), notfoundchans.c_str(), nc->display.c_str());
- }
-
- if (delchans.empty())
- return;
-
- delchans = delchans.substr(0, delchans.length() - 2);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->display;
- source.Reply(_("%s was removed from %s's auto join list."), delchans.c_str(), nc->display.c_str());
-
- if ((*channels)->empty())
- nc->Shrink<AJoinList>("ajoinlist");
- }
-
- public:
- CommandNSAJoin(Module *creator) : Command(creator, "nickserv/ajoin", 1, 4)
- {
- this->SetDesc(_("Manage your auto join list"));
- this->SetSyntax(_("ADD [\037nickname\037] \037channel\037 [\037key\037]"));
- this->SetSyntax(_("DEL [\037nickname\037] \037channel\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, param, param2;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- nick = (params.size() > 2 && IRCD->IsChannelValid(params[2])) ? params[1] : "";
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasCommand("nickserv/ajoin"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- nc = na->nc;
- param = params.size() > 2 ? params[2] : "";
- param2 = params.size() > 3 ? params[3] : "";
- }
- else
- {
- nc = source.nc;
- param = params.size() > 1 ? params[1] : "";
- param2 = params.size() > 2 ? params[2] : "";
- }
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (param.empty())
- this->OnSyntaxError(source, "");
- else if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, param, param2);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, param);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command manages your auto join list. When you identify\n"
- "you will automatically join the channels on your auto join list.\n"
- "Services Operators may provide a nick to modify other users'\n"
- "auto join lists."));
- return true;
- }
-};
-
-class NSAJoin : public Module
-{
- CommandNSAJoin commandnsajoin;
- ExtensibleItem<AJoinList> ajoinlist;
- Serialize::Type ajoinentry_type;
-
- public:
- NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsajoin(this), ajoinlist(this, "ajoinlist"),
- ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize)
- {
-
- if (!IRCD || !IRCD->CanSVSJoin)
- throw ModuleException("Your IRCd does not support SVSJOIN");
-
- }
-
- void OnUserLogin(User *u) anope_override
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
- if (!NickServ)
- return;
-
- AJoinList *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
- if (channels == NULL)
- return;
-
- /* Set +r now, so we can ajoin users into +R channels */
- ModeManager::ProcessModes();
-
- for (unsigned i = 0; i < (*channels)->size(); ++i)
- {
- AJoinEntry *entry = (*channels)->at(i);
- Channel *c = Channel::Find(entry->channel);
- ChannelInfo *ci;
-
- if (c)
- ci = c->ci;
- else
- ci = ChannelInfo::Find(entry->channel);
-
- bool need_invite = false;
- Anope::string key = entry->key;
- AccessGroup u_access;
-
- if (ci != NULL)
- {
- if (ci->HasExt("CS_SUSPENDED"))
- continue;
- u_access = ci->AccessFor(u);
- }
- if (c != NULL)
- {
- if (c->FindUser(u) != NULL)
- continue;
- else if (c->HasMode("OPERONLY") && !u->HasMode("OPER"))
- continue;
- else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN"))
- continue;
- else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExt("ssl")))
- continue;
- else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false)
- need_invite = true;
- else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false)
- need_invite = true;
-
- if (c->HasMode("KEY"))
- {
- Anope::string k;
- if (c->GetParam("KEY", k))
- {
- if (u_access.HasPriv("GETKEY"))
- key = k;
- else if (key != k)
- need_invite = true;
- }
- }
- if (c->HasMode("LIMIT"))
- {
- Anope::string l;
- if (c->GetParam("LIMIT", l))
- {
- try
- {
- unsigned limit = convertTo<unsigned>(l);
- if (c->users.size() >= limit)
- need_invite = true;
- }
- catch (const ConvertException &) { }
- }
- }
- }
-
- if (need_invite && c != NULL)
- {
- if (!u_access.HasPriv("INVITE"))
- continue;
- IRCD->SendInvite(NickServ, c, u);
- }
-
- IRCD->SendSVSJoin(NickServ, u, entry->channel, key);
- }
- }
-};
-
-MODULE_INIT(NSAJoin)
diff --git a/modules/commands/ns_alist.cpp b/modules/commands/ns_alist.cpp
deleted file mode 100644
index 5f5efc7ea..000000000
--- a/modules/commands/ns_alist.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSAList : public Command
-{
- static bool ChannelSort(ChannelInfo *ci1, ChannelInfo *ci2)
- {
- return ci::less()(ci1->name, ci2->name);
- }
-
- public:
- CommandNSAList(Module *creator) : Command(creator, "nickserv/alist", 0, 2)
- {
- this->SetDesc(_("List channels you have access on"));
- this->SetSyntax(_("[\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string nick = source.GetNick();
- NickCore *nc = source.nc;
-
- if (params.size() && source.HasPriv("nickserv/alist"))
- {
- nick = params[0];
- const NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- nc = na->nc;
- }
-
- ListFormatter list(source.GetAccount());
- int chan_count = 0;
-
- list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Access")).AddColumn(_("Description"));
-
- std::deque<ChannelInfo *> queue;
- nc->GetChannelReferences(queue);
- std::sort(queue.begin(), queue.end(), ChannelSort);
-
- for (unsigned i = 0; i < queue.size(); ++i)
- {
- ChannelInfo *ci = queue[i];
- ListFormatter::ListEntry entry;
-
- if (ci->GetFounder() == nc)
- {
- ++chan_count;
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- entry["Access"] = Language::Translate(source.GetAccount(), _("Founder"));
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- continue;
- }
-
- if (ci->GetSuccessor() == nc)
- {
- ++chan_count;
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- entry["Access"] = Language::Translate(source.GetAccount(), _("Successor"));
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- continue;
- }
-
- AccessGroup access = ci->AccessFor(nc, false);
- if (access.empty())
- continue;
-
- ++chan_count;
-
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- for (unsigned j = 0; j < access.paths.size(); ++j)
- {
- ChanAccess::Path &p = access.paths[j];
-
- // not interested in indirect access
- if (p.size() != 1)
- continue;
-
- ChanAccess *a = p[0];
- entry["Access"] = entry["Access"] + ", " + a->AccessSerialize();
- }
- entry["Access"] = entry["Access"].substr(2);
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- if (!chan_count)
- {
- source.Reply(_("\002%s\002 has no access in any channels."), nc->display.c_str());
- }
- else
- {
- source.Reply(_("Channels that \002%s\002 has access on:"), nc->display.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d channels shown."), chan_count);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all channels you have access on.\n"
- " \n"
- "Channels that have the \037NOEXPIRE\037 option set will be\n"
- "prefixed by an exclamation mark. The nickname parameter is\n"
- "limited to Services Operators"));
-
- return true;
- }
-};
-
-class NSAList : public Module
-{
- CommandNSAList commandnsalist;
-
- public:
- NSAList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsalist(this)
- {
-
- }
-};
-
-MODULE_INIT(NSAList)
diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp
deleted file mode 100644
index 6fa5decab..000000000
--- a/modules/commands/ns_cert.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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/ns_cert.h"
-
-static Anope::hash_map<NickCore *> certmap;
-
-struct CertServiceImpl : CertService
-{
- CertServiceImpl(Module *o) : CertService(o) { }
-
- NickCore* FindAccountFromCert(const Anope::string &cert) anope_override
- {
- Anope::hash_map<NickCore *>::iterator it = certmap.find(cert);
- if (it != certmap.end())
- return it->second;
- return NULL;
- }
-};
-
-struct NSCertListImpl : NSCertList
-{
- Serialize::Reference<NickCore> nc;
- std::vector<Anope::string> certs;
-
- public:
- NSCertListImpl(Extensible *obj) : nc(anope_dynamic_static_cast<NickCore *>(obj)) { }
-
- ~NSCertListImpl()
- {
- ClearCert();
- }
-
- /** Add an entry to the nick's certificate list
- *
- * @param entry The fingerprint to add to the cert list
- *
- * Adds a new entry into the cert list.
- */
- void AddCert(const Anope::string &entry) anope_override
- {
- this->certs.push_back(entry);
- certmap[entry] = nc;
- FOREACH_MOD(OnNickAddCert, (this->nc, entry));
- }
-
- /** Get an entry from the nick's cert list by index
- *
- * @param entry Index in the certificaate list vector to retrieve
- * @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
- *
- * Retrieves an entry from the certificate list corresponding to the given index.
- */
- Anope::string GetCert(unsigned entry) const anope_override
- {
- if (entry >= this->certs.size())
- return "";
- return this->certs[entry];
- }
-
- unsigned GetCertCount() const anope_override
- {
- return this->certs.size();
- }
-
- /** Find an entry in the nick's cert list
- *
- * @param entry The fingerprint to search for
- * @return True if the fingerprint is found in the cert list, false otherwise
- *
- * Search for an fingerprint within the cert list.
- */
- bool FindCert(const Anope::string &entry) const anope_override
- {
- return std::find(this->certs.begin(), this->certs.end(), entry) != this->certs.end();
- }
-
- /** Erase a fingerprint from the nick's certificate list
- *
- * @param entry The fingerprint to remove
- *
- * Removes the specified fingerprint from the cert list.
- */
- void EraseCert(const Anope::string &entry) anope_override
- {
- std::vector<Anope::string>::iterator it = std::find(this->certs.begin(), this->certs.end(), entry);
- if (it != this->certs.end())
- {
- FOREACH_MOD(OnNickEraseCert, (this->nc, entry));
- certmap.erase(entry);
- this->certs.erase(it);
- }
- }
-
- /** Clears the entire nick's cert list
- *
- * Deletes all the memory allocated in the certificate list vector and then clears the vector.
- */
- void ClearCert() anope_override
- {
- FOREACH_MOD(OnNickClearCert, (this->nc));
- for (unsigned i = 0; i < certs.size(); ++i)
- certmap.erase(certs[i]);
- this->certs.clear();
- }
-
- void Check() anope_override
- {
- if (this->certs.empty())
- nc->Shrink<NSCertList>("certificates");
- }
-
- struct ExtensibleItem : ::ExtensibleItem<NSCertListImpl>
- {
- ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem<NSCertListImpl>(m, ename) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- const NickCore *n = anope_dynamic_static_cast<const NickCore *>(e);
- NSCertList *c = this->Get(n);
- if (c == NULL || !c->GetCertCount())
- return;
-
- for (unsigned i = 0; i < c->GetCertCount(); ++i)
- data["cert"] << c->GetCert(i) << " ";
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- NickCore *n = anope_dynamic_static_cast<NickCore *>(e);
- NSCertListImpl *c = this->Require(n);
-
- Anope::string buf;
- data["cert"] >> buf;
- spacesepstream sep(buf);
- for (unsigned i = 0; i < c->certs.size(); ++i)
- certmap.erase(c->certs[i]);
- c->certs.clear();
- while (sep.GetToken(buf))
- {
- c->certs.push_back(buf);
- certmap[buf] = n;
- }
- }
- };
-};
-
-class CommandNSCert : public Command
-{
- private:
- void DoAdd(CommandSource &source, NickCore *nc, Anope::string certfp)
- {
- NSCertList *cl = nc->Require<NSCertList>("certificates");
- unsigned max = Config->GetModule(this->owner)->Get<unsigned>("max", "5");
-
- if (cl->GetCertCount() >= max)
- {
- source.Reply(_("Sorry, the maximum of %d certificate entries has been reached."), max);
- return;
- }
-
- if (source.GetAccount() == nc)
- {
- User *u = source.GetUser();
-
- if (!u || u->fingerprint.empty())
- {
- source.Reply(_("You are not using a client certificate."));
- return;
- }
-
- certfp = u->fingerprint;
- }
-
- if (cl->FindCert(certfp))
- {
- source.Reply(_("Fingerprint \002%s\002 already present on %s's certificate list."), certfp.c_str(), nc->display.c_str());
- return;
- }
-
- if (certmap.find(certfp) != certmap.end())
- {
- source.Reply(_("Fingerprint \002%s\002 is already in use."), certfp.c_str());
- return;
- }
-
- cl->AddCert(certfp);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD certificate fingerprint " << certfp << " to " << nc->display;
- source.Reply(_("\002%s\002 added to %s's certificate list."), certfp.c_str(), nc->display.c_str());
- }
-
- void DoDel(CommandSource &source, NickCore *nc, Anope::string certfp)
- {
- NSCertList *cl = nc->Require<NSCertList>("certificates");
-
- if (certfp.empty())
- {
- User *u = source.GetUser();
- if (u)
- certfp = u->fingerprint;
- }
-
- if (certfp.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (!cl->FindCert(certfp))
- {
- source.Reply(_("\002%s\002 not found on %s's certificate list."), certfp.c_str(), nc->display.c_str());
- return;
- }
-
- cl->EraseCert(certfp);
- cl->Check();
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE certificate fingerprint " << certfp << " from " << nc->display;
- source.Reply(_("\002%s\002 deleted from %s's certificate list."), certfp.c_str(), nc->display.c_str());
- }
-
- void DoList(CommandSource &source, const NickCore *nc)
- {
- NSCertList *cl = nc->GetExt<NSCertList>("certificates");
-
- if (!cl || !cl->GetCertCount())
- {
- source.Reply(_("%s's certificate list is empty."), nc->display.c_str());
- return;
- }
-
- source.Reply(_("Certificate list for %s:"), nc->display.c_str());
- for (unsigned i = 0; i < cl->GetCertCount(); ++i)
- {
- Anope::string fingerprint = cl->GetCert(i);
- source.Reply(" %s", fingerprint.c_str());
- }
- }
-
- public:
- CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3)
- {
- this->SetDesc(_("Modify the nickname client certificate list"));
- this->SetSyntax(_("ADD [\037nickname\037] [\037fingerprint\037]"));
- this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, certfp;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- {
- nick = params.size() == 3 ? params[1] : "";
- certfp = params.size() > 1 ? params[params.size() - 1] : "";
- }
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/access"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
- {
- source.Reply(_("You may view but not modify the certificate list of other Services Operators."));
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.nc;
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, certfp);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, certfp);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Modifies or displays the certificate list for your nick.\n"
- "If you connect to IRC and provide a client certificate with a\n"
- "matching fingerprint in the cert list, you will be\n"
- "automatically identified to services. Services Operators\n"
- "may provide a nick to modify other users' certificate lists.\n"
- " \n"));
- source.Reply(_("Examples:\n"
- " \n"
- " \002CERT ADD\002\n"
- " Adds your current fingerprint to the certificate list and\n"
- " automatically identifies you when you connect to IRC\n"
- " using this fingerprint.\n"
- " \n"
- " \002CERT DEL <fingerprint>\002\n"
- " Removes the fingerprint <fingerprint> from your certificate list.\n"
- " \n"
- " \002CERT LIST\002\n"
- " Displays the current certificate list."));
- return true;
- }
-};
-
-class NSCert : public Module
-{
- CommandNSCert commandnscert;
- NSCertListImpl::ExtensibleItem certs;
- CertServiceImpl cs;
-
- public:
- NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnscert(this), certs(this, "certificates"), cs(this)
- {
- if (!IRCD || !IRCD->CanCertFP)
- throw ModuleException("Your IRCd does not support ssl client certificates");
- }
-
- void OnFingerprint(User *u) anope_override
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
- if (!NickServ || u->IsIdentified())
- return;
-
- NickCore *nc = cs.FindAccountFromCert(u->fingerprint);
- if (!nc || nc->HasExt("NS_SUSPENDED"))
- return;
-
- unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
- if (maxlogins && nc->users.size() >= maxlogins)
- {
- u->SendMessage(NickServ, _("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), nc->display.c_str(), maxlogins);
- return;
- }
-
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && na->nc == nc)
- u->Identify(na);
- else
- u->Login(nc);
-
- u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified to \002%s\002."), nc->display.c_str());
- Log(NickServ) << u->GetMask() << " automatically identified for account " << nc->display << " via SSL certificate fingerprint";
- }
-
- EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
- {
- NSCertList *cl = certs.Get(na->nc);
- if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
-
- unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
- if (maxlogins && na->nc->users.size() >= maxlogins)
- {
- u->SendMessage(NickServ, _("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), na->nc->display.c_str(), maxlogins);
- return EVENT_CONTINUE;
- }
-
- u->Identify(na);
-
- u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified."));
- Log(NickServ) << u->GetMask() << " automatically identified for account " << na->nc->display << " via SSL certificate fingerprint";
- return EVENT_ALLOW;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(NSCert)
diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp
deleted file mode 100644
index df632fd24..000000000
--- a/modules/commands/ns_drop.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSDrop : public Command
-{
- public:
- CommandNSDrop(Module *creator) : Command(creator, "nickserv/drop", 1, 1)
- {
- this->SetSyntax(_("\037nickname\037"));
- this->SetDesc(_("Cancel the registration of a nickname"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
-
- if (Anope::ReadOnly && !source.HasPriv("nickserv/drop"))
- {
- source.Reply(_("Sorry, nickname de-registration is temporarily disabled."));
- return;
- }
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- bool is_mine = source.GetAccount() == na->nc;
-
- if (!is_mine && !source.HasPriv("nickserv/drop"))
- source.Reply(ACCESS_DENIED);
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->nc->IsServicesOper())
- source.Reply(_("You may not drop other Services Operators' nicknames."));
- else
- {
- FOREACH_MOD(OnNickDrop, (source, na));
-
- Log(!is_mine ? LOG_ADMIN : LOG_COMMAND, source, this) << "to drop nickname " << na->nick << " (group: " << na->nc->display << ") (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")";
- delete na;
-
- source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Drops the given nick from the database. Once your nickname\n"
- "is dropped you may lose all of your access and channels that\n"
- "you may own. Any other user will be able to gain control of\n"
- "this nick."));
- if (!source.HasPriv("nickserv/drop"))
- source.Reply(_("You may drop any nick within your group."));
- else
- source.Reply(_("As a Services Operator, you may drop any nick."));
-
- return true;
- }
-};
-
-class NSDrop : public Module
-{
- CommandNSDrop commandnsdrop;
-
- public:
- NSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsdrop(this)
- {
-
- }
-};
-
-MODULE_INIT(NSDrop)
diff --git a/modules/commands/ns_getemail.cpp b/modules/commands/ns_getemail.cpp
deleted file mode 100644
index 0e782938f..000000000
--- a/modules/commands/ns_getemail.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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.
- *
- * A simple call to check for all emails that a user may have registered
- * with. It returns the nicks that match the email you provide. Wild
- * Cards are not excepted. Must use user@email-host.
- */
-
-#include "module.h"
-
-class CommandNSGetEMail : public Command
-{
- public:
- CommandNSGetEMail(Module *creator) : Command(creator, "nickserv/getemail", 1, 1)
- {
- this->SetDesc(_("Matches and returns all users that registered using given email"));
- this->SetSyntax(_("\037email\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &email = params[0];
- int j = 0;
-
- Log(LOG_ADMIN, source, this) << "on " << email;
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (!nc->email.empty() && Anope::Match(nc->email, email))
- {
- ++j;
- source.Reply(_("Email matched: \002%s\002 (\002%s\002) to \002%s\002."), nc->display.c_str(), nc->email.c_str(), email.c_str());
- }
- }
-
- if (j <= 0)
- {
- source.Reply(_("No registrations matching \002%s\002 were found."), email.c_str());
- return;
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the matching accounts that used given email."));
- return true;
- }
-};
-
-class NSGetEMail : public Module
-{
- CommandNSGetEMail commandnsgetemail;
- public:
- NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgetemail(this)
- {
-
- }
-};
-
-MODULE_INIT(NSGetEMail)
diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp
deleted file mode 100644
index ae32fc2ef..000000000
--- a/modules/commands/ns_getpass.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSGetPass : public Command
-{
- public:
- CommandNSGetPass(Module *creator) : Command(creator, "nickserv/getpass", 1, 1)
- {
- this->SetDesc(_("Retrieve the password for a nickname"));
- this->SetSyntax(_("\037nickname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- Anope::string tmp_pass;
- const NickAlias *na;
-
- if (!(na = NickAlias::Find(nick)))
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
- source.Reply(_("You may not get the password of other Services Operators."));
- else
- {
- if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1)
- {
- Log(LOG_ADMIN, source, this) << "for " << nick;
- source.Reply(_("Password for %s is \002%s\002."), nick.c_str(), tmp_pass.c_str());
- }
- else
- source.Reply(_("GETPASS command unavailable because encryption is in use."));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the password for the given nickname. \002Note\002 that\n"
- "whenever this command is used, a message including the\n"
- "person who issued the command and the nickname it was used\n"
- "on will be logged and sent out as a WALLOPS/GLOBOPS."));
- return true;
- }
-};
-
-class NSGetPass : public Module
-{
- CommandNSGetPass commandnsgetpass;
-
- public:
- NSGetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgetpass(this)
- {
-
- Anope::string tmp_pass = "plain:tmp";
- if (!Anope::Decrypt(tmp_pass, tmp_pass))
- throw ModuleException("Incompatible with the encryption module being used");
-
- }
-};
-
-MODULE_INIT(NSGetPass)
diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp
deleted file mode 100644
index 63d0dff10..000000000
--- a/modules/commands/ns_group.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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/ns_cert.h"
-
-class NSGroupRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
- Anope::string nick;
- Reference<NickAlias> target;
-
- public:
- NSGroupRequest(Module *o, CommandSource &src, Command *c, const Anope::string &n, NickAlias *targ, const Anope::string &pass) : IdentifyRequest(o, targ->nc->display, pass), source(src), cmd(c), nick(n), target(targ) { }
-
- void OnSuccess() anope_override
- {
- if (!source.GetUser() || source.GetUser()->nick != nick || !target || !target->nc)
- return;
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(nick);
- /* If the nick is already registered, drop it. */
- if (na)
- {
- FOREACH_MOD(OnChangeCoreDisplay, (na->nc, u->nick));
- delete na;
- }
-
- na = new NickAlias(nick, target->nc);
-
- Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_usermask = last_usermask;
- na->last_realname = u->realname;
- na->time_registered = na->last_seen = Anope::CurTime;
-
- u->Login(target->nc);
- FOREACH_MOD(OnNickGroup, (u, target));
-
- Log(LOG_COMMAND, source, cmd) << "to make " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
- source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str());
-
- u->lastnickreg = Anope::CurTime;
-
- }
-
- void OnFail() anope_override
- {
- if (!source.GetUser())
- return;
-
- Log(LOG_COMMAND, source, cmd) << "and failed to group to " << target->nick;
- if (NickAlias::Find(GetAccount()) != NULL)
- {
- source.Reply(PASSWORD_INCORRECT);
- source.GetUser()->BadPassword();
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
-};
-
-class CommandNSGroup : public Command
-{
- public:
- CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 0, 2)
- {
- this->SetDesc(_("Join a group"));
- this->SetSyntax(_("\037[target]\037 \037[password]\037"));
- this->AllowUnregistered(true);
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- Anope::string nick;
- if (params.empty())
- {
- NickCore* core = u->Account();
- if (core)
- nick = core->display;
- }
- else
- nick = params[0];
-
- if (nick.empty())
- {
- this->SendSyntax(source);
- return;
- }
-
- const Anope::string &pass = params.size() > 1 ? params[1] : "";
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, nickname grouping is temporarily disabled."));
- return;
- }
-
- if (!IRCD->IsNickValid(u->nick))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- if (!u->HasMode("OPER") && u->nick.find_ci(o->name) != Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- return;
- }
- }
-
- NickAlias *target, *na = NickAlias::Find(u->nick);
- const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
- time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
- unsigned maxaliases = Config->GetModule(this->owner)->Get<unsigned>("maxaliases");
- if (!(target = NickAlias::Find(nick)))
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Anope::CurTime < u->lastnickreg + reg_delay)
- source.Reply(_("Please wait %d seconds before using the GROUP command again."), (reg_delay + u->lastnickreg) - Anope::CurTime);
- else if (target->nc->HasExt("NS_SUSPENDED"))
- {
- Log(LOG_COMMAND, source, this) << "and tried to group to SUSPENDED nick " << target->nick;
- source.Reply(NICK_X_SUSPENDED, target->nick.c_str());
- }
- else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange"))
- source.Reply(_("Your nick is already registered."));
- else if (na && *target->nc == *na->nc)
- source.Reply(_("You are already a member of the group of \002%s\002."), target->nick.c_str());
- else if (na && na->nc != u->Account())
- source.Reply(NICK_IDENTIFY_REQUIRED);
- else if (maxaliases && target->nc->aliases->size() >= maxaliases && !target->nc->IsServicesOper())
- source.Reply(_("There are too many nicks in your group."));
- else if (u->nick.length() <= guestnick.length() + 7 &&
- u->nick.length() >= guestnick.length() + 1 &&
- !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890"))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- }
- else
- {
- bool ok = false;
- if (!na && u->Account() == target->nc)
- ok = true;
-
- NSCertList *cl = target->nc->GetExt<NSCertList>("certificates");
- if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
- ok = true;
-
- if (ok == false && !pass.empty())
- {
- NSGroupRequest *req = new NSGroupRequest(owner, source, this, u->nick, target, pass);
- FOREACH_MOD(OnCheckAuthentication, (source.GetUser(), req));
- req->Dispatch();
- }
- else
- {
- NSGroupRequest req(owner, source, this, u->nick, target, pass);
-
- if (ok)
- req.OnSuccess();
- else
- req.OnFail();
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command makes your nickname join the \037target\037 nickname's\n"
- "group. \037password\037 is the password of the target nickname.\n"
- " \n"
- "Joining a group will allow you to share your configuration,\n"
- "memos, and channel privileges with all the nicknames in the\n"
- "group, and much more!\n"
- " \n"
- "A group exists as long as it is useful. This means that even\n"
- "if a nick of the group is dropped, you won't lose the\n"
- "shared things described above, as long as there is at\n"
- "least one nick remaining in the group.\n"
- " \n"
- "You may be able to use this command even if you have not registered\n"
- "your nick yet. If your nick is already registered, you'll\n"
- "need to identify yourself before using this command.\n"
- " \n"
- "It is recommended to use this command with a non-registered\n"
- "nick because it will be registered automatically when\n"
- "using this command. You may use it with a registered nick (to\n"
- "change your group) only if your network administrators allowed\n"
- "it.\n"
- " \n"
- "You can only be in one group at a time. Group merging is\n"
- "not possible.\n"
- " \n"
- "\037Note\037: all the nicknames of a group have the same password."));
- return true;
- }
-};
-
-class CommandNSUngroup : public Command
-{
- public:
- CommandNSUngroup(Module *creator) : Command(creator, "nickserv/ungroup", 0, 1)
- {
- this->SetDesc(_("Remove a nick from a group"));
- this->SetSyntax(_("[\037nick\037]"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Anope::string nick = !params.empty() ? params[0] : "";
- NickAlias *na = NickAlias::Find(!nick.empty() ? nick : u->nick);
-
- if (u->Account()->aliases->size() == 1)
- source.Reply(_("Your nick is not grouped to anything, you can't ungroup it."));
- else if (!na)
- source.Reply(NICK_X_NOT_REGISTERED, !nick.empty() ? nick.c_str() : u->nick.c_str());
- else if (na->nc != u->Account())
- source.Reply(_("Nick %s is not in your group."), na->nick.c_str());
- else
- {
- NickCore *oldcore = na->nc;
-
- std::vector<NickAlias *>::iterator it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na);
- if (it != oldcore->aliases->end())
- oldcore->aliases->erase(it);
-
- if (na->nick.equals_ci(oldcore->display))
- oldcore->SetDisplay(oldcore->aliases->front());
-
- NickCore *nc = new NickCore(na->nick);
- na->nc = nc;
- nc->aliases->push_back(na);
-
- nc->pass = oldcore->pass;
- if (!oldcore->email.empty())
- nc->email = oldcore->email;
- nc->language = oldcore->language;
-
- source.Reply(_("Nick %s has been ungrouped from %s."), na->nick.c_str(), oldcore->display.c_str());
-
- User *user = User::Find(na->nick, true);
- if (user)
- /* The user on the nick who was ungrouped may be identified to the old group, set -r */
- user->RemoveMode(source.service, "REGISTERED");
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command ungroups your nick, or if given, the specificed nick,\n"
- "from the group it is in. The ungrouped nick keeps its registration\n"
- "time, password, email, greet, language, and url. Everything else\n"
- "is reset. You may not ungroup yourself if there is only one nick in\n"
- "your group."));
- return true;
- }
-};
-
-class CommandNSGList : public Command
-{
- public:
- CommandNSGList(Module *creator) : Command(creator, "nickserv/glist", 0, 1)
- {
- this->SetDesc(_("Lists all nicknames in your group"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = !params.empty() ? params[0] : "";
- const NickCore *nc;
-
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.IsServicesOper())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.GetAccount();
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Nick")).AddColumn(_("Expires"));
- time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire", "21d"),
- unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- const NickAlias *na2 = nc->aliases->at(i);
-
- Anope::string expires;
- if (na2->HasExt("NS_NO_EXPIRE"))
- expires = NO_EXPIRE;
- else if (!nickserv_expire || Anope::NoExpire)
- ;
- else if (na2->nc->HasExt("UNCONFIRMED") && unconfirmed_expire)
- expires = Anope::strftime(na2->time_registered + unconfirmed_expire, source.GetAccount());
- else
- expires = Anope::strftime(na2->last_seen + nickserv_expire, source.GetAccount());
-
- ListFormatter::ListEntry entry;
- entry["Nick"] = na2->nick;
- entry["Expires"] = expires;
- list.AddEntry(entry);
- }
-
- source.Reply(!nick.empty() ? _("List of nicknames in the group of \002%s\002:") : _("List of nicknames in your group:"), nc->display.c_str());
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("%d nickname(s) in the group."), nc->aliases->size());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (source.IsServicesOper())
- source.Reply(_("Syntax: \002%s [\037nickname\037]\002\n"
- " \n"
- "Without a parameter, lists all nicknames that are in\n"
- "your group.\n"
- " \n"
- "With a parameter, lists all nicknames that are in the\n"
- "group of the given nick.\n"
- "Specifying a nick is limited to \002Services Operators\002."),
- source.command.c_str());
- else
- source.Reply(_("Syntax: \002%s\002\n"
- " \n"
- "Lists all nicks in your group."), source.command.c_str());
-
- return true;
- }
-};
-
-class NSGroup : public Module
-{
- CommandNSGroup commandnsgroup;
- CommandNSUngroup commandnsungroup;
- CommandNSGList commandnsglist;
-
- public:
- NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgroup(this), commandnsungroup(this), commandnsglist(this)
- {
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
- }
-};
-
-MODULE_INIT(NSGroup)
diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp
deleted file mode 100644
index a188b2ee8..000000000
--- a/modules/commands/ns_identify.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 NSIdentifyRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
-
- public:
- NSIdentifyRequest(Module *o, CommandSource &s, Command *c, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(o, acc, pass), source(s), cmd(c) { }
-
- void OnSuccess() anope_override
- {
- if (!source.GetUser())
- return;
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(GetAccount());
-
- if (!na)
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- else
- {
- if (u->IsIdentified())
- Log(LOG_COMMAND, source, cmd) << "to log out of account " << u->Account()->display;
-
- Log(LOG_COMMAND, source, cmd) << "and identified for account " << na->nc->display;
- source.Reply(_("Password accepted - you are now recognized."));
- u->Identify(na);
- }
- }
-
- void OnFail() anope_override
- {
- if (source.GetUser())
- {
- bool accountexists = NickAlias::Find(GetAccount()) != NULL;
- Log(LOG_COMMAND, source, cmd) << "and failed to identify to" << (accountexists ? " " : " nonexistent ") << "account " << GetAccount();
- if (accountexists)
- {
- source.Reply(PASSWORD_INCORRECT);
- source.GetUser()->BadPassword();
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
- }
-};
-
-class CommandNSIdentify : public Command
-{
- public:
- CommandNSIdentify(Module *creator) : Command(creator, "nickserv/identify", 1, 2)
- {
- this->SetDesc(_("Identify yourself with your password"));
- this->SetSyntax(_("[\037account\037] \037password\037"));
- this->AllowUnregistered(true);
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- const Anope::string &nick = params.size() == 2 ? params[0] : u->nick;
- Anope::string pass = params[params.size() - 1];
-
- NickAlias *na = NickAlias::Find(nick);
- if (na && na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(NICK_X_SUSPENDED, na->nick.c_str());
- return;
- }
-
- if (u->Account() && na && u->Account() == na->nc)
- {
- source.Reply(_("You are already identified."));
- return;
- }
-
- unsigned int maxlogins = Config->GetModule(this->owner)->Get<unsigned int>("maxlogins");
- if (na && maxlogins && na->nc->users.size() >= maxlogins)
- {
- source.Reply(_("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), na->nc->display.c_str(), maxlogins);
- return;
- }
-
- NSIdentifyRequest *req = new NSIdentifyRequest(owner, source, this, na ? na->nc->display : nick, pass);
- FOREACH_MOD(OnCheckAuthentication, (u, req));
- req->Dispatch();
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells %s that you are really the owner of this\n"
- "nick. Many commands require you to authenticate yourself\n"
- "with this command before you use them. The password\n"
- "should be the same one you sent with the \002REGISTER\002\n"
- "command."), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSIdentify : public Module
-{
- CommandNSIdentify commandnsidentify;
-
- public:
- NSIdentify(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsidentify(this)
- {
-
- }
-};
-
-MODULE_INIT(NSIdentify)
diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp
deleted file mode 100644
index a1cdfc897..000000000
--- a/modules/commands/ns_info.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSInfo : public Command
-{
- public:
- CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2)
- {
- this->SetDesc(_("Displays information about a given nickname"));
- this->SetSyntax(_("[\037nickname\037]"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = params.size() ? params[0] : (source.nc ? source.nc->display : source.GetNick());
- NickAlias *na = NickAlias::Find(nick);
- bool has_auspex = source.HasPriv("nickserv/auspex");
-
- if (!na)
- {
- if (BotInfo::Find(nick, true))
- source.Reply(_("Nick \002%s\002 is part of this Network's Services."), nick.c_str());
- else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- }
- else
- {
- bool nick_online = false, show_hidden = false;
-
- /* Is the real owner of the nick we're looking up online? -TheShadow */
- User *u2 = User::Find(na->nick, true);
- if (u2 && u2->Account() == na->nc)
- {
- nick_online = true;
- na->last_seen = Anope::CurTime;
- }
-
- if (has_auspex || na->nc == source.GetAccount())
- show_hidden = true;
-
- source.Reply(_("%s is %s"), na->nick.c_str(), na->last_realname.c_str());
-
- if (na->nc->HasExt("UNCONFIRMED"))
- source.Reply(_("%s is an unconfirmed nickname."), na->nick.c_str());
-
- if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasExt("HIDE_STATUS")))
- source.Reply(_("%s is a Services Operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str());
-
- InfoFormatter info(source.nc);
-
- if (nick_online)
- {
- bool shown = false;
- if (show_hidden && !na->last_realhost.empty())
- {
- info[_("Online from")] = na->last_realhost;
- shown = true;
- }
- if ((show_hidden || !na->nc->HasExt("HIDE_MASK")) && (!shown || na->last_usermask != na->last_realhost))
- info[_("Online from")] = na->last_usermask;
- else
- source.Reply(_("%s is currently online."), na->nick.c_str());
- }
- else
- {
- Anope::string shown;
- if (show_hidden || !na->nc->HasExt("HIDE_MASK"))
- {
- info[_("Last seen address")] = na->last_usermask;
- shown = na->last_usermask;
- }
-
- if (show_hidden && !na->last_realhost.empty() && na->last_realhost != shown)
- info[_("Last seen address")] = na->last_realhost;
- }
-
- info[_("Registered")] = Anope::strftime(na->time_registered, source.GetAccount());
-
- if (!nick_online)
- info[_("Last seen")] = Anope::strftime(na->last_seen, source.GetAccount());
-
- if (!na->last_quit.empty() && (show_hidden || !na->nc->HasExt("HIDE_QUIT")))
- info[_("Last quit message")] = na->last_quit;
-
- if (!na->nc->email.empty() && (show_hidden || !na->nc->HasExt("HIDE_EMAIL")))
- info[_("Email address")] = na->nc->email;
-
- if (show_hidden)
- {
- if (na->HasVhost())
- {
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- info[_("VHost")] = na->GetVhostIdent() + "@" + na->GetVhostHost();
- else
- info[_("VHost")] = na->GetVhostHost();
- }
- }
-
- FOREACH_MOD(OnNickInfo, (source, na, info, show_hidden));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Displays information about the given nickname, such as\n"
- "the nick's owner, last seen address and time, and nick\n"
- "options. If no nick is given, and you are identified,\n"
- "your account name is used, else your current nickname is\n"
- "used."));
-
- return true;
- }
-};
-
-
-class CommandNSSetHide : public Command
-{
- public:
- CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Hide certain pieces of nickname information"));
- this->SetSyntax("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param, const Anope::string &arg)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Anope::string onmsg, offmsg, flag;
-
- if (param.equals_ci("EMAIL"))
- {
- flag = "HIDE_EMAIL";
- onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("USERMASK"))
- {
- flag = "HIDE_MASK";
- onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("STATUS"))
- {
- flag = "HIDE_STATUS";
- onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("QUIT"))
- {
- flag = "HIDE_QUIT";
- onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays.");
- }
- else
- {
- this->OnSyntaxError(source, "HIDE");
- return;
- }
-
- if (arg.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->display;
- nc->Extend<bool>(flag);
- source.Reply(onmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
- }
- else if (arg.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->display;
- nc->Shrink<bool>(flag);
- source.Reply(offmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "HIDE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to prevent certain pieces of information from\n"
- "being displayed when someone does a %s \002INFO\002 on your\n"
- "nick. You can hide your E-mail address (\002EMAIL\002), last seen\n"
- "user@host mask (\002USERMASK\002), your services access status\n"
- "(\002STATUS\002) and last quit message (\002QUIT\002).\n"
- "The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetHide : public CommandNSSetHide
-{
- public:
- CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3)
- {
- this->SetSyntax(_("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->ClearSyntax();
- this->Run(source, params[0], params[1], params[2]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to prevent certain pieces of information from\n"
- "being displayed when someone does a %s \002INFO\002 on the\n"
- "nick. You can hide the E-mail address (\002EMAIL\002), last seen\n"
- "user@host mask (\002USERMASK\002), the services access status\n"
- "(\002STATUS\002) and last quit message (\002QUIT\002).\n"
- "The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSInfo : public Module
-{
- CommandNSInfo commandnsinfo;
-
- CommandNSSetHide commandnssethide;
- CommandNSSASetHide commandnssasethide;
-
- SerializableExtensibleItem<bool> hide_email, hide_usermask, hide_status, hide_quit;
-
- public:
- NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsinfo(this), commandnssethide(this), commandnssasethide(this),
- hide_email(this, "HIDE_EMAIL"), hide_usermask(this, "HIDE_MASK"), hide_status(this, "HIDE_STATUS"),
- hide_quit(this, "HIDE_QUIT")
- {
-
- }
-};
-
-MODULE_INIT(NSInfo)
diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp
deleted file mode 100644
index 43e8d3f13..000000000
--- a/modules/commands/ns_list.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSList : public Command
-{
- public:
- CommandNSList(Module *creator) : Command(creator, "nickserv/list", 1, 2)
- {
- this->SetDesc(_("List all registered nicknames that match a given pattern"));
- this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- Anope::string pattern = params[0];
- const NickCore *mync;
- unsigned nnicks;
- bool is_servadmin = source.HasCommand("nickserv/list");
- int count = 0, from = 0, to = 0;
- bool suspended, nsnoexpire, unconfirmed;
- unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
-
- suspended = nsnoexpire = unconfirmed = false;
-
- if (pattern[0] == '#')
- {
- Anope::string n1, n2;
- sepstream(pattern.substr(1), '-').GetToken(n1, 0);
- sepstream(pattern, '-').GetToken(n2, 1);
- try
- {
- from = convertTo<int>(n1);
- to = convertTo<int>(n2);
- }
- catch (const ConvertException &)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- return;
- }
-
- pattern = "*";
- }
-
- nnicks = 0;
-
- if (is_servadmin && params.size() > 1)
- {
- Anope::string keyword;
- spacesepstream keywords(params[1]);
- while (keywords.GetToken(keyword))
- {
- if (keyword.equals_ci("NOEXPIRE"))
- nsnoexpire = true;
- if (keyword.equals_ci("SUSPENDED"))
- suspended = true;
- if (keyword.equals_ci("UNCONFIRMED"))
- unconfirmed = true;
- }
- }
-
- mync = source.nc;
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Nick")).AddColumn(_("Last usermask"));
-
- Anope::map<NickAlias *> ordered_map;
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- ordered_map[it->first] = it->second;
-
- for (Anope::map<NickAlias *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
- {
- const NickAlias *na = it->second;
-
- /* Don't show private nicks to non-services admins. */
- if (na->nc->HasExt("NS_PRIVATE") && !is_servadmin && na->nc != mync)
- continue;
- else if (nsnoexpire && !na->HasExt("NS_NO_EXPIRE"))
- continue;
- else if (suspended && !na->nc->HasExt("NS_SUSPENDED"))
- continue;
- else if (unconfirmed && !na->nc->HasExt("UNCONFIRMED"))
- continue;
-
- /* We no longer compare the pattern against the output buffer.
- * Instead we build a nice nick!user@host buffer to compare.
- * The output is then generated separately. -TheShadow */
- Anope::string buf = Anope::printf("%s!%s", na->nick.c_str(), !na->last_usermask.empty() ? na->last_usermask.c_str() : "*@*");
- if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true))
- {
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax)
- {
- bool isnoexpire = false;
- if (is_servadmin && na->HasExt("NS_NO_EXPIRE"))
- isnoexpire = true;
-
- ListFormatter::ListEntry entry;
- entry["Nick"] = (isnoexpire ? "!" : "") + na->nick;
- if (na->nc->HasExt("HIDE_MASK") && !is_servadmin && na->nc != mync)
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Hostname hidden]"));
- else if (na->nc->HasExt("NS_SUSPENDED"))
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
- else if (na->nc->HasExt("UNCONFIRMED"))
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Unconfirmed]"));
- else
- entry["Last usermask"] = na->last_usermask;
- list.AddEntry(entry);
- }
- ++count;
- }
- }
-
- source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks);
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all registered nicknames which match the given\n"
- "pattern, in \037nick!user@host\037 format. Nicks with the \002PRIVATE\002\n"
- "option set will only be displayed to Services Operators with the\n"
- "proper access. Nicks with the \002NOEXPIRE\002 option set will have\n"
- "a \002!\002 prefixed to the nickname for Services Operators to see.\n"
- " \n"
- "Note that a preceding '#' specifies a range.\n"
- " \n"
- "If the SUSPENDED, UNCONFIRMED or NOEXPIRE options are given, only\n"
- "nicks which, respectively, are SUSPENDED, UNCONFIRMED or have the\n"
- "NOEXPIRE flag set will be displayed. If multiple options are\n"
- "given, all nicks matching at least one option will be displayed.\n"
- "Note that these options are limited to \037Services Operators\037.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002LIST *!joeuser@foo.com\002\n"
- " Lists all registered nicks owned by joeuser@foo.com.\n"
- " \n"
- " \002LIST *Bot*!*@*\002\n"
- " Lists all registered nicks with \002Bot\002 in their\n"
- " names (case insensitive).\n"
- " \n"
- " \002LIST * NOEXPIRE\002\n"
- " Lists all registered nicks which have been set to not expire.\n"
- " \n"
- " \002LIST #51-100\002\n"
- " Lists all registered nicks within the given range (51-100)."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-
-class CommandNSSetPrivate : public Command
-{
- public:
- CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Prevent the nickname from appearing in the LIST command"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->display;
- nc->Extend<bool>("NS_PRIVATE");
- source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->display;
- nc->Shrink<bool>("NS_PRIVATE");
- source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "PRIVATE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's privacy option on or off for your nick.\n"
- "With \002PRIVATE\002 set, your nickname will not appear in\n"
- "nickname lists generated with %s's \002LIST\002 command.\n"
- "(However, anyone who knows your nickname can still get\n"
- "information on it using the \002INFO\002 command.)"),
- source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetPrivate : public CommandNSSetPrivate
-{
- public:
- CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's privacy option on or off for the nick.\n"
- "With \002PRIVATE\002 set, the nickname will not appear in\n"
- "nickname lists generated with %s's \002LIST\002 command.\n"
- "(However, anyone who knows the nickname can still get\n"
- "information on it using the \002INFO\002 command.)"),
- source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-
-class NSList : public Module
-{
- CommandNSList commandnslist;
-
- CommandNSSetPrivate commandnssetprivate;
- CommandNSSASetPrivate commandnssasetprivate;
-
- SerializableExtensibleItem<bool> priv;
-
- public:
- NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnslist(this), commandnssetprivate(this), commandnssasetprivate(this),
- priv(this, "NS_PRIVATE")
- {
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (priv.HasExt(na->nc))
- info.AddOption(_("Private"));
- }
-};
-
-MODULE_INIT(NSList)
diff --git a/modules/commands/ns_logout.cpp b/modules/commands/ns_logout.cpp
deleted file mode 100644
index 7567626e0..000000000
--- a/modules/commands/ns_logout.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<NickServService> NickServService("NickServService", "NickServ");
-
-class CommandNSLogout : public Command
-{
- public:
- CommandNSLogout(Module *creator) : Command(creator, "nickserv/logout", 0, 2)
- {
- this->SetDesc(_("Reverses the effect of the IDENTIFY command"));
- this->SetSyntax(_("[\037nickname\037 [REVALIDATE]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = !params.empty() ? params[0] : "";
- const Anope::string &param = params.size() > 1 ? params[1] : "";
-
- User *u2;
- if (!source.IsServicesOper() && !nick.empty())
- this->OnSyntaxError(source, "");
- else if (!(u2 = (!nick.empty() ? User::Find(nick, true) : source.GetUser())))
- source.Reply(NICK_X_NOT_IN_USE, !nick.empty() ? nick.c_str() : source.GetNick().c_str());
- else if (!nick.empty() && u2->IsServicesOper())
- source.Reply(_("You can't logout %s, they are a Services Operator."), nick.c_str());
- else
- {
- if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE") && NickServService)
- NickServService->Validate(u2);
-
- u2->super_admin = false; /* Don't let people logout and remain a SuperAdmin */
- Log(LOG_COMMAND, source, this) << "to logout " << u2->nick;
-
- /* Remove founder status from this user in all channels */
- if (!nick.empty())
- source.Reply(_("Nick %s has been logged out."), nick.c_str());
- else
- source.Reply(_("Your nick has been logged out."));
-
- IRCD->SendLogout(u2);
- u2->RemoveMode(source.service, "REGISTERED");
- u2->Logout();
-
- /* Send out an event */
- FOREACH_MOD(OnNickLogout, (u2));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without a parameter, reverses the effect of the \002IDENTIFY\002\n"
- "command, i.e. make you not recognized as the real owner of the nick\n"
- "anymore. Note, however, that you won't be asked to reidentify\n"
- "yourself.\n"
- " \n"
- "With a parameter, does the same for the given nick. If you\n"
- "specify \002REVALIDATE\002 as well, Services will ask the given nick\n"
- "to re-identify. This is limited to \002Services Operators\002."));
-
- return true;
- }
-};
-
-class NSLogout : public Module
-{
- CommandNSLogout commandnslogout;
-
- public:
- NSLogout(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnslogout(this)
- {
-
- }
-};
-
-MODULE_INIT(NSLogout)
diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp
deleted file mode 100644
index f41a8d782..000000000
--- a/modules/commands/ns_recover.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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/ns_cert.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-typedef std::map<Anope::string, ChannelStatus> NSRecoverInfo;
-
-class NSRecoverSvsnick
-{
- public:
- Reference<User> from;
- Anope::string to;
-};
-
-class NSRecoverRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
- Anope::string user;
-
- public:
- NSRecoverRequest(Module *o, CommandSource &src, Command *c, const Anope::string &nick, const Anope::string &pass) : IdentifyRequest(o, nick, pass), source(src), cmd(c), user(nick) { }
-
- void OnSuccess() anope_override
- {
- User *u = User::Find(user, true);
- if (!source.GetUser() || !source.service)
- return;
-
- NickAlias *na = NickAlias::Find(user);
- if (!na)
- return;
-
- Log(LOG_COMMAND, source, cmd) << "for " << na->nick;
-
- /* Nick is being held by us, release it */
- if (na->HasExt("HELD"))
- {
- nickserv->Release(na);
- source.Reply(_("Service's hold on \002%s\002 has been released."), na->nick.c_str());
- }
- else if (!u)
- {
- source.Reply(_("No one is using your nick, and services are not holding it."));
- }
- // If the user being recovered is identified for the account of the nick then the user is the
- // same person that is executing the command, so kill them off (old GHOST command).
- else if (u->Account() == na->nc)
- {
- if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
- {
- source.GetUser()->Login(u->Account());
- Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display;
- }
-
- if (Config->GetModule("ns_recover")->Get<bool>("restoreonrecover"))
- {
- if (!u->chans.empty())
- {
- NSRecoverInfo *ei = source.GetUser()->Extend<NSRecoverInfo>("recover");
- for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
- (*ei)[it->first->name] = it->second->status;
- }
- }
-
- u->SendMessage(source.service, _("This nickname has been recovered by %s. If you did not do\n"
- "this then %s may have your password, and you should change it."),
- source.GetNick().c_str(), source.GetNick().c_str());
-
- Anope::string buf = source.command.upper() + " command used by " + source.GetNick();
- u->Kill(*source.service, buf);
-
- source.Reply(_("Ghost with your nick has been killed."));
-
- if (IRCD->CanSVSNick)
- IRCD->SendForceNickChange(source.GetUser(), GetAccount(), Anope::CurTime);
- }
- /* User is not identified or not identified to the same account as the person using this command */
- else
- {
- if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
- {
- source.GetUser()->Login(na->nc); // Identify the user using the command if they arent identified
- Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->nick << " (" << na->nc->display << ")";
- source.Reply(_("You have been logged in as \002%s\002."), na->nc->display.c_str());
- }
-
- u->SendMessage(source.service, _("This nickname has been recovered by %s."), source.GetNick().c_str());
-
- if (IRCD->CanSVSNick)
- {
- NSRecoverSvsnick *svs = u->Extend<NSRecoverSvsnick>("svsnick");
- svs->from = source.GetUser();
- svs->to = u->nick;
- }
-
- if (nickserv)
- nickserv->Collide(u, na);
-
- if (IRCD->CanSVSNick)
- {
- /* If we can svsnick then release our hold and svsnick the user using the command */
- if (nickserv)
- nickserv->Release(na);
-
- source.Reply(_("You have regained control of \002%s\002."), u->nick.c_str());
- }
- else
- {
- source.Reply(_("The user with your nick has been removed. Use this command again\n"
- "to release services's hold on your nick."));
- }
- }
- }
-
- void OnFail() anope_override
- {
- if (NickAlias::Find(GetAccount()) != NULL)
- {
- source.Reply(ACCESS_DENIED);
- if (!GetPassword().empty())
- {
- Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount();
- if (source.GetUser())
- source.GetUser()->BadPassword();
- }
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
-};
-
-class CommandNSRecover : public Command
-{
- public:
- CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2)
- {
- this->SetDesc(_("Regains control of your nick"));
- this->SetSyntax(_("\037nickname\037 [\037password\037]"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- const Anope::string &pass = params.size() > 1 ? params[1] : "";
-
- User *user = User::Find(nick, true);
-
- if (user && source.GetUser() == user)
- {
- source.Reply(_("You can't %s yourself!"), source.command.lower().c_str());
- return;
- }
-
- const NickAlias *na = NickAlias::Find(nick);
-
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(NICK_X_SUSPENDED, na->nick.c_str());
- return;
- }
-
- bool ok = false;
- if (source.GetAccount() == na->nc)
- ok = true;
- else if (!na->nc->HasExt("NS_SECURE") && source.GetUser() && na->nc->IsOnAccess(source.GetUser()))
- ok = true;
-
- NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
- if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl && cl->FindCert(source.GetUser()->fingerprint))
- ok = true;
-
- if (ok == false && !pass.empty())
- {
- NSRecoverRequest *req = new NSRecoverRequest(owner, source, this, na->nick, pass);
- FOREACH_MOD(OnCheckAuthentication, (source.GetUser(), req));
- req->Dispatch();
- }
- else
- {
- NSRecoverRequest req(owner, source, this, na->nick, pass);
-
- if (ok)
- req.OnSuccess();
- else
- req.OnFail();
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Recovers your nick from another user or from services.\n"
- "If services are currently holding your nick, the hold\n"
- "will be released. If another user is holding your nick\n"
- "and is identified they will be killed (similar to the old\n"
- "GHOST command). If they are not identified they will be\n"
- "forced off of the nick."));
- return true;
- }
-};
-
-class NSRecover : public Module
-{
- CommandNSRecover commandnsrecover;
- PrimitiveExtensibleItem<NSRecoverInfo> recover;
- PrimitiveExtensibleItem<NSRecoverSvsnick> svsnick;
-
- public:
- NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsrecover(this), recover(this, "recover"), svsnick(this, "svsnick")
- {
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
-
- }
-
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
- {
- NSRecoverInfo *ei = recover.Get(u);
- BotInfo *NickServ = Config->GetClient("NickServ");
-
- if (ei != NULL && NickServ != NULL)
- for (NSRecoverInfo::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
- {
- Channel *c = Channel::Find(it->first);
- const Anope::string &cname = it->first;
- ++it;
-
- /* User might already be on the channel */
- if (u->FindChannel(c))
- this->OnJoinChannel(u, c);
- else if (IRCD->CanSVSJoin)
- IRCD->SendSVSJoin(NickServ, u, cname, "");
- }
- }
-
- NSRecoverSvsnick *svs = svsnick.Get(u);
- if (svs)
- {
- if (svs->from)
- {
- // svsnick from to to
- IRCD->SendForceNickChange(svs->from, svs->to, Anope::CurTime);
- }
-
- svsnick.Unset(u);
- }
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
- {
- NSRecoverInfo *ei = recover.Get(u);
-
- if (ei != NULL)
- {
- NSRecoverInfo::iterator it = ei->find(c->name);
- if (it != ei->end())
- {
- for (size_t i = 0; i < it->second.Modes().length(); ++i)
- c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(it->second.Modes()[i]), u->GetUID());
-
- ei->erase(it);
- if (ei->empty())
- recover.Unset(u);
- }
- }
- }
- }
-};
-
-MODULE_INIT(NSRecover)
diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp
deleted file mode 100644
index ce5dbc997..000000000
--- a/modules/commands/ns_register.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static bool SendRegmail(User *u, const NickAlias *na, BotInfo *bi);
-
-class CommandNSConfirm : public Command
-{
- public:
- CommandNSConfirm(Module *creator) : Command(creator, "nickserv/confirm", 1, 2)
- {
- this->SetDesc(_("Confirm a passcode"));
- this->SetSyntax(_("\037passcode\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &passcode = params[0];
-
- if (source.nc && !source.nc->HasExt("UNCONFIRMED") && source.HasPriv("nickserv/confirm"))
- {
- NickAlias *na = NickAlias::Find(passcode);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, passcode.c_str());
- else if (na->nc->HasExt("UNCONFIRMED") == false)
- source.Reply(_("Nick \002%s\002 is already confirmed."), na->nick.c_str());
- else
- {
- na->nc->Shrink<bool>("UNCONFIRMED");
- FOREACH_MOD(OnNickConfirm, (source.GetUser(), na->nc));
- Log(LOG_ADMIN, source, this) << "to confirm nick " << na->nick << " (" << na->nc->display << ")";
- source.Reply(_("Nick \002%s\002 has been confirmed."), na->nick.c_str());
-
- /* Login the users online already */
- for (std::list<User *>::iterator it = na->nc->users.begin(); it != na->nc->users.end(); ++it)
- {
- User *u = *it;
-
- IRCD->SendLogin(u, na);
-
- NickAlias *u_na = NickAlias::Find(u->nick);
-
- /* Set +r if they're on a nick in the group */
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && u_na && *u_na->nc == *na->nc)
- u->SetMode(source.service, "REGISTERED");
- }
- }
- }
- else if (source.nc)
- {
- Anope::string *code = source.nc->GetExt<Anope::string>("passcode");
- if (code != NULL && *code == passcode)
- {
- NickCore *nc = source.nc;
- nc->Shrink<Anope::string>("passcode");
- Log(LOG_COMMAND, source, this) << "to confirm their email";
- source.Reply(_("Your email address of \002%s\002 has been confirmed."), source.nc->email.c_str());
- nc->Shrink<bool>("UNCONFIRMED");
- FOREACH_MOD(OnNickConfirm, (source.GetUser(), nc));
-
- if (source.GetUser())
- {
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (na)
- {
- IRCD->SendLogin(source.GetUser(), na);
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && na->nc == source.GetAccount() && !na->nc->HasExt("UNCONFIRMED"))
- source.GetUser()->SetMode(source.service, "REGISTERED");
- }
- }
- }
- else
- source.Reply(_("Invalid passcode."));
- }
- else
- source.Reply(_("Invalid passcode."));
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command is used by several commands as a way to confirm\n"
- "changes made to your account.\n"
- " \n"
- "This is most commonly used to confirm your email address once\n"
- "you register or change it.\n"
- " \n"
- "This is also used after the RESETPASS command has been used to\n"
- "force identify you to your nick so you may change your password."));
- if (source.HasPriv("nickserv/confirm"))
- source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n"
- "replace \037passcode\037 with a users nick to force validate them."));
- return true;
- }
-
- void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- source.Reply(NICK_CONFIRM_INVALID);
- }
-};
-
-class CommandNSRegister : public Command
-{
- public:
- CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2)
- {
- this->SetDesc(_("Register a nickname"));
- if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- this->SetSyntax(_("\037password\037 \037email\037"));
- else
- this->SetSyntax(_("\037password\037 \037[email]\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Anope::string u_nick = source.GetNick();
- size_t nicklen = u_nick.length();
- Anope::string pass = params[0];
- Anope::string email = params.size() > 1 ? params[1] : "";
- const Anope::string &nsregister = Config->GetModule(this->owner)->Get<const Anope::string>("registration");
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, nickname registration is temporarily disabled."));
- return;
- }
-
- if (nsregister.equals_ci("disable"))
- {
- source.Reply(_("Registration is currently disabled."));
- return;
- }
-
- time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay");
- time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
- if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay)
- {
- source.Reply(_("You must have been using this nick for at least %d seconds to register."), nickregdelay);
- return;
- }
-
- /* Prevent "Guest" nicks from being registered. -TheShadow */
-
- /* Guest nick can now have a series of between 1 and 7 digits.
- * --lara
- */
- const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
- if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (!IRCD->IsNickValid(u_nick))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (BotInfo::Find(u_nick, true))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- if (!source.IsOper() && u_nick.find_ci(o->name) != Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
-
- if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty())
- this->OnSyntaxError(source, "");
- else if (u && Anope::CurTime < u->lastnickreg + reg_delay)
- source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + reg_delay) - Anope::CurTime);
- else if (NickAlias::Find(u_nick) != NULL)
- source.Reply(NICK_ALREADY_REGISTERED, u_nick.c_str());
- else if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5))
- source.Reply(MORE_OBSCURE_PASSWORD);
- else if (pass.length() > passlen)
- source.Reply(PASSWORD_TOO_LONG, passlen);
- else if (!email.empty() && !Mail::Validate(email))
- source.Reply(MAIL_X_INVALID, email.c_str());
- else
- {
- NickCore *nc = new NickCore(u_nick);
- NickAlias *na = new NickAlias(u_nick, nc);
- Anope::Encrypt(pass, nc->pass);
- if (!email.empty())
- nc->email = email;
-
- if (u)
- {
- na->last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_realname = u->realname;
- }
- else
- na->last_realname = source.GetNick();
-
- Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")";
-
- if (na->nc->GetAccessCount())
- source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str());
- else
- source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str());
-
- Anope::string tmp_pass;
- if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1)
- source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str());
-
- if (nsregister.equals_ci("admin"))
- {
- nc->Extend<bool>("UNCONFIRMED");
- // User::Identify() called below will notify the user that their registration is pending
- }
- else if (nsregister.equals_ci("mail"))
- {
- if (!email.empty())
- {
- nc->Extend<bool>("UNCONFIRMED");
- SendRegmail(NULL, na, source.service);
- }
- }
-
- FOREACH_MOD(OnNickRegister, (source.GetUser(), na, pass));
-
- if (u)
- {
- u->Identify(na);
- u->lastnickreg = Anope::CurTime;
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Registers your nickname in the %s database. Once\n"
- "your nick is registered, you can use the \002SET\002 and \002ACCESS\002\n"
- "commands to configure your nick's settings as you like\n"
- "them. Make sure you remember the password you use when\n"
- "registering - you'll need it to make changes to your nick\n"
- "later. (Note that \002case matters!\002 \037ANOPE\037, \037Anope\037, and\n"
- "\037anope\037 are all different passwords!)\n"
- " \n"
- "Guidelines on choosing passwords:\n"
- " \n"
- "Passwords should not be easily guessable. For example,\n"
- "using your real name as a password is a bad idea. Using\n"
- "your nickname as a password is a much worse idea ;) and,\n"
- "in fact, %s will not allow it. Also, short\n"
- "passwords are vulnerable to trial-and-error searches, so\n"
- "you should choose a password at least 5 characters long.\n"
- "Finally, the space character cannot be used in passwords."),
- source.service->nick.c_str(), source.service->nick.c_str());
-
- if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- {
- source.Reply(" ");
- source.Reply(_("The \037email\037 parameter is optional and will set the email\n"
- "for your nick immediately.\n"
- "Your privacy is respected; this e-mail won't be given to\n"
- "any third-party person. You may also wish to \002SET HIDE\002 it\n"
- "after registering if it isn't the default setting already."));
- }
-
- source.Reply(" ");
- source.Reply(_("This command also creates a new group for your nickname,\n"
- "that will allow you to register other nicks later sharing\n"
- "the same configuration, the same set of memos and the\n"
- "same channel privileges."));
- return true;
- }
-};
-
-class CommandNSResend : public Command
-{
- public:
- CommandNSResend(Module *creator) : Command(creator, "nickserv/resend", 0, 0)
- {
- this->SetDesc(_("Resend registration confirmation email"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(source.GetNick());
-
- if (na == NULL)
- source.Reply(NICK_NOT_REGISTERED);
- else if (na->nc != source.GetAccount() || !source.nc->HasExt("UNCONFIRMED"))
- source.Reply(_("Your account is already confirmed."));
- else
- {
- if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->owner)->Get<time_t>("resenddelay"))
- source.Reply(_("Cannot send mail now; please retry a little later."));
- else if (SendRegmail(source.GetUser(), na, source.service))
- {
- na->nc->lastmail = Anope::CurTime;
- source.Reply(_("Your passcode has been re-sent to %s."), na->nc->email.c_str());
- Log(LOG_COMMAND, source, this) << "to resend registration verification code";
- }
- else
- Log(this->owner) << "Unable to resend registration verification code for " << source.GetNick();
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- return false;
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command will resend you the registration confirmation email."));
- return true;
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- Command::OnServHelp(source);
- }
-};
-
-class NSRegister : public Module
-{
- CommandNSRegister commandnsregister;
- CommandNSConfirm commandnsconfirm;
- CommandNSResend commandnsrsend;
-
- SerializableExtensibleItem<bool> unconfirmed;
- SerializableExtensibleItem<Anope::string> passcode;
-
- public:
- NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsregister(this), commandnsconfirm(this), commandnsrsend(this), unconfirmed(this, "UNCONFIRMED"),
- passcode(this, "passcode")
- {
- if (Config->GetModule(this)->Get<const Anope::string>("registration").equals_ci("disable"))
- throw ModuleException("Module " + this->name + " will not load with registration disabled.");
- }
-
- void OnNickIdentify(User *u) anope_override
- {
- BotInfo *NickServ;
- if (unconfirmed.HasExt(u->Account()) && (NickServ = Config->GetClient("NickServ")))
- {
- const Anope::string &nsregister = Config->GetModule(this)->Get<const Anope::string>("registration");
- if (nsregister.equals_ci("admin"))
- u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
- else
- u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you."));
- const NickAlias *this_na = NickAlias::Find(u->Account()->display);
- time_t time_registered = Anope::CurTime - this_na->time_registered;
- time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
- if (unconfirmed_expire > time_registered)
- u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s."), Anope::Duration(unconfirmed_expire - time_registered, u->Account()).c_str());
- }
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- if (unconfirmed.HasExt(na->nc))
- {
- time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
- if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire)
- expire = true;
- }
- }
-};
-
-static bool SendRegmail(User *u, const NickAlias *na, BotInfo *bi)
-{
- NickCore *nc = na->nc;
-
- Anope::string *code = na->nc->GetExt<Anope::string>("passcode");
- if (code == NULL)
- {
- code = na->nc->Extend<Anope::string>("passcode");
- *code = Anope::Random(9);
- }
-
- Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_subject").c_str()),
- message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_message").c_str());
-
- subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", *code);
-
- message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", *code);
-
- return Mail::Send(u, nc, bi, subject, message);
-}
-
-MODULE_INIT(NSRegister)
diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp
deleted file mode 100644
index b1f835a01..000000000
--- a/modules/commands/ns_resetpass.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi);
-
-class CommandNSResetPass : public Command
-{
- public:
- CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 2, 2)
- {
- this->SetDesc(_("Helps you reset lost passwords"));
- this->SetSyntax(_("\037nickname\037 \037email\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const NickAlias *na;
-
- if (!(na = NickAlias::Find(params[0])))
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- else if (!na->nc->email.equals_ci(params[1]))
- source.Reply(_("Incorrect email address."));
- else
- {
- if (SendResetEmail(source.GetUser(), na, source.service))
- {
- Log(LOG_COMMAND, source, this) << "for " << na->nick << " (group: " << na->nc->display << ")";
- source.Reply(_("Password reset email for \002%s\002 has been sent."), na->nick.c_str());
- }
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends a passcode to the nickname with instructions on how to\n"
- "reset their password. Email must be the email address associated\n"
- "to the nickname."));
- return true;
- }
-};
-
-struct ResetInfo
-{
- Anope::string code;
- time_t time;
-};
-
-class NSResetPass : public Module
-{
- CommandNSResetPass commandnsresetpass;
- PrimitiveExtensibleItem<ResetInfo> reset;
-
- public:
- NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsresetpass(this), reset(this, "reset")
- {
- if (!Config->GetBlock("mail")->Get<bool>("usemail"))
- throw ModuleException("Not using mail.");
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- if (command->name == "nickserv/confirm" && params.size() > 1)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return EVENT_STOP;
- }
-
- NickAlias *na = NickAlias::Find(params[0]);
-
- ResetInfo *ri = na ? reset.Get(na->nc) : NULL;
- if (na && ri)
- {
- NickCore *nc = na->nc;
- const Anope::string &passcode = params[1];
- if (ri->time < Anope::CurTime - 3600)
- {
- reset.Unset(nc);
- source.Reply(_("Your password reset request has expired."));
- }
- else if (passcode.equals_cs(ri->code))
- {
- reset.Unset(nc);
- nc->Shrink<bool>("UNCONFIRMED");
-
- Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->nick;
-
- if (source.GetUser())
- {
- source.GetUser()->Identify(na);
- source.Reply(_("You are now identified for your nick. Change your password now."));
- }
- }
- else
- return EVENT_CONTINUE;
-
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi)
-{
- Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_subject").c_str()),
- message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_message").c_str()),
- passcode = Anope::Random(20);
-
- subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", passcode);
-
- message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", passcode);
-
- ResetInfo *ri = na->nc->Extend<ResetInfo>("reset");
- ri->code = passcode;
- ri->time = Anope::CurTime;
-
- return Mail::Send(u, na->nc, bi, subject, message);
-}
-
-MODULE_INIT(NSResetPass)
diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp
deleted file mode 100644
index f9351424e..000000000
--- a/modules/commands/ns_set.cpp
+++ /dev/null
@@ -1,1341 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSSet : public Command
-{
- public:
- CommandNSSet(Module *creator) : Command(creator, "nickserv/set", 1, 3)
- {
- this->SetDesc(_("Set options, including kill protection"));
- this->SetSyntax(_("\037option\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various nickname options. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> c("Command", info.name);
- // XXX dup
- if (!c)
- continue;
- else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
- continue;
- else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- source.command = c_name;
- c->OnServHelp(source);
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
-
- return true;
- }
-};
-
-class CommandNSSASet : public Command
-{
- public:
- CommandNSSASet(Module *creator) : Command(creator, "nickserv/saset", 2, 4)
- {
- this->SetDesc(_("Set SET-options on another nickname"));
- this->SetSyntax(_("\037option\037 \037nickname\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various nickname options. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> command("Command", info.name);
- if (command)
- {
- source.command = c_name;
- command->OnServHelp(source);
- }
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option. The options will be set on the given\n"
- "\037nickname\037."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
- return true;
- }
-};
-
-class CommandNSSetPassword : public Command
-{
- public:
- CommandNSSetPassword(Module *creator) : Command(creator, "nickserv/set/password", 1)
- {
- this->SetDesc(_("Set your nickname password"));
- this->SetSyntax(_("\037new-password\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &param = params[0];
- unsigned len = param.length();
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
- {
- source.Reply(MORE_OBSCURE_PASSWORD);
- return;
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
- if (len > passlen)
- {
- source.Reply(PASSWORD_TOO_LONG, passlen);
- return;
- }
-
- Log(LOG_COMMAND, source, this) << "to change their password";
-
- Anope::Encrypt(param, source.nc->pass);
- Anope::string tmp_pass;
- if (Anope::Decrypt(source.nc->pass, tmp_pass) == 1)
- source.Reply(_("Password for \002%s\002 changed to \002%s\002."), source.nc->display.c_str(), tmp_pass.c_str());
- else
- source.Reply(_("Password for \002%s\002 changed."), source.nc->display.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the password used to identify you as the nick's\n"
- "owner."));
- return true;
- }
-};
-
-class CommandNSSASetPassword : public Command
-{
- public:
- CommandNSSASetPassword(Module *creator) : Command(creator, "nickserv/saset/password", 2, 2)
- {
- this->SetDesc(_("Set the nickname password"));
- this->SetSyntax(_("\037nickname\037 \037new-password\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *setter_na = NickAlias::Find(params[0]);
- if (setter_na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
- NickCore *nc = setter_na->nc;
-
- size_t len = params[1].length();
-
- if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
- {
- source.Reply(_("You may not change the password of other Services Operators."));
- return;
- }
-
- if (nc->display.equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
- {
- source.Reply(MORE_OBSCURE_PASSWORD);
- return;
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
- if (len > passlen)
- {
- source.Reply(PASSWORD_TOO_LONG, passlen);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to change the password of " << nc->display;
-
- Anope::Encrypt(params[1], nc->pass);
- Anope::string tmp_pass;
- if (Anope::Decrypt(nc->pass, tmp_pass) == 1)
- source.Reply(_("Password for \002%s\002 changed to \002%s\002."), nc->display.c_str(), tmp_pass.c_str());
- else
- source.Reply(_("Password for \002%s\002 changed."), nc->display.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the password used to identify as the nick's owner."));
- return true;
- }
-};
-
-class CommandNSSetAutoOp : public Command
-{
- public:
- CommandNSSetAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Sets whether services should set channel status modes on you automatically."));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autoop for " << na->nc->display;
- nc->Extend<bool>("AUTOOP");
- source.Reply(_("Services will from now on set status modes on %s in channels."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autoop for " << na->nc->display;
- nc->Shrink<bool>("AUTOOP");
- source.Reply(_("Services will no longer set status modes on %s in channels."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "AUTOOP");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *bi = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether you will be given your channel status modes automatically.\n"
- "Set to \002ON\002 to allow %s to set status modes on you automatically\n"
- "when entering channels. Note that depending on channel settings some modes\n"
- "may not get set automatically."), bi ? bi->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandNSSASetAutoOp : public CommandNSSetAutoOp
-{
- public:
- CommandNSSASetAutoOp(Module *creator) : CommandNSSetAutoOp(creator, "nickserv/saset/autoop", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *bi = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether the given nickname will be given its status modes\n"
- "in channels automatically. Set to \002ON\002 to allow %s\n"
- "to set status modes on the given nickname automatically when it\n"
- "is entering channels. Note that depending on channel settings\n"
- "some modes may not get set automatically."), bi ? bi->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandNSSetDisplay : public Command
-{
- public:
- CommandNSSetDisplay(Module *creator, const Anope::string &sname = "nickserv/set/display", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Set the display of your group in Services"));
- this->SetSyntax(_("\037new-display\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param);
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- {
- source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
- return;
- }
- if (user_na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- else if (!na || *na->nc != *user_na->nc)
- {
- source.Reply(_("The new display MUST be a nickname of the nickname group %s."), user_na->nc->display.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, user_na->nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Log(user_na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the display of " << user_na->nc->display << " to " << na->nick;
-
- user_na->nc->SetDisplay(na);
-
- /* Send updated account name */
- for (std::list<User *>::iterator it = user_na->nc->users.begin(); it != user_na->nc->users.end(); ++it)
- {
- User *u = *it;
- IRCD->SendLogin(u, user_na);
- }
-
- source.Reply(NICK_SET_DISPLAY_CHANGED, user_na->nc->display.c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the display used to refer to your nickname group in\n"
- "Services. The new display MUST be a nick of your group."));
- return true;
- }
-};
-
-class CommandNSSASetDisplay : public CommandNSSetDisplay
-{
- public:
- CommandNSSASetDisplay(Module *creator) : CommandNSSetDisplay(creator, "nickserv/saset/display", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037new-display\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the display used to refer to the nickname group in\n"
- "Services. The new display MUST be a nick of the group."));
- return true;
- }
-};
-
-class CommandNSSetEmail : public Command
-{
- static bool SendConfirmMail(User *u, BotInfo *bi, const Anope::string &new_email)
- {
- Anope::string code = Anope::Random(9);
-
- std::pair<Anope::string, Anope::string> *n = u->Account()->Extend<std::pair<Anope::string, Anope::string> >("ns_set_email");
- n->first = new_email;
- n->second = code;
-
- Anope::string subject = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_subject"),
- message = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_message");
-
- subject = subject.replace_all_cs("%e", u->Account()->email);
- subject = subject.replace_all_cs("%E", new_email);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", code);
-
- message = message.replace_all_cs("%e", u->Account()->email);
- message = message.replace_all_cs("%E", new_email);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", code);
-
- Anope::string old = u->Account()->email;
- u->Account()->email = new_email;
- bool b = Mail::Send(u, u->Account(), bi, subject, message);
- u->Account()->email = old;
- return b;
- }
-
- public:
- CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1)
- {
- this->SetDesc(_("Associate an E-mail address with your nickname"));
- this->SetSyntax(_("\037address\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- if (nc->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You may not change the email of an unconfirmed account."));
- return;
- }
-
- if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- {
- source.Reply(_("You cannot unset the e-mail on this network."));
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
- {
- source.Reply(_("You may not change the e-mail of other Services Operators."));
- return;
- }
- else if (!param.empty() && !Mail::Validate(param))
- {
- source.Reply(MAIL_X_INVALID, param.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("confirmemailchanges") && !source.IsServicesOper())
- {
- if (SendConfirmMail(source.GetUser(), source.service, param))
- source.Reply(_("A confirmation e-mail has been sent to \002%s\002. Follow the instructions in it to change your e-mail address."), param.c_str());
- }
- else
- {
- if (!param.empty())
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the email of " << nc->display << " to " << param;
- nc->email = param;
- source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
- }
- else
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the email of " << nc->display;
- nc->email.clear();
- source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str());
- }
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params.size() ? params[0] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Associates the given E-mail address with your nickname.\n"
- "This address will be displayed whenever someone requests\n"
- "information on the nickname with the \002INFO\002 command."));
- return true;
- }
-};
-
-class CommandNSSASetEmail : public CommandNSSetEmail
-{
- public:
- CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037address\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Associates the given E-mail address with the nickname."));
- return true;
- }
-};
-
-class CommandNSSetKeepModes : public Command
-{
- public:
- CommandNSSetKeepModes(Module *creator, const Anope::string &sname = "nickserv/set/keepmodes", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Enable or disable keep modes"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable keepmodes for " << nc->display;
- nc->Extend<bool>("NS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002on\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable keepmodes for " << nc->display;
- nc->Shrink<bool>("NS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002off\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for your nick. If keep\n"
- "modes is enabled, services will remember your usermodes\n"
- "and attempt to re-set them the next time you authenticate."));
- return true;
- }
-};
-
-class CommandNSSASetKeepModes : public CommandNSSetKeepModes
-{
- public:
- CommandNSSASetKeepModes(Module *creator) : CommandNSSetKeepModes(creator, "nickserv/saset/keepmodes", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for the given nick. If keep\n"
- "modes is enabled, services will remember users' usermodes\n"
- "and attempt to re-set them the next time they authenticate."));
- return true;
- }
-};
-
-class CommandNSSetKill : public Command
-{
- public:
- CommandNSSetKill(Module *creator, const Anope::string &sname = "nickserv/set/kill", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Turn protection on or off"));
- this->SetSyntax("{ON | QUICK | IMMED | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- {
- source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill on for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("QUICK"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Extend<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill quick for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str());
- }
- else if (param.equals_ci("IMMED"))
- {
- if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Extend<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill immed for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str());
- }
- else
- source.Reply(_("The \002IMMED\002 option is not available on this network."));
- }
- else if (param.equals_ci("OFF"))
- {
- nc->Shrink<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable kill for " << nc->display;
- source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "KILL");
-
- return;
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns the automatic protection option for your nick\n"
- "on or off. With protection on, if another user\n"
- "tries to take your nick, they will be given one minute to\n"
- "change to another nick, after which %s will forcibly change\n"
- "their nick.\n"
- " \n"
- "If you select \002QUICK\002, the user will be given only 20 seconds\n"
- "to change nicks instead of the usual 60. If you select\n"
- "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
- "warned first or given a chance to change their nick; please\n"
- "do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetKill : public CommandNSSetKill
-{
- public:
- CommandNSSASetKill(Module *creator) : CommandNSSetKill(creator, "nickserv/saset/kill", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | QUICK | IMMED | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns the automatic protection option for the nick\n"
- "on or off. With protection on, if another user\n"
- "tries to take the nick, they will be given one minute to\n"
- "change to another nick, after which %s will forcibly change\n"
- "their nick.\n"
- " \n"
- "If you select \002QUICK\002, the user will be given only 20 seconds\n"
- "to change nicks instead of the usual 60. If you select\n"
- "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
- "warned first or given a chance to change their nick; please\n"
- "do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSetLanguage : public Command
-{
- public:
- CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Set the language Services will use when messaging you"));
- this->SetSyntax(_("\037language\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param != "en_US")
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- if (Language::Languages[j] == param)
- break;
- else if (j + 1 == Language::Languages.size())
- {
- this->OnSyntaxError(source, "");
- return;
- }
- }
-
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the language of " << nc->display << " to " << param;
-
- nc->language = param;
- if (source.GetAccount() == nc)
- source.Reply(_("Language changed to \002English\002."));
- else
- source.Reply(_("Language for \002%s\002 changed to \002%s\002."), nc->display.c_str(), Language::Translate(param.c_str(), _("English")));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &param) anope_override
- {
- this->Run(source, source.nc->display, param[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the language Services uses when sending messages to\n"
- "you (for example, when responding to a command you send).\n"
- "\037language\037 should be chosen from the following list of\n"
- "supported languages:"));
-
- source.Reply(" en_US (English)");
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
- if (langname == "English")
- continue;
- source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
- }
-
- return true;
- }
-};
-
-class CommandNSSASetLanguage : public CommandNSSetLanguage
-{
- public:
- CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037language\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the language Services uses when sending messages to\n"
- "the given user (for example, when responding to a command they send).\n"
- "\037language\037 should be chosen from the following list of\n"
- "supported languages:"));
- source.Reply(" en (English)");
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
- if (langname == "English")
- continue;
- source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
- }
- return true;
- }
-};
-
-class CommandNSSetMessage : public Command
-{
- public:
- CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Change the communication method of Services"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
- {
- source.Reply(_("You cannot %s on this network."), source.command.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display;
- nc->Extend<bool>("MSG");
- source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display;
- nc->Shrink<bool>("MSG");
- source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "MSG");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- Anope::string cmd = source.command;
- size_t i = cmd.find_last_of(' ');
- if (i != Anope::string::npos)
- cmd = cmd.substr(i + 1);
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to choose the way Services are communicating with\n"
- "you. With \002%s\002 set, Services will use messages, else they'll\n"
- "use notices."), cmd.upper().c_str());
- return true;
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
- Command::OnServHelp(source);
- }
-};
-
-class CommandNSSASetMessage : public CommandNSSetMessage
-{
- public:
- CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to choose the way Services are communicating with\n"
- "the given user. With \002MSG\002 set, Services will use messages,\n"
- "else they'll use notices."));
- return true;
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-};
-
-class CommandNSSetSecure : public Command
-{
- public:
- CommandNSSetSecure(Module *creator, const Anope::string &sname = "nickserv/set/secure", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Turn nickname security on or off"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable secure for " << nc->display;
- nc->Extend<bool>("NS_SECURE");
- source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable secure for " << nc->display;
- nc->Shrink<bool>("NS_SECURE");
- source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "SECURE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's security features on or off for your\n"
- "nick. With \002SECURE\002 set, you must enter your password\n"
- "before you will be recognized as the owner of the nick,\n"
- "regardless of whether your address is on the access\n"
- "list. However, if you are on the access list, %s\n"
- "will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetSecure : public CommandNSSetSecure
-{
- public:
- CommandNSSASetSecure(Module *creator) : CommandNSSetSecure(creator, "nickserv/saset/secure", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's security features on or off for your\n"
- "nick. With \002SECURE\002 set, you must enter your password\n"
- "before you will be recognized as the owner of the nick,\n"
- "regardless of whether your address is on the access\n"
- "list. However, if you are on the access list, %s\n"
- "will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetNoexpire : public Command
-{
- public:
- CommandNSSASetNoexpire(Module *creator) : Command(creator, "nickserv/saset/noexpire", 1, 2)
- {
- this->SetDesc(_("Prevent the nickname from expiring"));
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *na = NickAlias::Find(params[0]);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- Anope::string param = params.size() > 1 ? params[1] : "";
-
- if (param.equals_ci("ON"))
- {
- Log(LOG_ADMIN, source, this) << "to enable noexpire for " << na->nick << " (" << na->nc->display << ")";
- na->Extend<bool>("NS_NO_EXPIRE");
- source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(LOG_ADMIN, source, this) << "to disable noexpire for " << na->nick << " (" << na->nc->display << ")";
- na->Shrink<bool>("NS_NO_EXPIRE");
- source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "NOEXPIRE");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether the given nickname will expire. Setting this\n"
- "to \002ON\002 prevents the nickname from expiring."));
- return true;
- }
-};
-
-class NSSet : public Module
-{
- CommandNSSet commandnsset;
- CommandNSSASet commandnssaset;
-
- CommandNSSetAutoOp commandnssetautoop;
- CommandNSSASetAutoOp commandnssasetautoop;
-
- CommandNSSetDisplay commandnssetdisplay;
- CommandNSSASetDisplay commandnssasetdisplay;
-
- CommandNSSetEmail commandnssetemail;
- CommandNSSASetEmail commandnssasetemail;
-
- CommandNSSetKeepModes commandnssetkeepmodes;
- CommandNSSASetKeepModes commandnssasetkeepmodes;
-
- CommandNSSetKill commandnssetkill;
- CommandNSSASetKill commandnssasetkill;
-
- CommandNSSetLanguage commandnssetlanguage;
- CommandNSSASetLanguage commandnssasetlanguage;
-
- CommandNSSetMessage commandnssetmessage;
- CommandNSSASetMessage commandnssasetmessage;
-
- CommandNSSetPassword commandnssetpassword;
- CommandNSSASetPassword commandnssasetpassword;
-
- CommandNSSetSecure commandnssetsecure;
- CommandNSSASetSecure commandnssasetsecure;
-
- CommandNSSASetNoexpire commandnssasetnoexpire;
-
- SerializableExtensibleItem<bool> autoop, killprotect, kill_quick, kill_immed,
- message, secure, noexpire;
-
- struct KeepModes : SerializableExtensibleItem<bool>
- {
- KeepModes(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleSerialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- const NickCore *nc = anope_dynamic_static_cast<const NickCore *>(s);
- Anope::string modes;
- for (User::ModeList::const_iterator it = nc->last_modes.begin(); it != nc->last_modes.end(); ++it)
- {
- if (!modes.empty())
- modes += " ";
- modes += it->first;
- if (!it->second.empty())
- modes += "," + it->second;
- }
- data["last_modes"] << modes;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- NickCore *nc = anope_dynamic_static_cast<NickCore *>(s);
- Anope::string modes;
- data["last_modes"] >> modes;
- for (spacesepstream sep(modes); sep.GetToken(modes);)
- {
- size_t c = modes.find(',');
- if (c == Anope::string::npos)
- nc->last_modes.insert(std::make_pair(modes, ""));
- else
- nc->last_modes.insert(std::make_pair(modes.substr(0, c), modes.substr(c + 1)));
- }
- }
- } keep_modes;
-
- /* email, passcode */
- PrimitiveExtensibleItem<std::pair<Anope::string, Anope::string > > ns_set_email;
-
- public:
- NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsset(this), commandnssaset(this),
- commandnssetautoop(this), commandnssasetautoop(this),
- commandnssetdisplay(this), commandnssasetdisplay(this),
- commandnssetemail(this), commandnssasetemail(this),
- commandnssetkeepmodes(this), commandnssasetkeepmodes(this),
- commandnssetkill(this), commandnssasetkill(this),
- commandnssetlanguage(this), commandnssasetlanguage(this),
- commandnssetmessage(this), commandnssasetmessage(this),
- commandnssetpassword(this), commandnssasetpassword(this),
- commandnssetsecure(this), commandnssasetsecure(this),
- commandnssasetnoexpire(this),
-
- autoop(this, "AUTOOP"),
- killprotect(this, "KILLPROTECT"), kill_quick(this, "KILL_QUICK"),
- kill_immed(this, "KILL_IMMED"), message(this, "MSG"),
- secure(this, "NS_SECURE"), noexpire(this, "NS_NO_EXPIRE"),
-
- keep_modes(this, "NS_KEEP_MODES"), ns_set_email(this, "ns_set_email")
- {
-
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- NickCore *uac = source.nc;
-
- if (command->name == "nickserv/confirm" && !params.empty() && uac)
- {
- std::pair<Anope::string, Anope::string> *n = ns_set_email.Get(uac);
- if (n)
- {
- if (params[0] == n->second)
- {
- uac->email = n->first;
- Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email;
- source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str());
- ns_set_email.Unset(uac);
- return EVENT_STOP;
- }
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
- {
- if (chan->ci)
- {
- /* Only give modes if autoop is set */
- give_modes &= !user->Account() || autoop.HasExt(user->Account());
- }
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- if (noexpire.HasExt(na))
- expire = false;
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!show_hidden)
- return;
-
- if (kill_immed.HasExt(na->nc))
- info.AddOption(_("Immediate protection"));
- else if (kill_quick.HasExt(na->nc))
- info.AddOption(_("Quick protection"));
- else if (killprotect.HasExt(na->nc))
- info.AddOption(_("Protection"));
- if (secure.HasExt(na->nc))
- info.AddOption(_("Security"));
- if (message.HasExt(na->nc))
- info.AddOption(_("Message mode"));
- if (autoop.HasExt(na->nc))
- info.AddOption(_("Auto-op"));
- if (noexpire.HasExt(na))
- info.AddOption(_("No expire"));
- if (keep_modes.HasExt(na->nc))
- info.AddOption(_("Keep modes"));
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (u->Account() && setter.GetUser() == u)
- u->Account()->last_modes = u->GetModeList();
- }
-
- void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (u->Account() && setter.GetUser() == u)
- u->Account()->last_modes = u->GetModeList();
- }
-
- void OnUserLogin(User *u) anope_override
- {
- if (keep_modes.HasExt(u->Account()))
- {
- User::ModeList modes = u->Account()->last_modes;
- for (User::ModeList::iterator it = modes.begin(); it != modes.end(); ++it)
- {
- UserMode *um = ModeManager::FindUserModeByName(it->first);
- /* if the null user can set the mode, then it's probably safe */
- if (um && um->CanSet(NULL))
- u->SetMode(NULL, it->first, it->second);
- }
- }
- }
-};
-
-MODULE_INIT(NSSet)
diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp
deleted file mode 100644
index c145e386c..000000000
--- a/modules/commands/ns_set_misc.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- *
- * (C) 2003-2016 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/set_misc.h"
-
-static Module *me;
-
-static Anope::map<Anope::string> descriptions;
-
-struct NSMiscData;
-static Anope::map<ExtensibleItem<NSMiscData> *> items;
-
-static ExtensibleItem<NSMiscData> *GetItem(const Anope::string &name)
-{
- ExtensibleItem<NSMiscData>* &it = items[name];
- if (!it)
- try
- {
- it = new ExtensibleItem<NSMiscData>(me, name);
- }
- catch (const ModuleException &) { }
- return it;
-}
-
-struct NSMiscData : MiscData, Serializable
-{
- NSMiscData(Extensible *) : Serializable("NSMiscData") { }
-
- NSMiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : Serializable("NSMiscData")
- {
- object = ncore->display;
- name = n;
- data = d;
- }
-
- void Serialize(Serialize::Data &sdata) const anope_override
- {
- sdata["nc"] << this->object;
- sdata["name"] << this->name;
- sdata["data"] << this->data;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snc, sname, sdata;
-
- data["nc"] >> snc;
- data["name"] >> sname;
- data["data"] >> sdata;
-
- NickCore *nc = NickCore::Find(snc);
- if (nc == NULL)
- return NULL;
-
- NSMiscData *d = NULL;
- if (obj)
- {
- d = anope_dynamic_static_cast<NSMiscData *>(obj);
- d->object = nc->display;
- data["name"] >> d->name;
- data["data"] >> d->data;
- }
- else
- {
- ExtensibleItem<NSMiscData> *item = GetItem(sname);
- if (item)
- d = item->Set(nc, NSMiscData(nc, sname, sdata));
- }
-
- return d;
- }
-};
-
-static Anope::string GetAttribute(const Anope::string &command)
-{
- size_t sp = command.rfind(' ');
- if (sp != Anope::string::npos)
- return command.substr(sp + 1);
- return command;
-}
-
-class CommandNSSetMisc : public Command
-{
- public:
- CommandNSSetMisc(Module *creator, const Anope::string &cname = "nickserv/set/misc", size_t min = 0) : Command(creator, cname, min, min + 1)
- {
- this->SetSyntax(_("[\037parameter\037]"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Anope::string scommand = GetAttribute(source.command);
- Anope::string key = "ns_set_misc:" + scommand;
- ExtensibleItem<NSMiscData> *item = GetItem(key);
- if (item == NULL)
- return;
-
- if (!param.empty())
- {
- item->Set(nc, NSMiscData(nc, key, param));
- source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), nc->display.c_str(), param.c_str());
- }
- else
- {
- item->Unset(nc);
- source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), nc->display.c_str());
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, !params.empty() ? params[0] : "");
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (descriptions.count(source.command))
- {
- this->SetDesc(descriptions[source.command]);
- Command::OnServHelp(source);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (descriptions.count(source.command))
- {
- source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
- return true;
- }
- return false;
- }
-};
-
-class CommandNSSASetMisc : public CommandNSSetMisc
-{
- public:
- CommandNSSASetMisc(Module *creator) : CommandNSSetMisc(creator, "nickserv/saset/misc", 1)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 [\037parameter\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-};
-
-class NSSetMisc : public Module
-{
- CommandNSSetMisc commandnssetmisc;
- CommandNSSASetMisc commandnssasetmisc;
- Serialize::Type nsmiscdata_type;
-
- public:
- NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnssetmisc(this), commandnssasetmisc(this), nsmiscdata_type("NSMiscData", NSMiscData::Unserialize)
- {
- me = this;
- }
-
- ~NSSetMisc()
- {
- for (Anope::map<ExtensibleItem<NSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- delete it->second;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- descriptions.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- const Anope::string &cmd = block->Get<const Anope::string>("command");
-
- if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc")
- continue;
-
- Anope::string cname = block->Get<const Anope::string>("name");
- Anope::string desc = block->Get<const Anope::string>("misc_description");
-
- if (cname.empty() || desc.empty())
- continue;
-
- descriptions[cname] = desc;
- }
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool) anope_override
- {
- for (Anope::map<ExtensibleItem<NSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- {
- ExtensibleItem<NSMiscData> *e = it->second;
- NSMiscData *data = e->Get(na->nc);
-
- if (data != NULL)
- info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
- }
- }
-};
-
-MODULE_INIT(NSSetMisc)
diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp
deleted file mode 100644
index 76b79d1d1..000000000
--- a/modules/commands/ns_suspend.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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/suspend.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-struct NSSuspendInfo : SuspendInfo, Serializable
-{
- NSSuspendInfo(Extensible *) : Serializable("NSSuspendInfo") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["nick"] << what;
- data["by"] << by;
- data["reason"] << reason;
- data["time"] << when;
- data["expires"] << expires;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snick;
- data["nick"] >> snick;
-
- NSSuspendInfo *si;
- if (obj)
- si = anope_dynamic_static_cast<NSSuspendInfo *>(obj);
- else
- {
- NickAlias *na = NickAlias::Find(snick);
- if (!na)
- return NULL;
- si = na->nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
- data["nick"] >> si->what;
- }
-
- data["by"] >> si->by;
- data["reason"] >> si->reason;
- data["time"] >> si->when;
- data["expires"] >> si->expires;
- return si;
- }
-};
-
-class CommandNSSuspend : public Command
-{
- public:
- CommandNSSuspend(Module *creator) : Command(creator, "nickserv/suspend", 2, 3)
- {
- this->SetDesc(_("Suspend a given nick"));
- this->SetSyntax(_("\037nickname\037 [+\037expiry\037] [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = params[0];
- Anope::string expiry = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire");
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (expiry[0] != '+')
- {
- reason = expiry + " " + reason;
- reason.trim();
- expiry.clear();
- }
- else
- {
- expiry_secs = Anope::DoTime(expiry);
- if (expiry_secs == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- }
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
- {
- source.Reply(_("You may not suspend other Services Operators' nicknames."));
- return;
- }
-
- if (na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(_("\002%s\002 is already suspended."), na->nc->display.c_str());
- return;
- }
-
- NickCore *nc = na->nc;
-
- NSSuspendInfo *si = nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
- si->what = nc->display;
- si->by = source.GetNick();
- si->reason = reason;
- si->when = Anope::CurTime;
- si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
-
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- NickAlias *na2 = nc->aliases->at(i);
-
- if (na2 && *na2->nc == *na->nc)
- {
- na2->last_quit = reason;
-
- User *u2 = User::Find(na2->nick, true);
- if (u2)
- {
- u2->Logout();
- if (nickserv)
- nickserv->Collide(u2, na2);
- }
- }
- }
-
- Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
- source.Reply(_("Nick %s is now suspended."), nick.c_str());
-
- FOREACH_MOD(OnNickSuspend, (na));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Suspends a registered nickname, which prevents it from being used\n"
- "while keeping all the data for that nick. If an expiry is given\n"
- "the nick will be unsuspended after that period of time, else the\n"
- "default expiry from the configuration is used."));
- return true;
- }
-};
-
-class CommandNSUnSuspend : public Command
-{
- public:
- CommandNSUnSuspend(Module *creator) : Command(creator, "nickserv/unsuspend", 1, 1)
- {
- this->SetDesc(_("Unsuspend a given nick"));
- this->SetSyntax(_("\037nickname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- if (!na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(_("Nick %s is not suspended."), na->nick.c_str());
- return;
- }
-
- NSSuspendInfo *si = na->nc->GetExt<NSSuspendInfo>("NS_SUSPENDED");
-
- Log(LOG_ADMIN, source, this) << "for " << na->nick << " which was suspended by " << (!si->by.empty() ? si->by : "(none)") << " for: " << (!si->reason.empty() ? si->reason : "No reason");
-
- na->nc->Shrink<NSSuspendInfo>("NS_SUSPENDED");
-
- source.Reply(_("Nick %s is now released."), nick.c_str());
-
- FOREACH_MOD(OnNickUnsuspended, (na));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Unsuspends a nickname which allows it to be used again."));
- return true;
- }
-};
-
-class NSSuspend : public Module
-{
- CommandNSSuspend commandnssuspend;
- CommandNSUnSuspend commandnsunsuspend;
- ExtensibleItem<NSSuspendInfo> suspend;
- Serialize::Type suspend_type;
- std::vector<Anope::string> show;
-
- struct trim
- {
- Anope::string operator()(Anope::string s) const
- {
- return s.trim();
- }
- };
-
- bool Show(CommandSource &source, const Anope::string &what) const
- {
- return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
- }
-
- public:
- NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"),
- suspend_type("NSSuspendInfo", NSSuspendInfo::Unserialize)
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Anope::string s = conf->GetModule(this)->Get<Anope::string>("show");
- commasepstream(s).GetTokens(show);
- std::transform(show.begin(), show.end(), show.begin(), trim());
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return;
-
- if (show_hidden || Show(source, "suspended"))
- info[_("Suspended")] = _("This nickname is \002suspended\002.");
- if (!s->by.empty() && (show_hidden || Show(source, "by")))
- info[_("Suspended by")] = s->by;
- if (!s->reason.empty() && (show_hidden || Show(source, "reason")))
- info[_("Suspend reason")] = s->reason;
- if (s->when && (show_hidden || Show(source, "on")))
- info[_("Suspended on")] = Anope::strftime(s->when, source.GetAccount());
- if (s->expires && (show_hidden || Show(source, "expires")))
- info[_("Suspension expires")] = Anope::strftime(s->expires, source.GetAccount());
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return;
-
- expire = false;
-
- if (!s->expires)
- return;
-
- if (s->expires < Anope::CurTime)
- {
- na->last_seen = Anope::CurTime;
- suspend.Unset(na->nc);
-
- Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
- }
- }
-
- EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return EVENT_CONTINUE;
-
- u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
- return EVENT_STOP;
- }
-};
-
-MODULE_INIT(NSSuspend)
diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp
deleted file mode 100644
index fcbe02f21..000000000
--- a/modules/commands/ns_update.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 CommandNSUpdate : public Command
-{
- public:
- CommandNSUpdate(Module *creator) : Command(creator, "nickserv/update", 0, 0)
- {
- this->SetDesc(_("Updates your current status, i.e. it checks for new memos"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(u->nick);
-
- if (na && na->nc == source.GetAccount())
- {
- na->last_realname = u->realname;
- na->last_seen = Anope::CurTime;
- }
-
- FOREACH_MOD(OnNickUpdate, (u));
-
- source.Reply(_("Status updated (memos, vhost, chmodes, flags)."));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Updates your current status, i.e. it checks for new memos,\n"
- "sets needed channel modes and updates your vhost and\n"
- "your userflags (lastseentime, etc)."));
- return true;
- }
-};
-
-class NSUpdate : public Module
-{
- CommandNSUpdate commandnsupdate;
-
- public:
- NSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsupdate(this)
- {
-
- }
-};
-
-MODULE_INIT(NSUpdate)
diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp
deleted file mode 100644
index 08bbc79ac..000000000
--- a/modules/commands/os_akill.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
-
-class AkillDelCallback : public NumberList
-{
- CommandSource &source;
- unsigned deleted;
- Command *cmd;
- public:
- AkillDelCallback(CommandSource &_source, const Anope::string &numlist, Command *c) : NumberList(numlist, true), source(_source), deleted(0), cmd(c)
- {
- }
-
- ~AkillDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on the AKILL list."));
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from the AKILL list."));
- else
- source.Reply(_("Deleted %d entries from the AKILL list."), deleted);
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- XLine *x = akills->GetEntry(number - 1);
-
- if (!x)
- return;
-
- Log(LOG_ADMIN, source, cmd) << "to remove " << x->mask << " from the list";
-
- ++deleted;
- DoDel(source, x);
- }
-
- static void DoDel(CommandSource &source, XLine *x)
- {
- akills->DelXLine(x);
- }
-};
-
-class CommandOSAKill : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string expiry, mask;
-
- if (params.size() < 2)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- spacesepstream sep(params[1]);
- sep.GetToken(mask);
-
- if (mask[0] == '+')
- {
- expiry = mask;
- sep.GetToken(mask);
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (sep.StreamEnd())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason;
- if (mask.find('#') != Anope::string::npos)
- {
- Anope::string remaining = sep.GetRemaining();
-
- size_t co = remaining[0] == ':' ? 0 : remaining.rfind(" :");
- if (co == Anope::string::npos)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (co != 0)
- ++co;
-
- reason = remaining.substr(co + 1);
- mask += " " + remaining.substr(0, co);
- mask.trim();
- }
- else
- reason = sep.GetRemaining();
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- User *targ = User::Find(mask, true);
- if (targ)
- mask = "*@" + targ->host;
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("/~@.*?") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
- else if (mask.find('@') == Anope::string::npos)
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (akills->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to akill " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!akills->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, akills));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- akills->AddXLine(x);
- if (Config->GetModule("operserv")->Get<bool>("akillonadd"))
- akills->Send(NULL, x);
-
- source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
-
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << x->reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- AkillDelCallback list(source, mask, this);
- list.Process();
- }
- else
- {
- XLine *x = akills->HasEntry(mask);
-
- if (!x)
- {
- source.Reply(_("\002%s\002 not found on the AKILL list."), mask.c_str());
- return;
- }
-
- do
- {
- FOREACH_MOD(OnDelXLine, (source, x, akills));
-
- Log(LOG_ADMIN, source, this) << "to remove " << x->mask << " from the list";
- source.Reply(_("\002%s\002 deleted from the AKILL list."), x->mask.c_str());
- AkillDelCallback::DoDel(source, x);
- }
- while ((x = akills->HasEntry(mask)));
-
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class ListCallback : public NumberList
- {
- CommandSource &source;
- ListFormatter &list;
- public:
- ListCallback(CommandSource &_source, ListFormatter &_list, const Anope::string &numstr) : NumberList(numstr, false), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- const XLine *x = akills->GetEntry(number - 1);
-
- if (!x)
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Mask"] = x->mask;
- entry["Creator"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(source, list, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
- {
- const XLine *x = akills->GetEntry(i);
-
- if (mask.empty() || mask.equals_ci(x->mask) || mask == x->id || Anope::Match(x->mask, mask, false, true))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = x->mask;
- entry["Creator"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on the AKILL list."));
- else
- {
- source.Reply(_("Current AKILL list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of AKILL list."));
- }
- }
-
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Expires"));
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- list.AddColumn(_("ID"));
- list.AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoClear(CommandSource &source)
- {
-
- for (unsigned i = akills->GetCount(); i > 0; --i)
- {
- XLine *x = akills->GetEntry(i - 1);
- FOREACH_MOD(OnDelXLine, (source, x, akills));
- akills->DelXLine(x);
- }
-
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("The AKILL list has been cleared."));
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- public:
- CommandOSAKill(Module *creator) : Command(creator, "operserv/akill", 1, 2)
- {
- this->SetDesc(_("Manipulate the AKILL list"));
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (!akills)
- return;
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the AKILL list. If\n"
- "a user matching an AKILL mask attempts to connect, Services\n"
- "will issue a KILL for that user and, on supported server\n"
- "types, will instruct all servers to add a ban for the mask\n"
- "which the user matched.\n"
- " \n"
- "\002AKILL ADD\002 adds the given mask to the AKILL\n"
- "list for the given reason, which \002must\002 be given.\n"
- "Mask should be in the format of nick!user@host#real name,\n"
- "though all that is required is user@host. If a real name is specified,\n"
- "the reason must be prepended with a :.\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an AKILL which does not expire, use \037+0\037. If the\n"
- "usermask to be added starts with a \037+\037, an expiry time must\n"
- "be given, even if it is the same as the default. The\n"
- "current AKILL default expiry time can be found with the\n"
- "\002STATS AKILL\002 command."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(
- " \n"
- "The \002AKILL DEL\002 command removes the given mask from the\n"
- "AKILL list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002AKILL LIST\002 command displays the AKILL list.\n"
- "If 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"
- " \002AKILL LIST 2-5,7-9\002\n"
- " Lists AKILL entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002AKILL VIEW\002 is a more verbose version of \002AKILL LIST\002, and\n"
- "will show who added an AKILL, the date it was added, and when\n"
- "it expires, as well as the user@host/ip mask and reason.\n"
- " \n"
- "\002AKILL CLEAR\002 clears all entries of the AKILL list."));
- return true;
- }
-};
-
-class OSAKill : public Module
-{
- CommandOSAKill commandosakill;
-
- public:
- OSAKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosakill(this)
- {
-
- }
-};
-
-MODULE_INIT(OSAKill)
diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp
deleted file mode 100644
index 56b5f6b33..000000000
--- a/modules/commands/os_chankill.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
-
-class CommandOSChanKill : public Command
-{
- public:
- CommandOSChanKill(Module *creator) : Command(creator, "operserv/chankill", 2, 3)
- {
- this->SetDesc(_("AKILL all users on a specific channel"));
- this->SetSyntax(_("[+\037expiry\037] \037channel\037 \037reason\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!akills)
- return;
-
- Anope::string expiry, channel;
- unsigned last_param = 1;
- Channel *c;
-
- channel = params[0];
- if (!channel.empty() && channel[0] == '+')
- {
- expiry = channel;
- channel = params[1];
- last_param = 2;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (params.size() > last_param + 1)
- reason += params[last_param + 1];
- if (!reason.empty())
- {
- Anope::string realreason;
- if (Config->GetModule("operserv")->Get<bool>("addakiller") && !source.GetNick().empty())
- realreason = "[" + source.GetNick() + "] " + reason;
- else
- realreason = reason;
-
- if ((c = Channel::Find(channel)))
- {
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
-
- if (uc->user->server == Me || uc->user->HasMode("OPER"))
- continue;
-
- Anope::string akillmask = "*@" + uc->user->host;
- if (akills->HasEntry(akillmask))
- continue;
-
- XLine *x = new XLine(akillmask, source.GetNick(), expires, realreason, XLineManager::GenerateUID());
- akills->AddXLine(x);
- akills->OnMatch(uc->user, x);
- }
-
- Log(LOG_ADMIN, source, this) << "on " << c->name << " (" << realreason << ")";
- }
- else
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Puts an AKILL for every nick on the specified channel. It\n"
- "uses the entire real ident@host for every nick, and\n"
- "then enforces the AKILL."));
- return true;
- }
-};
-
-class OSChanKill : public Module
-{
- CommandOSChanKill commandoschankill;
-
- public:
- OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoschankill(this)
- {
-
- }
-};
-
-MODULE_INIT(OSChanKill)
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp
deleted file mode 100644
index 687f44f4a..000000000
--- a/modules/commands/os_dns.cpp
+++ /dev/null
@@ -1,949 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/dns.h"
-
-static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager");
-
-struct DNSZone;
-class DNSServer;
-
-static Serialize::Checker<std::vector<DNSZone *> > zones("DNSZone");
-static Serialize::Checker<std::vector<DNSServer *> > dns_servers("DNSServer");
-
-static std::map<Anope::string, std::list<time_t> > server_quit_times;
-
-struct DNSZone : Serializable
-{
- Anope::string name;
- std::set<Anope::string, ci::less> servers;
-
- DNSZone(const Anope::string &n) : Serializable("DNSZone"), name(n)
- {
- zones->push_back(this);
- }
-
- ~DNSZone()
- {
- std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this);
- if (it != zones->end())
- zones->erase(it);
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["name"] << name;
- unsigned count = 0;
- for (std::set<Anope::string, ci::less>::iterator it = servers.begin(), it_end = servers.end(); it != it_end; ++it)
- data["server" + stringify(count++)] << *it;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- DNSZone *zone;
- Anope::string zone_name;
-
- data["name"] >> zone_name;
-
- if (obj)
- {
- zone = anope_dynamic_static_cast<DNSZone *>(obj);
- data["name"] >> zone->name;
- }
- else
- zone = new DNSZone(zone_name);
-
- zone->servers.clear();
- for (unsigned count = 0; true; ++count)
- {
- Anope::string server_str;
- data["server" + stringify(count)] >> server_str;
- if (server_str.empty())
- break;
- zone->servers.insert(server_str);
- }
-
- return zone;
- }
-
- static DNSZone *Find(const Anope::string &name)
- {
- for (unsigned i = 0; i < zones->size(); ++i)
- if (zones->at(i)->name.equals_ci(name))
- {
- DNSZone *z = zones->at(i);
- z->QueueUpdate();
- return z;
- }
- return NULL;
- }
-};
-
-class DNSServer : public Serializable
-{
- Anope::string server_name;
- std::vector<Anope::string> ips;
- unsigned limit;
- /* wants to be in the pool */
- bool pooled;
- /* is actually in the pool */
- bool active;
-
- public:
- std::set<Anope::string, ci::less> zones;
- time_t repool;
-
- DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), active(false), repool(0)
- {
- dns_servers->push_back(this);
- }
-
- ~DNSServer()
- {
- std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this);
- if (it != dns_servers->end())
- dns_servers->erase(it);
- }
-
- const Anope::string &GetName() const { return server_name; }
- std::vector<Anope::string> &GetIPs() { return ips; }
- unsigned GetLimit() const { return limit; }
- void SetLimit(unsigned l) { limit = l; }
-
- bool Pooled() const { return pooled; }
- void Pool(bool p)
- {
- if (!p)
- this->SetActive(p);
- pooled = p;
- }
-
- bool Active() const { return pooled && active; }
- void SetActive(bool p)
- {
- if (p)
- this->Pool(p);
- active = p;
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["server_name"] << server_name;
- for (unsigned i = 0; i < ips.size(); ++i)
- data["ip" + stringify(i)] << ips[i];
- data["limit"] << limit;
- data["pooled"] << pooled;
- unsigned count = 0;
- for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it)
- data["zone" + stringify(count++)] << *it;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- DNSServer *req;
- Anope::string server_name;
-
- data["server_name"] >> server_name;
-
- if (obj)
- {
- req = anope_dynamic_static_cast<DNSServer *>(obj);
- req->server_name = server_name;
- }
- else
- req = new DNSServer(server_name);
-
- for (unsigned i = 0; true; ++i)
- {
- Anope::string ip_str;
- data["ip" + stringify(i)] >> ip_str;
- if (ip_str.empty())
- break;
- req->ips.push_back(ip_str);
- }
-
- data["limit"] >> req->limit;
- data["pooled"] >> req->pooled;
-
- req->zones.clear();
- for (unsigned i = 0; true; ++i)
- {
- Anope::string zone_str;
- data["zone" + stringify(i)] >> zone_str;
- if (zone_str.empty())
- break;
- req->zones.insert(zone_str);
- }
-
- return req;
- }
-
- static DNSServer *Find(const Anope::string &s)
- {
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- if (dns_servers->at(i)->GetName().equals_ci(s))
- {
- DNSServer *serv = dns_servers->at(i);
- serv->QueueUpdate();
- return serv;
- }
- return NULL;
- }
-};
-
-class CommandOSDNS : public Command
-{
- void DisplayPoolState(CommandSource &source)
- {
- if (dns_servers->empty())
- {
- source.Reply(_("There are no configured servers."));
- return;
- }
-
- ListFormatter lf(source.GetAccount());
- lf.AddColumn(_("Server")).AddColumn(_("IP")).AddColumn(_("Limit")).AddColumn(_("State"));
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
- Server *srv = Server::Find(s->GetName(), true);
-
- ListFormatter::ListEntry entry;
- entry["Server"] = s->GetName();
- entry["Limit"] = s->GetLimit() ? stringify(s->GetLimit()) : Language::Translate(source.GetAccount(), _("None"));
-
- Anope::string ip_str;
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- ip_str += s->GetIPs()[j] + " ";
- ip_str.trim();
- if (ip_str.empty())
- ip_str = "None";
- entry["IP"] = ip_str;
-
- if (s->Active())
- entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Active"));
- else if (s->Pooled())
- entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Not Active"));
- else
- entry["State"] = Language::Translate(source.GetAccount(), _("Unpooled"));
-
- if (!srv)
- entry["State"] += Anope::string(" ") + Language::Translate(source.GetAccount(), _("(Split)"));
-
- lf.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- lf.Process(replies);
-
- if (!zones->empty())
- {
- ListFormatter lf2(source.GetAccount());
- lf2.AddColumn(_("Zone")).AddColumn(_("Servers"));
-
- for (unsigned i = 0; i < zones->size(); ++i)
- {
- const DNSZone *z = zones->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Zone"] = z->name;
-
- Anope::string server_str;
- for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it)
- server_str += *it + " ";
- server_str.trim();
-
- if (server_str.empty())
- server_str = "None";
-
- entry["Servers"] = server_str;
-
- lf2.AddEntry(entry);
- }
-
- lf2.Process(replies);
- }
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- void AddZone(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &zone = params[1];
-
- if (DNSZone::Find(zone))
- {
- source.Reply(_("Zone %s already exists."), zone.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add zone " << zone;
-
- new DNSZone(zone);
- source.Reply(_("Added zone %s."), zone.c_str());
- }
-
- void DelZone(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &zone = params[1];
-
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to delete zone " << z->name;
-
- for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it)
- {
- DNSServer *s = DNSServer::Find(*it);
- if (s)
- s->zones.erase(z->name);
- }
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
-
- source.Reply(_("Zone %s removed."), z->name.c_str());
- delete z;
- }
-
- void AddServer(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
- const Anope::string &zone = params.size() > 2 ? params[2] : "";
-
- if (s)
- {
- if (zone.empty())
- {
- source.Reply(_("Server %s already exists."), s->GetName().c_str());
- }
- else
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
- else if (z->servers.count(s->GetName()))
- {
- source.Reply(_("Server %s is already in zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- z->servers.insert(s->GetName());
- s->zones.insert(zone);
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(zone);
- }
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << z->name;
-
- source.Reply(_("Server %s added to zone %s."), s->GetName().c_str(), z->name.c_str());
- }
-
- return;
- }
-
- Server *serv = Server::Find(params[1], true);
- if (!serv || serv == Me || serv->IsJuped())
- {
- source.Reply(_("Server %s is not linked to the network."), params[1].c_str());
- return;
- }
-
- s = new DNSServer(params[1]);
- if (zone.empty())
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName();
- source.Reply(_("Added server %s."), s->GetName().c_str());
- }
- else
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- delete s;
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << zone;
-
- z->servers.insert(s->GetName());
- s->zones.insert(z->name);
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
- }
- }
-
- void DelServer(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
- const Anope::string &zone = params.size() > 2 ? params[2] : "";
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!zone.empty())
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
- else if (!z->servers.count(s->GetName()))
- {
- source.Reply(_("Server %s is not in zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove server " << s->GetName() << " from zone " << z->name;
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
-
- z->servers.erase(s->GetName());
- s->zones.erase(z->name);
- source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
- else if (Server::Find(s->GetName(), true))
- {
- source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str());
- return;
- }
-
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- {
- DNSZone *z = DNSZone::Find(*it);
- if (z)
- z->servers.erase(s->GetName());
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (dnsmanager)
- dnsmanager->UpdateSerial();
-
- Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName();
- source.Reply(_("Removed server %s."), s->GetName().c_str());
- delete s;
- }
-
- void AddIP(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- for (unsigned i = 0; i < s->GetIPs().size(); ++i)
- if (params[2].equals_ci(s->GetIPs()[i]))
- {
- source.Reply(_("IP %s already exists for %s."), s->GetIPs()[i].c_str(), s->GetName().c_str());
- return;
- }
-
- sockaddrs addr(params[2]);
- if (!addr.valid())
- {
- source.Reply(_("%s is not a valid IP address."), params[2].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->GetIPs().push_back(params[2]);
- source.Reply(_("Added IP %s to %s."), params[2].c_str(), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName();
-
- if (s->Active() && dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
- }
-
- void DelIP(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- for (unsigned i = 0; i < s->GetIPs().size(); ++i)
- if (params[2].equals_ci(s->GetIPs()[i]))
- {
- s->GetIPs().erase(s->GetIPs().begin() + i);
- source.Reply(_("Removed IP %s from %s."), params[2].c_str(), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to remove IP " << params[2] << " from " << s->GetName();
-
- if (s->GetIPs().empty())
- {
- s->repool = 0;
- s->Pool(false);
- }
-
- if (s->Active() && dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
-
- return;
- }
-
- source.Reply(_("IP %s does not exist for %s."), params[2].c_str(), s->GetName().c_str());
- }
-
- void OnSet(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (params[2].equals_ci("LIMIT"))
- {
- try
- {
- unsigned l = convertTo<unsigned>(params[3]);
- s->SetLimit(l);
- if (l)
- source.Reply(_("User limit for %s set to %d."), s->GetName().c_str(), l);
- else
- source.Reply(_("User limit for %s removed."), s->GetName().c_str());
- }
- catch (const ConvertException &ex)
- {
- source.Reply(_("Invalid value for LIMIT. Must be numerical."));
- }
- }
- else
- source.Reply(_("Unknown SET option."));
- }
-
- void OnPool(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!Server::Find(s->GetName(), true))
- {
- source.Reply(_("Server %s is not currently linked."), s->GetName().c_str());
- return;
- }
- else if (s->Pooled())
- {
- source.Reply(_("Server %s is already pooled."), s->GetName().c_str());
- return;
- }
- else if (s->GetIPs().empty())
- {
- source.Reply(_("Server %s has no configured IPs."), s->GetName().c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->SetActive(true);
-
- source.Reply(_("Pooled %s."), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to pool " << s->GetName();
- }
-
-
- void OnDepool(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!s->Pooled())
- {
- source.Reply(_("Server %s is not pooled."), s->GetName().c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->Pool(false);
-
- source.Reply(_("Depooled %s."), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to depool " << s->GetName();
- }
-
- public:
- CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 4)
- {
- this->SetDesc(_("Manage DNS zones for this network"));
- this->SetSyntax(_("ADDZONE \037zone.name\037"));
- this->SetSyntax(_("DELZONE \037zone.name\037"));
- this->SetSyntax(_("ADDSERVER \037server.name\037 [\037zone.name\037]"));
- this->SetSyntax(_("DELSERVER \037server.name\037 [\037zone.name\037]"));
- this->SetSyntax(_("ADDIP \037server.name\037 \037ip\037"));
- this->SetSyntax(_("DELIP \037server.name\037 \037ip\037"));
- this->SetSyntax(_("SET \037server.name\037 \037option\037 \037value\037"));
- this->SetSyntax(_("POOL \037server.name\037"));
- this->SetSyntax(_("DEPOOL \037server.name\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.empty())
- this->DisplayPoolState(source);
- else if (params[0].equals_ci("ADDZONE") && params.size() > 1)
- this->AddZone(source, params);
- else if (params[0].equals_ci("DELZONE") && params.size() > 1)
- this->DelZone(source, params);
- else if (params[0].equals_ci("ADDSERVER") && params.size() > 1)
- this->AddServer(source, params);
- else if (params[0].equals_ci("DELSERVER") && params.size() > 1)
- this->DelServer(source, params);
- else if (params[0].equals_ci("ADDIP") && params.size() > 2)
- this->AddIP(source, params);
- else if (params[0].equals_ci("DELIP") && params.size() > 2)
- this->DelIP(source, params);
- else if (params[0].equals_ci("SET") && params.size() > 3)
- this->OnSet(source, params);
- else if (params[0].equals_ci("POOL") && params.size() > 1)
- this->OnPool(source, params);
- else if (params[0].equals_ci("DEPOOL") && params.size() > 1)
- this->OnDepool(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command allows managing DNS zones used for controlling what servers users\n"
- "are directed to when connecting. Omitting all parameters prints out the status of\n"
- "the DNS zone.\n"
- " \n"
- "\002ADDZONE\002 adds a zone, eg us.yournetwork.tld. Servers can then be added to this\n"
- "zone with the \002ADDSERVER\002 command.\n"
- " \n"
- "The \002ADDSERVER\002 command adds a server to the given zone. When a query is done, the\n"
- "zone in question is served if it exists, else all servers in all zones are served.\n"
- "A server may be in more than one zone.\n"
- " \n"
- "The \002ADDIP\002 command associates an IP with a server.\n"
- " \n"
- "The \002POOL\002 and \002DEPOOL\002 commands actually add and remove servers to their given zones."));
- return true;
- }
-};
-
-class ModuleDNS : public Module
-{
- Serialize::Type zone_type, dns_type;
- CommandOSDNS commandosdns;
-
- time_t ttl;
- int user_drop_mark;
- time_t user_drop_time;
- time_t user_drop_readd_time;
- bool remove_split_servers;
- bool readd_connected_servers;
-
- time_t last_warn;
-
- public:
- ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- zone_type("DNSZone", DNSZone::Unserialize), dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this),
- last_warn(0)
- {
-
-
- for (unsigned j = 0; j < dns_servers->size(); ++j)
- {
- DNSServer *s = dns_servers->at(j);
- if (s->Pooled() && Server::Find(s->GetName(), true))
- s->SetActive(true);
- }
- }
-
- ~ModuleDNS()
- {
- for (unsigned i = zones->size(); i > 0; --i)
- delete zones->at(i - 1);
- for (unsigned i = dns_servers->size(); i > 0; --i)
- delete dns_servers->at(i - 1);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->ttl = block->Get<time_t>("ttl");
- this->user_drop_mark = block->Get<int>("user_drop_mark");
- this->user_drop_time = block->Get<time_t>("user_drop_time");
- this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time");
- this->remove_split_servers = block->Get<bool>("remove_split_servers");
- this->readd_connected_servers = block->Get<bool>("readd_connected_servers");
- }
-
- void OnNewServer(Server *s) anope_override
- {
- if (s == Me || s->IsJuped())
- return;
- if (!Me->IsSynced() || this->readd_connected_servers)
- {
- DNSServer *dns = DNSServer::Find(s->GetName());
- if (dns && dns->Pooled() && !dns->Active() && !dns->GetIPs().empty())
- {
- dns->SetActive(true);
- Log(this) << "Pooling server " << s->GetName();
- }
- }
- }
-
- void OnServerQuit(Server *s) anope_override
- {
- DNSServer *dns = DNSServer::Find(s->GetName());
- if (remove_split_servers && dns && dns->Pooled() && dns->Active())
- {
- if (readd_connected_servers)
- dns->SetActive(false); // Will be reactivated when it comes back
- else
- dns->Pool(false); // Otherwise permanently pull this
- Log(this) << "Depooling delinked server " << s->GetName();
- }
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (!u->Quitting() && u->server)
- {
- DNSServer *s = DNSServer::Find(u->server->GetName());
- /* Check for user limit reached */
- if (s && s->Pooled() && s->Active() && s->GetLimit() && u->server->users >= s->GetLimit())
- {
- Log(this) << "Depooling full server " << s->GetName() << ": " << u->server->users << " users";
- s->SetActive(false);
- }
- }
- }
-
- void OnPreUserLogoff(User *u) anope_override
- {
- if (u && u->server)
- {
- DNSServer *s = DNSServer::Find(u->server->GetName());
- if (!s || !s->Pooled())
- return;
-
- /* Check for dropping under userlimit */
- if (s->GetLimit() && !s->Active() && s->GetLimit() > u->server->users)
- {
- Log(this) << "Pooling server " << s->GetName();
- s->SetActive(true);
- }
-
- if (this->user_drop_mark > 0)
- {
- std::list<time_t>& times = server_quit_times[u->server->GetName()];
- times.push_back(Anope::CurTime);
- if (times.size() > static_cast<unsigned>(this->user_drop_mark))
- times.pop_front();
-
- if (times.size() == static_cast<unsigned>(this->user_drop_mark))
- {
- time_t diff = Anope::CurTime - *times.begin();
-
- /* Check for very fast user drops */
- if (s->Active() && diff <= this->user_drop_time)
- {
- Log(this) << "Depooling server " << s->GetName() << ": dropped " << this->user_drop_mark << " users in " << diff << " seconds";
- s->repool = Anope::CurTime + this->user_drop_readd_time;
- s->SetActive(false);
- }
- /* Check for needing to re-pool a server that dropped users */
- else if (!s->Active() && s->repool && s->repool <= Anope::CurTime)
- {
- s->SetActive(true);
- s->repool = 0;
- Log(this) << "Pooling server " << s->GetName();
- }
- }
- }
- }
- }
-
- void OnDnsRequest(DNS::Query &req, DNS::Query *packet) anope_override
- {
- if (req.questions.empty())
- return;
- /* Currently we reply to any QR for A/AAAA */
- const DNS::Question& q = req.questions[0];
- if (q.type != DNS::QUERY_A && q.type != DNS::QUERY_AAAA && q.type != DNS::QUERY_AXFR && q.type != DNS::QUERY_ANY)
- return;
-
- DNSZone *zone = DNSZone::Find(q.name);
- size_t answer_size = packet->answers.size();
- if (zone)
- {
- for (std::set<Anope::string, ci::less>::iterator it = zone->servers.begin(), it_end = zone->servers.end(); it != it_end; ++it)
- {
- DNSServer *s = DNSServer::Find(*it);
- if (!s || !s->Active())
- continue;
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- /* Default zone */
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
- if (!s->Active())
- continue;
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- if (last_warn + 60 < Anope::CurTime)
- {
- last_warn = Anope::CurTime;
- Log(this) << "Warning! There are no pooled servers!";
- }
-
- /* Something messed up, just return them all and hope one is available */
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- Log(this) << "Error! There are no servers with any IPs of type " << q.type;
- /* Send back an empty answer anyway */
- }
- }
- }
-};
-
-MODULE_INIT(ModuleDNS)
diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp
deleted file mode 100644
index 8c723b337..000000000
--- a/modules/commands/os_forbid.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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/os_forbid.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-struct ForbidDataImpl : ForbidData, Serializable
-{
- ForbidDataImpl() : Serializable("ForbidData") { }
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-void ForbidDataImpl::Serialize(Serialize::Data &data) const
-{
- data["mask"] << this->mask;
- data["creator"] << this->creator;
- data["reason"] << this->reason;
- data["created"] << this->created;
- data["expires"] << this->expires;
- data["type"] << this->type;
-}
-
-Serializable* ForbidDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- if (!forbid_service)
- return NULL;
-
- ForbidDataImpl *fb;
- if (obj)
- fb = anope_dynamic_static_cast<ForbidDataImpl *>(obj);
- else
- fb = new ForbidDataImpl();
-
- data["mask"] >> fb->mask;
- data["creator"] >> fb->creator;
- data["reason"] >> fb->reason;
- data["created"] >> fb->created;
- data["expires"] >> fb->expires;
- unsigned int t;
- data["type"] >> t;
- fb->type = static_cast<ForbidType>(t);
-
- if (t > FT_SIZE - 1)
- return NULL;
-
- if (!obj)
- forbid_service->AddForbid(fb);
- return fb;
-}
-
-class MyForbidService : public ForbidService
-{
- Serialize::Checker<std::vector<ForbidData *>[FT_SIZE - 1]> forbid_data;
-
- inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; }
-
- public:
- MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { }
-
- ~MyForbidService()
- {
- std::vector<ForbidData *> f = GetForbids();
- for (unsigned i = 0; i < f.size(); ++i)
- delete f[i];
- }
-
- void AddForbid(ForbidData *d) anope_override
- {
- this->forbids(d->type).push_back(d);
- }
-
- void RemoveForbid(ForbidData *d) anope_override
- {
- std::vector<ForbidData *>::iterator it = std::find(this->forbids(d->type).begin(), this->forbids(d->type).end(), d);
- if (it != this->forbids(d->type).end())
- this->forbids(d->type).erase(it);
- delete d;
- }
-
- ForbidData *CreateForbid() anope_override
- {
- return new ForbidDataImpl();
- }
-
- ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) anope_override
- {
- for (unsigned i = this->forbids(ftype).size(); i > 0; --i)
- {
- ForbidData *d = this->forbids(ftype)[i - 1];
-
- if (Anope::Match(mask, d->mask, false, true))
- return d;
- }
- return NULL;
- }
-
- std::vector<ForbidData *> GetForbids() anope_override
- {
- std::vector<ForbidData *> f;
- for (unsigned j = FT_NICK; j < FT_SIZE; ++j)
- for (unsigned i = this->forbids(j).size(); i > 0; --i)
- {
- ForbidData *d = this->forbids(j).at(i - 1);
-
- if (d->expires && !Anope::NoExpire && Anope::CurTime >= d->expires)
- {
- Anope::string ftype = "none";
- if (d->type == FT_NICK)
- ftype = "nick";
- else if (d->type == FT_CHAN)
- ftype = "chan";
- else if (d->type == FT_EMAIL)
- ftype = "email";
-
- Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << d->mask << " type " << ftype;
- this->forbids(j).erase(this->forbids(j).begin() + i - 1);
- delete d;
- }
- else
- f.push_back(d);
- }
-
- return f;
- }
-};
-
-class CommandOSForbid : public Command
-{
- ServiceReference<ForbidService> fs;
- public:
- CommandOSForbid(Module *creator) : Command(creator, "operserv/forbid", 1, 5), fs("ForbidService", "forbid")
- {
- this->SetDesc(_("Forbid usage of nicknames, channels, and emails"));
- this->SetSyntax(_("ADD {NICK|CHAN|EMAIL|REGISTER} [+\037expiry\037] \037entry\037 \037reason\037"));
- this->SetSyntax(_("DEL {NICK|CHAN|EMAIL|REGISTER} \037entry\037"));
- this->SetSyntax("LIST [NICK|CHAN|EMAIL|REGISTER]");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->fs)
- return;
-
- const Anope::string &command = params[0];
- const Anope::string &subcommand = params.size() > 1 ? params[1] : "";
-
- ForbidType ftype = FT_SIZE;
- if (subcommand.equals_ci("NICK"))
- ftype = FT_NICK;
- else if (subcommand.equals_ci("CHAN"))
- ftype = FT_CHAN;
- else if (subcommand.equals_ci("EMAIL"))
- ftype = FT_EMAIL;
- else if (subcommand.equals_ci("REGISTER"))
- ftype = FT_REGISTER;
-
- if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE)
- {
- const Anope::string &expiry = params[2][0] == '+' ? params[2] : "";
- const Anope::string &entry = !expiry.empty() ? params[3] : params[2];
- Anope::string reason;
- if (expiry.empty())
- reason = params[3] + " ";
- if (params.size() > 4)
- reason += params[4];
- reason.trim();
-
- if (entry.replace_all_cs("?*", "").empty())
- {
- source.Reply(_("The mask must contain at least one non wildcard character."));
- return;
- }
-
- time_t expiryt = 0;
-
- if (!expiry.empty())
- {
- expiryt = Anope::DoTime(expiry);
- if (expiryt == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expiryt)
- expiryt += Anope::CurTime;
- }
-
- NickAlias *target = NickAlias::Find(entry);
- if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->nc->IsServicesOper())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- ForbidData *d = this->fs->FindForbid(entry, ftype);
- bool created = false;
- if (d == NULL)
- {
- d = new ForbidDataImpl();
- created = true;
- }
-
- d->mask = entry;
- d->creator = source.GetNick();
- d->reason = reason;
- d->created = Anope::CurTime;
- d->expires = expiryt;
- d->type = ftype;
- if (created)
- this->fs->AddForbid(d);
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand;
- source.Reply(_("Added a forbid on %s of type %s to expire on %s."), entry.c_str(), subcommand.lower().c_str(), d->expires ? Anope::strftime(d->expires, source.GetAccount()).c_str() : "never");
-
- /* apply forbid */
- switch (ftype)
- {
- case FT_NICK:
- {
- int na_matches = 0;
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- module->OnUserNickChange(it->second, "");
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end;)
- {
- NickAlias *na = it->second;
- ++it;
-
- d = this->fs->FindForbid(na->nick, FT_NICK);
- if (d == NULL)
- continue;
-
- ++na_matches;
-
- delete na;
- }
-
- source.Reply(_("\002%d\002 nickname(s) dropped."), na_matches);
- break;
- }
- case FT_CHAN:
- {
- int chan_matches = 0, ci_matches = 0;
-
- for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
- {
- Channel *c = it->second;
- ++it;
-
- d = this->fs->FindForbid(c->name, FT_CHAN);
- if (d == NULL)
- continue;
-
- ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (IRCD->CanSQLineChannel && OperServ)
- {
- time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
- XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason);
- IRCD->SendSQLine(NULL, &x);
- }
- else if (chanserv)
- {
- chanserv->Hold(c);
- }
-
- ++chan_matches;
-
- for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
- {
- User *u = cit->first;
- ++cit;
-
- if (u->server == Me || u->HasMode("OPER"))
- continue;
-
- reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: %s")), d->reason.c_str());
-
- c->Kick(source.service, u, "%s", reason.c_str());
- }
- }
-
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(); it != RegisteredChannelList->end();)
- {
- ChannelInfo *ci = it->second;
- ++it;
-
- d = this->fs->FindForbid(ci->name, FT_CHAN);
- if (d == NULL)
- continue;
-
- ++ci_matches;
-
- delete ci;
- }
-
- source.Reply(_("\002%d\002 channel(s) cleared, and \002%d\002 channel(s) dropped."), chan_matches, ci_matches);
-
- break;
- }
- default:
- break;
- }
-
- }
- else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE)
- {
- const Anope::string &entry = params[2];
-
- ForbidData *d = this->fs->FindForbid(entry, ftype);
- if (d != NULL)
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove forbid on " << d->mask << " of type " << subcommand;
- source.Reply(_("%s deleted from the %s forbid list."), d->mask.c_str(), subcommand.c_str());
- this->fs->RemoveForbid(d);
- }
- else
- source.Reply(_("Forbid on %s was not found."), entry.c_str());
- }
- else if (command.equals_ci("LIST"))
- {
- const std::vector<ForbidData *> &forbids = this->fs->GetForbids();
- if (forbids.empty())
- source.Reply(_("Forbid list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask")).AddColumn(_("Type")).AddColumn(_("Creator")).AddColumn(_("Expires")).AddColumn(_("Reason"));
-
- unsigned shown = 0;
- for (unsigned i = 0; i < forbids.size(); ++i)
- {
- ForbidData *d = forbids[i];
-
- if (ftype != FT_SIZE && ftype != d->type)
- continue;
-
- Anope::string stype;
- if (d->type == FT_NICK)
- stype = "NICK";
- else if (d->type == FT_CHAN)
- stype = "CHAN";
- else if (d->type == FT_EMAIL)
- stype = "EMAIL";
- else if (d->type == FT_REGISTER)
- stype = "REGISTER";
- else
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Mask"] = d->mask;
- entry["Type"] = stype;
- entry["Creator"] = d->creator;
- entry["Expires"] = d->expires ? Anope::strftime(d->expires, NULL, true).c_str() : Language::Translate(source.GetAccount(), _("Never"));
- entry["Reason"] = d->reason;
- list.AddEntry(entry);
- ++shown;
- }
-
- if (!shown)
- {
- source.Reply(_("There are no forbids of type %s."), subcommand.upper().c_str());
- }
- else
- {
- source.Reply(_("Forbid list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- if (shown >= forbids.size())
- source.Reply(_("End of forbid list."));
- else
- source.Reply(_("End of forbid list - %d/%d entries shown."), shown, forbids.size());
- }
- }
- }
- else
- this->OnSyntaxError(source, command);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n"
- "and email addresses. Wildcards are accepted for all entries."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class OSForbid : public Module
-{
- MyForbidService forbidService;
- Serialize::Type forbiddata_type;
- CommandOSForbid commandosforbid;
-
- public:
- OSForbid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- forbidService(this), forbiddata_type("ForbidData", ForbidDataImpl::Unserialize), commandosforbid(this)
- {
-
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (u->Quitting() || exempt)
- return;
-
- this->OnUserNickChange(u, "");
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
- {
- if (u->HasMode("OPER"))
- return;
-
- ForbidData *d = this->forbidService.FindForbid(u->nick, FT_NICK);
- if (d != NULL)
- {
- BotInfo *bi = Config->GetClient("NickServ");
- if (!bi)
- bi = Config->GetClient("OperServ");
- if (bi)
- u->SendMessage(bi, _("This nickname has been forbidden: %s"), d->reason.c_str());
- if (nickserv)
- nickserv->Collide(u, NULL);
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (u->HasMode("OPER") || !OperServ)
- return EVENT_CONTINUE;
-
- ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN);
- if (d != NULL)
- {
- ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
- if (IRCD->CanSQLineChannel)
- {
- time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
- XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason);
- IRCD->SendSQLine(NULL, &x);
- }
- else if (chanserv)
- {
- chanserv->Hold(c);
- }
-
- reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: %s")), d->reason.c_str());
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- if (command->name == "nickserv/info" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_NICK);
- if (d != NULL)
- {
- if (source.IsOper())
- source.Reply(_("Nick \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str());
- else
- source.Reply(_("Nick \002%s\002 is forbidden."), params[0].c_str());
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/info" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_CHAN);
- if (d != NULL)
- {
- if (source.IsOper())
- source.Reply(_("Channel \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str());
- else
- source.Reply(_("Channel \002%s\002 is forbidden."), params[0].c_str());
- return EVENT_STOP;
- }
- }
- else if (source.IsOper())
- return EVENT_CONTINUE;
- else if (command->name == "nickserv/register" && params.size() > 1)
- {
- ForbidData *d = this->forbidService.FindForbid(source.GetNick(), FT_REGISTER);
- if (d != NULL)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, source.GetNick().c_str());
- return EVENT_STOP;
- }
-
- d = this->forbidService.FindForbid(params[1], FT_EMAIL);
- if (d != NULL)
- {
- source.Reply(_("Your email address is not allowed, choose a different one."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "nickserv/set/email" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_EMAIL);
- if (d != NULL)
- {
- source.Reply(_("Your email address is not allowed, choose a different one."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/register" && !params.empty())
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_REGISTER);
- if (d != NULL)
- {
- source.Reply(CHAN_X_INVALID, params[0].c_str());
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSForbid)
diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp
deleted file mode 100644
index 2f4fca3e2..000000000
--- a/modules/commands/os_ignore.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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/os_ignore.h"
-
-struct IgnoreDataImpl : IgnoreData, Serializable
-{
- IgnoreDataImpl() : Serializable("IgnoreData") { }
- ~IgnoreDataImpl();
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-IgnoreDataImpl::~IgnoreDataImpl()
-{
- if (ignore_service)
- ignore_service->DelIgnore(this);
-}
-
-void IgnoreDataImpl::Serialize(Serialize::Data &data) const
-{
- data["mask"] << this->mask;
- data["creator"] << this->creator;
- data["reason"] << this->reason;
- data["time"] << this->time;
-}
-
-Serializable* IgnoreDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- if (!ignore_service)
- return NULL;
-
- IgnoreDataImpl *ign;
- if (obj)
- ign = anope_dynamic_static_cast<IgnoreDataImpl *>(obj);
- else
- {
- ign = new IgnoreDataImpl();
- ignore_service->AddIgnore(ign);
- }
-
- data["mask"] >> ign->mask;
- data["creator"] >> ign->creator;
- data["reason"] >> ign->reason;
- data["time"] >> ign->time;
-
- return ign;
-}
-
-
-class OSIgnoreService : public IgnoreService
-{
- Serialize::Checker<std::vector<IgnoreData *> > ignores;
-
- public:
- OSIgnoreService(Module *o) : IgnoreService(o), ignores("IgnoreData") { }
-
- void AddIgnore(IgnoreData *ign) anope_override
- {
- ignores->push_back(ign);
- }
-
- void DelIgnore(IgnoreData *ign) anope_override
- {
- std::vector<IgnoreData *>::iterator it = std::find(ignores->begin(), ignores->end(), ign);
- if (it != ignores->end())
- ignores->erase(it);
- }
-
- void ClearIgnores() anope_override
- {
- for (unsigned i = ignores->size(); i > 0; --i)
- {
- IgnoreData *ign = ignores->at(i - 1);
- delete ign;
- }
- }
-
- IgnoreData *Create() anope_override
- {
- return new IgnoreDataImpl();
- }
-
- IgnoreData *Find(const Anope::string &mask) anope_override
- {
- User *u = User::Find(mask, true);
- std::vector<IgnoreData *>::iterator ign = this->ignores->begin(), ign_end = this->ignores->end();
-
- if (u)
- {
- for (; ign != ign_end; ++ign)
- {
- Entry ignore_mask("", (*ign)->mask);
- if (ignore_mask.Matches(u, true))
- break;
- }
- }
- else
- {
- size_t user, host;
- Anope::string tmp;
- /* We didn't get a user.. generate a valid mask. */
- if ((host = mask.find('@')) != Anope::string::npos)
- {
- if ((user = mask.find('!')) != Anope::string::npos)
- {
- /* this should never happen */
- if (user > host)
- return NULL;
- tmp = mask;
- }
- else
- /* We have user@host. Add nick wildcard. */
- tmp = "*!" + mask;
- }
- /* We only got a nick.. */
- else
- tmp = mask + "!*@*";
-
- for (; ign != ign_end; ++ign)
- if (Anope::Match(tmp, (*ign)->mask, false, true))
- break;
- }
-
- /* Check whether the entry has timed out */
- if (ign != ign_end)
- {
- IgnoreData *id = *ign;
-
- if (id->time && !Anope::NoExpire && id->time <= Anope::CurTime)
- {
- Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->mask;
- delete id;
- }
- else
- return id;
- }
-
- return NULL;
- }
-
- std::vector<IgnoreData *> &GetIgnores() anope_override
- {
- return *ignores;
- }
-};
-
-class CommandOSIgnore : public Command
-{
- private:
- Anope::string RealMask(const Anope::string &mask)
- {
- /* If it s an existing user, we ignore the hostmask. */
- User *u = User::Find(mask, true);
- if (u)
- return "*!*@" + u->host;
-
- size_t host = mask.find('@');
- /* Determine whether we get a nick or a mask. */
- if (host != Anope::string::npos)
- {
- size_t user = mask.find('!');
- /* Check whether we have a nick too.. */
- if (user != Anope::string::npos)
- {
- if (user > host)
- /* this should never happen */
- return "";
- else
- return mask;
- }
- else
- /* We have user@host. Add nick wildcard. */
- return "*!" + mask;
- }
-
- /* We only got a nick.. */
- return mask + "!*@*";
- }
-
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (!ignore_service)
- return;
-
- const Anope::string &time = params.size() > 1 ? params[1] : "";
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
- const Anope::string &reason = params.size() > 3 ? params[3] : "";
-
- if (time.empty() || nick.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
- else
- {
- time_t t = Anope::DoTime(time);
-
- if (t <= -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
-
- Anope::string mask = RealMask(nick);
- if (mask.empty())
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- IgnoreData *ign = new IgnoreDataImpl();
- ign->mask = mask;
- ign->creator = source.GetNick();
- ign->reason = reason;
- ign->time = t ? Anope::CurTime + t : 0;
-
- ignore_service->AddIgnore(ign);
- if (!t)
- {
- source.Reply(_("\002%s\002 will now permanently be ignored."), mask.c_str());
- Log(LOG_ADMIN, source, this) << "to add a permanent ignore for " << mask;
- }
- else
- {
- source.Reply(_("\002%s\002 will now be ignored for \002%s\002."), mask.c_str(), Anope::Duration(t, source.GetAccount()).c_str());
- Log(LOG_ADMIN, source, this) << "to add an ignore on " << mask << " for " << Anope::Duration(t);
- }
- }
- }
-
- void DoList(CommandSource &source)
- {
- if (!ignore_service)
- return;
-
- std::vector<IgnoreData *> &ignores = ignore_service->GetIgnores();
- for (unsigned i = ignores.size(); i > 0; --i)
- {
- IgnoreData *id = ignores[i - 1];
-
- if (id->time && !Anope::NoExpire && id->time <= Anope::CurTime)
- {
- Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->mask;
- delete id;
- }
- }
-
- if (ignores.empty())
- source.Reply(_("Ignore list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Reason")).AddColumn(_("Expires"));
-
- for (unsigned i = ignores.size(); i > 0; --i)
- {
- const IgnoreData *ignore = ignores[i - 1];
-
- ListFormatter::ListEntry entry;
- entry["Mask"] = ignore->mask;
- entry["Creator"] = ignore->creator;
- entry["Reason"] = ignore->reason;
- entry["Expires"] = Anope::Expires(ignore->time, source.GetAccount());
- list.AddEntry(entry);
- }
-
- source.Reply(_("Services ignore list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (!ignore_service)
- return;
-
- const Anope::string nick = params.size() > 1 ? params[1] : "";
- if (nick.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- Anope::string mask = RealMask(nick);
- if (mask.empty())
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- IgnoreData *ign = ignore_service->Find(mask);
- if (ign)
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove an ignore on " << mask;
- source.Reply(_("\002%s\002 will no longer be ignored."), mask.c_str());
- delete ign;
- }
- else
- source.Reply(_("\002%s\002 not found on ignore list."), mask.c_str());
- }
-
- void DoClear(CommandSource &source)
- {
- if (!ignore_service)
- return;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ignore_service->ClearIgnores();
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("Ignore list has been cleared."));
-
- return;
- }
-
- public:
- CommandOSIgnore(Module *creator) : Command(creator, "operserv/ignore", 1, 4)
- {
- this->SetDesc(_("Modify the Services ignore list"));
- this->SetSyntax(_("ADD \037expiry\037 {\037nick\037|\037mask\037} [\037reason\037]"));
- this->SetSyntax(_("DEL {\037nick\037|\037mask\037}"));
- this->SetSyntax("LIST");
- this->SetSyntax("CLEAR");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to make Services ignore a nick or mask\n"
- "for a certain time or until the next restart. The default\n"
- "time format is seconds. You can specify it by using units.\n"
- "Valid units are: \037s\037 for seconds, \037m\037 for minutes,\n"
- "\037h\037 for hours and \037d\037 for days.\n"
- "Combinations of these units are not permitted.\n"
- "To make Services permanently ignore the user, type 0 as time.\n"
- "When adding a \037mask\037, it should be in the format nick!user@host,\n"
- "everything else will be considered a nick. Wildcards are permitted.\n"
- " \n"
- "Ignores will not be enforced on IRC Operators."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class OSIgnore : public Module
-{
- Serialize::Type ignoredata_type;
- OSIgnoreService osignoreservice;
- CommandOSIgnore commandosignore;
-
- public:
- OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- ignoredata_type("IgnoreData", IgnoreDataImpl::Unserialize), osignoreservice(this), commandosignore(this)
- {
-
- }
-
- EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
- {
- if (!u->HasMode("OPER") && this->osignoreservice.Find(u->nick))
- return EVENT_STOP;
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSIgnore)
diff --git a/modules/commands/os_info.cpp b/modules/commands/os_info.cpp
deleted file mode 100644
index 0965d5ea7..000000000
--- a/modules/commands/os_info.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-
-struct OperInfo : Serializable
-{
- Anope::string target;
- Anope::string info;
- Anope::string adder;
- time_t created;
-
- OperInfo() : Serializable("OperInfo"), created(0) { }
- OperInfo(const Anope::string &t, const Anope::string &i, const Anope::string &a, time_t c) :
- Serializable("OperInfo"), target(t), info(i), adder(a), created(c) { }
-
- ~OperInfo();
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["target"] << target;
- data["info"] << info;
- data["adder"] << adder;
- data["created"] << created;
- }
-
- static Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct OperInfos : Serialize::Checker<std::vector<OperInfo *> >
-{
- OperInfos(Extensible *) : Serialize::Checker<std::vector<OperInfo *> >("OperInfo") { }
-
- ~OperInfos()
- {
- for (unsigned i = (*this)->size(); i > 0; --i)
- delete (*this)->at(i - 1);
- }
-
- static Extensible *Find(const Anope::string &target)
- {
- NickAlias *na = NickAlias::Find(target);
- if (na)
- return na->nc;
- return ChannelInfo::Find(target);
- }
-};
-
-OperInfo::~OperInfo()
-{
- Extensible *e = OperInfos::Find(target);
- if (e)
- {
- OperInfos *op = e->GetExt<OperInfos>("operinfo");
- if (op)
- {
- std::vector<OperInfo *>::iterator it = std::find((*op)->begin(), (*op)->end(), this);
- if (it != (*op)->end())
- (*op)->erase(it);
- }
- }
-}
-
-Serializable *OperInfo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string starget;
- data["target"] >> starget;
-
- Extensible *e = OperInfos::Find(starget);
- if (!e)
- return NULL;
-
- OperInfos *oi = e->Require<OperInfos>("operinfo");
- OperInfo *o;
- if (obj)
- o = anope_dynamic_static_cast<OperInfo *>(obj);
- else
- {
- o = new OperInfo();
- o->target = starget;
- }
- data["info"] >> o->info;
- data["adder"] >> o->adder;
- data["created"] >> o->created;
-
- if (!obj)
- (*oi)->push_back(o);
- return o;
-}
-
-class CommandOSInfo : public Command
-{
- public:
- CommandOSInfo(Module *creator) : Command(creator, "operserv/info", 2, 3)
- {
- this->SetDesc(_("Associate oper info with a nick or channel"));
- this->SetSyntax(_("ADD \037target\037 \037info\037"));
- this->SetSyntax(_("DEL \037target\037 \037info\037"));
- this->SetSyntax(_("CLEAR \037target\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0], target = params[1], info = params.size() > 2 ? params[2] : "";
-
- Extensible *e;
- if (IRCD->IsChannelValid(target))
- {
- ChannelInfo *ci = ChannelInfo::Find(target);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- e = ci;
- }
- else
- {
- NickAlias *na = NickAlias::Find(target);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- e = na->nc;
- }
-
- if (cmd.equals_ci("ADD"))
- {
- if (info.empty())
- {
- this->OnSyntaxError(source, cmd);
- return;
- }
-
- OperInfos *oi = e->Require<OperInfos>("operinfo");
-
- if ((*oi)->size() >= Config->GetModule(this->module)->Get<unsigned>("max", "10"))
- {
- source.Reply(_("The oper info list for \002%s\002 is full."), target.c_str());
- return;
- }
-
- for (unsigned i = 0; i < (*oi)->size(); ++i)
- {
- OperInfo *o = (*oi)->at(i);
-
- if (o->info.equals_ci(info))
- {
- source.Reply(_("The oper info already exists on \002%s\002."), target.c_str());
- return;
- }
- }
-
- (*oi)->push_back(new OperInfo(target, info, source.GetNick(), Anope::CurTime));
-
- source.Reply(_("Added info to \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to add information to " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- else if (cmd.equals_ci("DEL"))
- {
- if (info.empty())
- {
- this->OnSyntaxError(source, cmd);
- return;
- }
-
- OperInfos *oi = e->GetExt<OperInfos>("operinfo");
-
- if (!oi)
- {
- source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str());
- return;
- }
-
- bool found = false;
- for (unsigned i = (*oi)->size(); i > 0; --i)
- {
- OperInfo *o = (*oi)->at(i - 1);
-
- if (o->info.equals_ci(info))
- {
- delete o;
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- source.Reply(_("No such info \"%s\" on \002%s\002."), info.c_str(), target.c_str());
- }
- else
- {
- if ((*oi)->empty())
- e->Shrink<OperInfos>("operinfo");
-
- source.Reply(_("Deleted info from \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to remove information from " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- }
- else if (cmd.equals_ci("CLEAR"))
- {
- OperInfos *oi = e->GetExt<OperInfos>("operinfo");
-
- if (!oi)
- {
- source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str());
- return;
- }
-
- e->Shrink<OperInfos>("operinfo");
-
- source.Reply(_("Cleared info from \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to clear information for " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- else
- {
- this->OnSyntaxError(source, cmd);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Add or delete oper information for a given nick or channel.\n"
- "This will show to opers in the respective info command for\n"
- "the nick or channel."));
- return true;
- }
-};
-
-class OSInfo : public Module
-{
- CommandOSInfo commandosinfo;
- ExtensibleItem<OperInfos> oinfo;
- Serialize::Type oinfo_type;
-
- void OnInfo(CommandSource &source, Extensible *e, InfoFormatter &info)
- {
- if (!source.IsOper())
- return;
-
- OperInfos *oi = oinfo.Get(e);
- if (!oi)
- return;
-
- for (unsigned i = 0; i < (*oi)->size(); ++i)
- {
- OperInfo *o = (*oi)->at(i);
- info[_("Oper Info")] = Anope::printf(_("(by %s on %s) %s"), o->adder.c_str(), Anope::strftime(o->created, source.GetAccount(), true).c_str(), o->info.c_str());
- }
- }
-
- public:
- OSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosinfo(this), oinfo(this, "operinfo"), oinfo_type("OperInfo", OperInfo::Unserialize)
- {
-
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- OnInfo(source, na->nc, info);
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- OnInfo(source, ci, info);
- }
-};
-
-MODULE_INIT(OSInfo)
diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp
deleted file mode 100644
index c586feee3..000000000
--- a/modules/commands/os_jupe.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 CommandOSJupe : public Command
-{
- public:
- CommandOSJupe(Module *creator) : Command(creator, "operserv/jupe", 1, 2)
- {
- this->SetDesc(_("\"Jupiter\" a server"));
- this->SetSyntax(_("\037server\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &jserver = params[0];
- const Anope::string &reason = params.size() > 1 ? params[1] : "";
- Server *server = Server::Find(jserver, true);
-
- if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos)
- source.Reply(_("Please use a valid server name when juping."));
- else if (server == Me || server == Servers::GetUplink())
- source.Reply(_("You can not jupe your Services' pseudoserver or your uplink server."));
- else if (server && server->IsJuped())
- source.Reply(_("You can not jupe an already juped server."));
- else
- {
- Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : "");
- /* Generate the new sid before quitting the old server, so they can't collide */
- Anope::string sid = IRCD->SID_Retrieve();
- if (server)
- {
- IRCD->SendSquit(server, rbuf);
- server->Delete(rbuf);
- }
- Server *juped_server = new Server(Me, jserver, 1, rbuf, sid, true);
- IRCD->SendServer(juped_server);
-
- Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")";
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells Services to jupiter a server -- that is, to create\n"
- "a fake \"server\" connected to Services which prevents\n"
- "the real server of that name from connecting. The jupe\n"
- "may be removed using a standard \002SQUIT\002. If a reason is\n"
- "given, it is placed in the server information field;\n"
- "otherwise, the server information field will contain the\n"
- "text \"Juped by <nick>\", showing the nickname of the\n"
- "person who jupitered the server."));
- return true;
- }
-};
-
-class OSJupe : public Module
-{
- CommandOSJupe commandosjupe;
-
- public:
- OSJupe(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosjupe(this)
- {
-
- }
-};
-
-MODULE_INIT(OSJupe)
diff --git a/modules/commands/os_kick.cpp b/modules/commands/os_kick.cpp
deleted file mode 100644
index 5a3584240..000000000
--- a/modules/commands/os_kick.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 CommandOSKick : public Command
-{
- public:
- CommandOSKick(Module *creator) : Command(creator, "operserv/kick", 3, 3)
- {
- this->SetDesc(_("Kick a user from a channel"));
- this->SetSyntax(_("\037channel\037 \037user\037 \037reason\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &nick = params[1];
- const Anope::string &s = params[2];
- Channel *c;
- User *u2;
-
- if (!(c = Channel::Find(chan)))
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
-
- if (c->bouncy_modes)
- {
- source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
- return;
- }
-
- if (!(u2 = User::Find(nick, true)))
- {
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- return;
- }
-
- if (!c->Kick(source.service, u2, "%s (%s)", source.GetNick().c_str(), s.c_str()))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "on " << u2->nick << " in " << c->name << " (" << s << ")";
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows staff to kick a user from any channel.\n"
- "Parameters are the same as for the standard /KICK\n"
- "command. The kick message will have the nickname of the\n"
- "IRCop sending the KICK command prepended; for example:\n"
- " \n"
- "*** SpamMan has been kicked off channel #my_channel by %s (Alcan (Flood))"), source.service->nick.c_str());
- return true;
- }
-};
-
-class OSKick : public Module
-{
- CommandOSKick commandoskick;
-
- public:
- OSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoskick(this)
- {
-
- }
-};
-
-MODULE_INIT(OSKick)
diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp
deleted file mode 100644
index b18ffc633..000000000
--- a/modules/commands/os_login.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 CommandOSLogin : public Command
-{
- public:
- CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1)
- {
- this->SetSyntax(_("\037password\037"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &password = params[0];
-
- User *u = source.GetUser();
- Oper *o = source.nc->o;
- if (o == NULL)
- source.Reply(_("No oper block for your nick."));
- else if (o->password.empty())
- source.Reply(_("Your oper block doesn't require logging in."));
- else if (u->HasExt("os_login"))
- source.Reply(_("You are already identified."));
- else if (o->password != password)
- {
- source.Reply(PASSWORD_INCORRECT);
- u->BadPassword();
- }
- else
- {
- Log(LOG_ADMIN, source, this) << "and successfully identified to " << source.service->nick;
- u->Extend<bool>("os_login");
- source.Reply(_("Password accepted."));
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Logs you in to %s so you gain Services Operator privileges.\n"
- "This command may be unnecessary if your oper block is\n"
- "configured without a password."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Login to %s")), source.service->nick.c_str());
- }
-};
-
-class CommandOSLogout : public Command
-{
- public:
- CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0)
- {
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Oper *o = source.nc->o;
- if (o == NULL)
- source.Reply(_("No oper block for your nick."));
- else if (o->password.empty())
- source.Reply(_("Your oper block doesn't require logging in."));
- else if (!u->HasExt("os_login"))
- source.Reply(_("You are not identified."));
- else
- {
- Log(LOG_ADMIN, source, this);
- u->Shrink<bool>("os_login");
- source.Reply(_("You have been logged out."));
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Logs you out from %s so you lose Services Operator privileges.\n"
- "This command is only useful if your oper block is configured\n"
- "with a password."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Logout from %s")), source.service->nick.c_str());
- }
-};
-
-class OSLogin : public Module
-{
- CommandOSLogin commandoslogin;
- CommandOSLogout commandoslogout;
- ExtensibleItem<bool> os_login;
-
- public:
- OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoslogin(this), commandoslogout(this), os_login(this, "os_login")
- {
-
- }
-
- EventReturn IsServicesOper(User *u) anope_override
- {
- if (!u->Account()->o->password.empty())
- {
- if (os_login.HasExt(u))
- return EVENT_ALLOW;
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSLogin)
diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp
deleted file mode 100644
index a35a74584..000000000
--- a/modules/commands/os_news.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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/os_news.h"
-
-/* List of messages for each news type. This simplifies message sending. */
-
-enum
-{
- MSG_SYNTAX,
- MSG_LIST_HEADER,
- MSG_LIST_NONE,
- MSG_ADDED,
- MSG_DEL_NOT_FOUND,
- MSG_DELETED,
- MSG_DEL_NONE,
- MSG_DELETED_ALL
-};
-
-struct NewsMessages msgarray[] = {
- {NEWS_LOGON, "LOGON",
- {_("LOGONNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Logon news items:"),
- _("There is no logon news."),
- _("Added new logon news item."),
- _("Logon news item #%s not found!"),
- _("Logon news item #%d deleted."),
- _("No logon news items to delete!"),
- _("All logon news items deleted.")}
- },
- {NEWS_OPER, "OPER",
- {_("OPERNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Oper news items:"),
- _("There is no oper news."),
- _("Added new oper news item."),
- _("Oper news item #%s not found!"),
- _("Oper news item #%d deleted."),
- _("No oper news items to delete!"),
- _("All oper news items deleted.")}
- },
- {NEWS_RANDOM, "RANDOM",
- {_("RANDOMNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Random news items:"),
- _("There is no random news."),
- _("Added new random news item."),
- _("Random news item #%s not found!"),
- _("Random news item #%d deleted."),
- _("No random news items to delete!"),
- _("All random news items deleted.")}
- }
-};
-
-struct MyNewsItem : NewsItem
-{
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["type"] << this->type;
- data["text"] << this->text;
- data["who"] << this->who;
- data["time"] << this->time;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- if (!news_service)
- return NULL;
-
- NewsItem *ni;
- if (obj)
- ni = anope_dynamic_static_cast<NewsItem *>(obj);
- else
- ni = new MyNewsItem();
-
- unsigned int t;
- data["type"] >> t;
- ni->type = static_cast<NewsType>(t);
- data["text"] >> ni->text;
- data["who"] >> ni->who;
- data["time"] >> ni->time;
-
- if (!obj)
- news_service->AddNewsItem(ni);
- return ni;
- }
-};
-
-class MyNewsService : public NewsService
-{
- std::vector<NewsItem *> newsItems[3];
- public:
- MyNewsService(Module *m) : NewsService(m) { }
-
- ~MyNewsService()
- {
- for (unsigned i = 0; i < 3; ++i)
- for (unsigned j = 0; j < newsItems[i].size(); ++j)
- delete newsItems[i][j];
- }
-
- NewsItem *CreateNewsItem() anope_override
- {
- return new MyNewsItem();
- }
-
- void AddNewsItem(NewsItem *n)
- {
- this->newsItems[n->type].push_back(n);
- }
-
- void DelNewsItem(NewsItem *n)
- {
- std::vector<NewsItem *> &list = this->GetNewsList(n->type);
- std::vector<NewsItem *>::iterator it = std::find(list.begin(), list.end(), n);
- if (it != list.end())
- list.erase(it);
- delete n;
- }
-
- std::vector<NewsItem *> &GetNewsList(NewsType t)
- {
- return this->newsItems[t];
- }
-};
-
-#define lenof(a) (sizeof(a) / sizeof(*(a)))
-static const char **findmsgs(NewsType type)
-{
- for (unsigned i = 0; i < lenof(msgarray); ++i)
- if (msgarray[i].type == type)
- return msgarray[i].msgs;
- return NULL;
-}
-
-class NewsBase : public Command
-{
- ServiceReference<NewsService> ns;
-
- protected:
- void DoList(CommandSource &source, NewsType ntype, const char **msgs)
- {
- std::vector<NewsItem *> &list = this->ns->GetNewsList(ntype);
- if (list.empty())
- source.Reply(msgs[MSG_LIST_NONE]);
- else
- {
- ListFormatter lflist(source.GetAccount());
- lflist.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Text"));
-
- for (unsigned i = 0, end = list.size(); i < end; ++i)
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Creator"] = list[i]->who;
- entry["Created"] = Anope::strftime(list[i]->time, NULL, true);
- entry["Text"] = list[i]->text;
- lflist.AddEntry(entry);
- }
-
- source.Reply(msgs[MSG_LIST_HEADER]);
-
- std::vector<Anope::string> replies;
- lflist.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of news list."));
- }
-
- return;
- }
-
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
- {
- const Anope::string text = params.size() > 1 ? params[1] : "";
-
- if (text.empty())
- this->OnSyntaxError(source, "ADD");
- else
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- NewsItem *news = new MyNewsItem();
- news->type = ntype;
- news->text = text;
- news->time = Anope::CurTime;
- news->who = source.GetNick();
-
- this->ns->AddNewsItem(news);
-
- source.Reply(msgs[MSG_ADDED]);
- Log(LOG_ADMIN, source, this) << "to add a news item";
- }
-
- return;
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
- {
- const Anope::string &text = params.size() > 1 ? params[1] : "";
-
- if (text.empty())
- this->OnSyntaxError(source, "DEL");
- else
- {
- std::vector<NewsItem *> &list = this->ns->GetNewsList(ntype);
- if (list.empty())
- source.Reply(msgs[MSG_LIST_NONE]);
- else
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- if (!text.equals_ci("ALL"))
- {
- try
- {
- unsigned num = convertTo<unsigned>(text);
- if (num > 0 && num <= list.size())
- {
- this->ns->DelNewsItem(list[num - 1]);
- source.Reply(msgs[MSG_DELETED], num);
- Log(LOG_ADMIN, source, this) << "to delete a news item";
- return;
- }
- }
- catch (const ConvertException &) { }
-
- source.Reply(msgs[MSG_DEL_NOT_FOUND], text.c_str());
- }
- else
- {
- for (unsigned i = list.size(); i > 0; --i)
- this->ns->DelNewsItem(list[i - 1]);
- source.Reply(msgs[MSG_DELETED_ALL]);
- Log(LOG_ADMIN, source, this) << "to delete all news items";
- }
- }
- }
-
- return;
- }
-
- void DoNews(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype)
- {
- if (!this->ns)
- return;
-
- const Anope::string &cmd = params[0];
-
- const char **msgs = findmsgs(ntype);
- if (!msgs)
- throw CoreException("news: Invalid type to do_news()");
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, ntype, msgs);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params, ntype, msgs);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params, ntype, msgs);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
- public:
- NewsBase(Module *creator, const Anope::string &newstype) : Command(creator, newstype, 1, 2), ns("NewsService", "news")
- {
- this->SetSyntax(_("ADD \037text\037"));
- this->SetSyntax(_("DEL {\037num\037 | ALL}"));
- this->SetSyntax("LIST");
- }
-
- virtual ~NewsBase()
- {
- }
-
- virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0;
-};
-
-class CommandOSLogonNews : public NewsBase
-{
- public:
- CommandOSLogonNews(Module *creator) : NewsBase(creator, "operserv/logonnews")
- {
- this->SetDesc(_("Define messages to be shown to users at logon"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_LOGON);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of logon news messages. When a\n"
- "user connects to the network, these messages will be sent\n"
- "to them. However, no more than \002%d\002 messages will be\n"
- "sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent."),
- Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
- return true;
- }
-};
-
-class CommandOSOperNews : public NewsBase
-{
- public:
- CommandOSOperNews(Module *creator) : NewsBase(creator, "operserv/opernews")
- {
- this->SetDesc(_("Define messages to be shown to users who oper"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_OPER);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of oper news messages. When a\n"
- "user opers up (with the /OPER command), these messages will\n"
- "be sent to them. However, no more than \002%d\002 messages will\n"
- "be sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent."),
- Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
- return true;
- }
-};
-
-class CommandOSRandomNews : public NewsBase
-{
- public:
- CommandOSRandomNews(Module *creator) : NewsBase(creator, "operserv/randomnews")
- {
- this->SetDesc(_("Define messages to be randomly shown to users at logon"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_RANDOM);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of random news messages. When a\n"
- "user connects to the network, one (and only one) of the\n"
- "random news will be randomly chosen and sent to them."));
- return true;
- }
-};
-
-static unsigned cur_rand_news = 0;
-
-class OSNews : public Module
-{
- MyNewsService newsservice;
- Serialize::Type newsitem_type;
-
- CommandOSLogonNews commandoslogonnews;
- CommandOSOperNews commandosopernews;
- CommandOSRandomNews commandosrandomnews;
-
- Anope::string oper_announcer, announcer;
- unsigned news_count;
-
- void DisplayNews(User *u, NewsType Type)
- {
- std::vector<NewsItem *> &newsList = this->newsservice.GetNewsList(Type);
- if (newsList.empty())
- return;
-
- BotInfo *bi = NULL;
- if (Type == NEWS_OPER)
- bi = BotInfo::Find(Config->GetModule(this)->Get<const Anope::string>("oper_announcer", "OperServ"), true);
- else
- bi = BotInfo::Find(Config->GetModule(this)->Get<const Anope::string>("announcer", "Global"), true);
- if (bi == NULL)
- return;
-
- Anope::string msg;
- if (Type == NEWS_LOGON)
- msg = _("[\002Logon News\002 - %s] %s");
- else if (Type == NEWS_OPER)
- msg = _("[\002Oper News\002 - %s] %s");
- else if (Type == NEWS_RANDOM)
- msg = _("[\002Random News\002 - %s] %s");
-
- int start = 0;
-
- if (Type != NEWS_RANDOM)
- {
- start = newsList.size() - news_count;
- if (start < 0)
- start = 0;
- }
-
- for (unsigned i = start, end = newsList.size(); i < end; ++i)
- {
- if (Type == NEWS_RANDOM && i != cur_rand_news)
- continue;
-
- u->SendMessage(bi, msg.c_str(), Anope::strftime(newsList[i]->time, u->Account(), true).c_str(), newsList[i]->text.c_str());
-
- if (Type == NEWS_RANDOM)
- {
- ++cur_rand_news;
- break;
- }
- }
-
- /* Reset to head of list to get first random news value */
- if (Type == NEWS_RANDOM && cur_rand_news >= newsList.size())
- cur_rand_news = 0;
- }
-
- public:
- OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- newsservice(this), newsitem_type("NewsItem", MyNewsItem::Unserialize),
- commandoslogonnews(this), commandosopernews(this), commandosrandomnews(this)
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- oper_announcer = conf->GetModule(this)->Get<const Anope::string>("oper_announcer", "OperServ");
- announcer = conf->GetModule(this)->Get<const Anope::string>("announcer", "Global");
- news_count = conf->GetModule(this)->Get<unsigned>("newscount", "3");
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (mname == "OPER")
- DisplayNews(u, NEWS_OPER);
- }
-
- void OnUserConnect(User *user, bool &) anope_override
- {
- if (user->Quitting() || !user->server->IsSynced())
- return;
-
- DisplayNews(user, NEWS_LOGON);
- DisplayNews(user, NEWS_RANDOM);
- }
-};
-
-MODULE_INIT(OSNews)
diff --git a/modules/commands/os_oper.cpp b/modules/commands/os_oper.cpp
deleted file mode 100644
index f5ac80160..000000000
--- a/modules/commands/os_oper.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-struct MyOper : Oper, Serializable
-{
- MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["name"] << this->name;
- data["type"] << this->ot->GetName();
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string stype, sname;
-
- data["type"] >> stype;
- data["name"] >> sname;
-
- OperType *ot = OperType::Find(stype);
- if (ot == NULL)
- return NULL;
- NickCore *nc = NickCore::Find(sname);
- if (nc == NULL)
- return NULL;
-
- MyOper *myo;
- if (obj)
- myo = anope_dynamic_static_cast<MyOper *>(obj);
- else
- myo = new MyOper(nc->display, ot);
- nc->o = myo;
- Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
- return myo;
- }
-};
-
-class CommandOSOper : public Command
-{
- bool HasPrivs(CommandSource &source, OperType *ot) const
- {
- std::list<Anope::string> commands = ot->GetCommands(), privs = ot->GetPrivs();
-
- for (std::list<Anope::string>::iterator it = commands.begin(); it != commands.end(); ++it)
- if (!source.HasCommand(*it))
- return false;
-
- for (std::list<Anope::string>::iterator it = privs.begin(); it != privs.end(); ++it)
- if (!source.HasPriv(*it))
- return false;
-
- return true;
- }
-
- public:
- CommandOSOper(Module *creator) : Command(creator, "operserv/oper", 1, 3)
- {
- this->SetDesc(_("View and change Services Operators"));
- this->SetSyntax(_("ADD \037oper\037 \037type\037"));
- this->SetSyntax(_("DEL \037oper\037"));
- this->SetSyntax(_("INFO [\037type\037]"));
- this->SetSyntax("LIST");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcommand = params[0];
-
- if (subcommand.equals_ci("ADD") && params.size() > 2)
- {
- const Anope::string &oper = params[1];
- const Anope::string &otype = params[2];
-
- if (!source.HasPriv("operserv/oper/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(oper);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
- else if (na->nc->o)
- source.Reply(_("Nick \002%s\002 is already an operator."), na->nick.c_str());
- else
- {
- OperType *ot = OperType::Find(otype);
- if (ot == NULL)
- {
- source.Reply(_("Oper type \002%s\002 has not been configured."), otype.c_str());
- return;
- }
-
- if (!HasPrivs(source, ot))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- na->nc->o = new MyOper(na->nc->display, ot);
- na->nc->o->require_oper = true;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "ADD " << na->nick << " as type " << ot->GetName();
- source.Reply("%s (%s) added to the \002%s\002 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str());
- }
- }
- else if (subcommand.equals_ci("DEL") && params.size() > 1)
- {
- const Anope::string &oper = params[1];
-
- if (!source.HasPriv("operserv/oper/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(oper);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
- else if (!na->nc || !na->nc->o)
- source.Reply(_("Nick \002%s\002 is not a Services Operator."), oper.c_str());
- else if (!HasPrivs(source, na->nc->o->ot))
- source.Reply(ACCESS_DENIED);
- else if (std::find(Config->Opers.begin(), Config->Opers.end(), na->nc->o) != Config->Opers.end())
- source.Reply(_("Oper \002%s\002 is configured in the configuration file(s) and can not be removed by this command."), na->nc->display.c_str());
- else
- {
- delete na->nc->o;
- na->nc->o = NULL;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "DEL " << na->nick;
- source.Reply(_("Oper privileges removed from %s (%s)."), na->nick.c_str(), na->nc->display.c_str());
- }
- }
- else if (subcommand.equals_ci("LIST"))
- {
- source.Reply(_("Name Type"));
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (!nc->o)
- continue;
-
- source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str());
- if (std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end())
- source.Reply(_(" This oper is configured in the configuration file."));
- for (std::list<User *>::const_iterator uit = nc->users.begin(); uit != nc->users.end(); ++uit)
- {
- User *u = *uit;
- source.Reply(_(" %s is online using this oper block."), u->nick.c_str());
- }
- }
- }
- else if (subcommand.equals_ci("INFO"))
- {
- if (params.size() < 2)
- {
- source.Reply(_("Available opertypes:"));
- for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
- {
- OperType *ot = Config->MyOperTypes[i];
- source.Reply("%s", ot->GetName().c_str());
- }
- return;
- }
-
- Anope::string fulltype = params[1];
- if (params.size() > 2)
- fulltype += " " + params[2];
- OperType *ot = OperType::Find(fulltype);
- if (ot == NULL)
- source.Reply(_("Oper type \002%s\002 has not been configured."), fulltype.c_str());
- else
- {
- if (ot->GetCommands().empty())
- source.Reply(_("Opertype \002%s\002 has no allowed commands."), ot->GetName().c_str());
- else
- {
- source.Reply(_("Available commands for \002%s\002:"), ot->GetName().c_str());
- Anope::string buf;
- std::list<Anope::string> cmds = ot->GetCommands();
- for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it)
- {
- buf += *it + " ";
- if (buf.length() > 400)
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (ot->GetPrivs().empty())
- source.Reply(_("Opertype \002%s\002 has no allowed privileges."), ot->GetName().c_str());
- else
- {
- source.Reply(_("Available privileges for \002%s\002:"), ot->GetName().c_str());
- Anope::string buf;
- std::list<Anope::string> privs = ot->GetPrivs();
- for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it)
- {
- buf += *it + " ";
- if (buf.length() > 400)
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!ot->modes.empty())
- source.Reply(_("Opertype \002%s\002 receives modes \002%s\002 once identified."), ot->GetName().c_str(), ot->modes.c_str());
- }
- }
- else
- this->OnSyntaxError(source, subcommand);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to change and view Services Operators.\n"
- "Note that operators removed by this command but are still set in\n"
- "the configuration file are not permanently affected by this."));
- return true;
- }
-};
-
-class OSOper : public Module
-{
- Serialize::Type myoper_type;
- CommandOSOper commandosoper;
-
- public:
- OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- myoper_type("Oper", MyOper::Unserialize), commandosoper(this)
- {
- }
-
- ~OSOper()
- {
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- NickCore *nc = it->second;
-
- if (nc->o && dynamic_cast<MyOper *>(nc->o))
- {
- delete nc->o;
- nc->o = NULL;
- }
- }
- }
-
- void OnDelCore(NickCore *nc) anope_override
- {
- if (nc->o && dynamic_cast<MyOper *>(nc->o))
- {
- delete nc->o;
- nc->o = NULL;
- }
- }
-};
-
-MODULE_INIT(OSOper)
diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp
deleted file mode 100644
index 1ab3c3c87..000000000
--- a/modules/commands/os_reload.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 CommandOSReload : public Command
-{
- public:
- CommandOSReload(Module *creator) : Command(creator, "operserv/reload", 0, 0)
- {
- this->SetDesc(_("Reload services' configuration file"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- try
- {
- Log(LOG_ADMIN, source, this);
-
- Configuration::Conf *new_config = new Configuration::Conf();
- Configuration::Conf *old = Config;
- Config = new_config;
- Config->Post(old);
- delete old;
-
- source.Reply(_("Services' configuration has been reloaded."));
- }
- catch (const ConfigException &ex)
- {
- Log(this->owner) << "Error reloading configuration file: " << ex.GetReason();
- source.Reply(_("Error reloading configuration file: %s"), ex.GetReason().c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to reload the configuration file. Note that\n"
- "some directives still need the restart of the Services to\n"
- "take effect (such as Services' nicknames, activation of the\n"
- "session limitation, etc.)."));
- return true;
- }
-};
-
-class OSReload : public Module
-{
- CommandOSReload commandosreload;
-
- public:
- OSReload(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosreload(this)
- {
-
- }
-};
-
-MODULE_INIT(OSReload)
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
deleted file mode 100644
index e8f1e241a..000000000
--- a/modules/commands/os_session.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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/os_session.h"
-
-namespace
-{
- /* The default session limit */
- unsigned session_limit;
- /* How many times to kill before adding an AKILL */
- unsigned max_session_kill;
- /* How long session akills should last */
- time_t session_autokill_expiry;
- /* Reason to use for session kills */
- Anope::string sle_reason;
- /* Optional second reason */
- Anope::string sle_detailsloc;
-
- /* Max limit that can be used for exceptions */
- unsigned max_exception_limit;
- /* How long before exceptions expire by default */
- time_t exception_expiry;
-
- /* Number of bits to use when comparing session IPs */
- unsigned ipv4_cidr;
- unsigned ipv6_cidr;
-}
-
-class MySessionService : public SessionService
-{
- SessionMap Sessions;
- Serialize::Checker<ExceptionVector> Exceptions;
- public:
- MySessionService(Module *m) : SessionService(m), Exceptions("Exception") { }
-
- Exception *CreateException() anope_override
- {
- return new Exception();
- }
-
- void AddException(Exception *e) anope_override
- {
- this->Exceptions->push_back(e);
- }
-
- void DelException(Exception *e) anope_override
- {
- ExceptionVector::iterator it = std::find(this->Exceptions->begin(), this->Exceptions->end(), e);
- if (it != this->Exceptions->end())
- this->Exceptions->erase(it);
- }
-
- Exception *FindException(User *u) anope_override
- {
- for (std::vector<Exception *>::const_iterator it = this->Exceptions->begin(), it_end = this->Exceptions->end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (Anope::Match(u->host, e->mask) || Anope::Match(u->ip.addr(), e->mask))
- return e;
-
- if (cidr(e->mask).match(u->ip))
- return e;
- }
- return NULL;
- }
-
- Exception *FindException(const Anope::string &host) anope_override
- {
- for (std::vector<Exception *>::const_iterator it = this->Exceptions->begin(), it_end = this->Exceptions->end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (Anope::Match(host, e->mask))
- return e;
-
- if (cidr(e->mask).match(sockaddrs(host)))
- return e;
- }
-
- return NULL;
- }
-
- ExceptionVector &GetExceptions() anope_override
- {
- return this->Exceptions;
- }
-
- void DelSession(Session *s)
- {
- this->Sessions.erase(s->addr);
- }
-
- Session *FindSession(const Anope::string &ip) anope_override
- {
- cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
- if (!c.valid())
- return NULL;
- SessionMap::iterator it = this->Sessions.find(c);
- if (it != this->Sessions.end())
- return it->second;
- return NULL;
- }
-
- SessionMap::iterator FindSessionIterator(const sockaddrs &ip)
- {
- cidr c(ip, ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- if (!c.valid())
- return this->Sessions.end();
- return this->Sessions.find(c);
- }
-
- Session* &FindOrCreateSession(const cidr &ip)
- {
- return this->Sessions[ip];
- }
-
- SessionMap &GetSessions() anope_override
- {
- return this->Sessions;
- }
-};
-
-class ExceptionDelCallback : public NumberList
-{
- protected:
- CommandSource &source;
- unsigned deleted;
- Command *cmd;
- public:
- ExceptionDelCallback(CommandSource &_source, const Anope::string &numlist, Command *c) : NumberList(numlist, true), source(_source), deleted(0), cmd(c)
- {
- }
-
- ~ExceptionDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on session-limit exception list."));
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from session-limit exception list."));
- else
- source.Reply(_("Deleted %d entries from session-limit exception list."), deleted);
- }
-
- virtual void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > session_service->GetExceptions().size())
- return;
-
- Log(LOG_ADMIN, source, cmd) << "to remove the session limit exception for " << session_service->GetExceptions()[number - 1]->mask;
-
- ++deleted;
- DoDel(source, number - 1);
- }
-
- static void DoDel(CommandSource &source, unsigned index)
- {
- Exception *e = session_service->GetExceptions()[index];
- FOREACH_MOD(OnExceptionDel, (source, e));
-
- session_service->DelException(e);
- delete e;
- }
-};
-
-class CommandOSSession : public Command
-{
- private:
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string param = params[1];
-
- unsigned mincount = 0;
- try
- {
- mincount = convertTo<unsigned>(param);
- }
- catch (const ConvertException &) { }
-
- if (mincount <= 1)
- source.Reply(_("Invalid threshold value. It must be a valid integer greater than 1."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Session")).AddColumn(_("Host"));
-
- for (SessionService::SessionMap::iterator it = session_service->GetSessions().begin(), it_end = session_service->GetSessions().end(); it != it_end; ++it)
- {
- Session *session = it->second;
-
- if (session->count >= mincount)
- {
- ListFormatter::ListEntry entry;
- entry["Session"] = stringify(session->count);
- entry["Host"] = session->addr.mask();
- list.AddEntry(entry);
- }
- }
-
- source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount);
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- return;
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string param = params[1];
- Session *session = session_service->FindSession(param);
-
- Exception *exception = session_service->FindException(param);
- Anope::string entry = "no entry";
- unsigned limit = session_limit;
- if (exception)
- {
- if (!exception->limit)
- limit = 0;
- else if (exception->limit > limit)
- limit = exception->limit;
- entry = exception->mask;
- }
-
- if (!session)
- source.Reply(_("\002%s\002 not found on session list, but has a limit of \002%d\002 because it matches entry: \002%s\002."), param.c_str(), limit, entry.c_str());
- else
- source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002 because it matches entry: \002%s\002."), session->addr.mask().c_str(), session->count, limit, entry.c_str());
- }
- public:
- CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2)
- {
- this->SetDesc(_("View the list of host sessions"));
- this->SetSyntax(_("LIST \037threshold\037"));
- this->SetSyntax(_("VIEW \037host\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- Log(LOG_ADMIN, source, this) << cmd << " " << params[1];
-
- if (!session_limit)
- source.Reply(_("Session limiting is disabled."));
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to view the session list.\n"
- " \n"
- "\002SESSION LIST\002 lists hosts with at least \037threshold\037 sessions.\n"
- "The threshold must be a number greater than 1. This is to\n"
- "prevent accidental listing of the large number of single\n"
- "session hosts.\n"
- " \n"
- "\002SESSION VIEW\002 displays detailed information about a specific\n"
- "host - including the current session count and session limit.\n"
- "The \037host\037 value may not include wildcards.\n"
- " \n"
- "See the \002EXCEPTION\002 help for more information about session\n"
- "limiting and how to set session limits specific to certain\n"
- "hosts and groups thereof."));
- return true;
- }
-};
-
-class CommandOSException : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string mask, expiry, limitstr;
- unsigned last_param = 3;
-
- mask = params.size() > 1 ? params[1] : "";
- if (!mask.empty() && mask[0] == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2] : "";
- last_param = 4;
- }
-
- limitstr = params.size() > last_param - 1 ? params[last_param - 1] : "";
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (last_param == 3 && params.size() > 4)
- reason += " " + params[4];
- if (reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry;
- if (expires < 0)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- unsigned limit = -1;
- try
- {
- limit = convertTo<unsigned>(limitstr);
- }
- catch (const ConvertException &) { }
-
- if (limit > max_exception_limit)
- {
- source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), max_exception_limit);
- return;
- }
- else
- {
- if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
- {
- source.Reply(_("Invalid hostmask. Only real hostmasks are valid, as exceptions are not matched against nicks or usernames."));
- return;
- }
-
- for (std::vector<Exception *>::iterator it = session_service->GetExceptions().begin(), it_end = session_service->GetExceptions().end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (e->mask.equals_ci(mask))
- {
- if (e->limit != limit)
- {
- e->limit = limit;
- source.Reply(_("Exception for \002%s\002 has been updated to %d."), mask.c_str(), e->limit);
- }
- else
- source.Reply(_("\002%s\002 already exists on the EXCEPTION list."), mask.c_str());
- return;
- }
- }
-
- Exception *exception = new Exception();
- exception->mask = mask;
- exception->limit = limit;
- exception->reason = reason;
- exception->time = Anope::CurTime;
- exception->who = source.GetNick();
- exception->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnExceptionAdd, MOD_RESULT, (exception));
- if (MOD_RESULT == EVENT_STOP)
- delete exception;
- else
- {
- Log(LOG_ADMIN, source, this) << "to set the session limit for " << mask << " to " << limit;
- session_service->AddException(exception);
- source.Reply(_("Session limit for \002%s\002 set to \002%d\002."), mask.c_str(), limit);
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- }
-
- return;
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- ExceptionDelCallback list(source, mask, this);
- list.Process();
- }
- else
- {
- unsigned i = 0, end = session_service->GetExceptions().size();
- for (; i < end; ++i)
- if (mask.equals_ci(session_service->GetExceptions()[i]->mask))
- {
- Log(LOG_ADMIN, source, this) << "to remove the session limit exception for " << mask;
- ExceptionDelCallback::DoDel(source, i);
- source.Reply(_("\002%s\002 deleted from session-limit exception list."), mask.c_str());
- break;
- }
- if (i == end)
- source.Reply(_("\002%s\002 not found on session-limit exception list."), mask.c_str());
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (session_service->GetExceptions().empty())
- {
- source.Reply(_("The session exception list is empty."));
- return;
- }
-
- if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class ExceptionListCallback : public NumberList
- {
- CommandSource &source;
- ListFormatter &list;
- public:
- ExceptionListCallback(CommandSource &_source, ListFormatter &_list, const Anope::string &numlist) : NumberList(numlist, false), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > session_service->GetExceptions().size())
- return;
-
- Exception *e = session_service->GetExceptions()[Number - 1];
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
- entry["Mask"] = e->mask;
- entry["By"] = e->who;
- entry["Created"] = Anope::strftime(e->time, NULL, true);
- entry["Expires"] = Anope::Expires(e->expires, source.GetAccount());
- entry["Limit"] = stringify(e->limit);
- entry["Reason"] = e->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(source, list, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = session_service->GetExceptions().size(); i < end; ++i)
- {
- Exception *e = session_service->GetExceptions()[i];
- if (mask.empty() || Anope::Match(e->mask, mask))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = e->mask;
- entry["By"] = e->who;
- entry["Created"] = Anope::strftime(e->time, NULL, true);
- entry["Expires"] = Anope::Expires(e->expires, source.GetAccount());
- entry["Limit"] = stringify(e->limit);
- entry["Reason"] = e->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on session-limit exception list."));
- else
- {
- source.Reply(_("Current Session Limit Exception list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Limit")).AddColumn(_("Mask"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires")).AddColumn(_("Limit")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- public:
- CommandOSException(Module *creator) : Command(creator, "operserv/exception", 1, 5)
- {
- this->SetDesc(_("Modify the session-limit exception list"));
- this->SetSyntax(_("ADD [\037+expiry\037] \037mask\037 \037limit\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (!session_limit)
- source.Reply(_("Session limiting is disabled."));
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the list of hosts that\n"
- "have specific session limits - allowing certain machines,\n"
- "such as shell servers, to carry more than the default number\n"
- "of clients at a time. Once a host reaches its session limit,\n"
- "all clients attempting to connect from that host will be\n"
- "killed. Before the user is killed, they are notified, of a\n"
- "source of help regarding session limiting. The content of\n"
- "this notice is a config setting."));
- source.Reply(" ");
- source.Reply(_("\002EXCEPTION ADD\002 adds the given host mask to the exception list.\n"
- "Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n"
- "Only real host masks, such as \002box.host.dom\002 and \002*.host.dom\002,\n"
- "are allowed because sessions limiting does not take nick or\n"
- "user names into account. \037limit\037 must be a number greater than\n"
- "or equal to zero. This determines how many sessions this host\n"
- "may carry at a time. A value of zero means the host has an\n"
- "unlimited session limit. See the \002AKILL\002 help for details about\n"
- "the format of the optional \037expiry\037 parameter.\n"
- " \n"
- "\002EXCEPTION DEL\002 removes the given mask from the exception list.\n"
- " \n"
- "\002EXCEPTION LIST\002 and \002EXCEPTION VIEW\002 show all current\n"
- "sessions if the optional mask is given, the list is limited\n"
- "to those sessions matching the mask. The difference is that\n"
- "\002EXCEPTION VIEW\002 is more verbose, displaying the name of the\n"
- "person who added the exception, its session limit, reason,\n"
- "host mask and the expiry date and time.\n"
- " \n"
- "Note that a connecting client will \"use\" the first exception\n"
- "their host matches."));
- return true;
- }
-};
-
-class OSSession : public Module
-{
- Serialize::Type exception_type;
- MySessionService ss;
- CommandOSSession commandossession;
- CommandOSException commandosexception;
- ServiceReference<XLineManager> akills;
-
- public:
- OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline")
- {
- this->SetPermanent(true);
- }
-
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = Config->GetModule(this);
-
- session_limit = block->Get<int>("defaultsessionlimit");
- max_session_kill = block->Get<int>("maxsessionkill");
- session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
- sle_reason = block->Get<const Anope::string>("sessionlimitexceeded");
- sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc");
-
- max_exception_limit = block->Get<int>("maxsessionlimit");
- exception_expiry = block->Get<time_t>("exceptionexpiry");
-
- ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32");
- ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128");
-
- if (ipv4_cidr > 32 || ipv6_cidr > 128)
- throw ConfigException(this->name + ": session CIDR value out of range");
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined())
- return;
-
- cidr u_ip(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- if (!u_ip.valid())
- return;
-
- Session* &session = this->ss.FindOrCreateSession(u_ip);
-
- if (session)
- {
- bool kill = false;
- if (session->count >= session_limit)
- {
- kill = true;
- Exception *exception = this->ss.FindException(u);
- if (exception)
- {
- kill = false;
- if (exception->limit && session->count >= exception->limit)
- kill = true;
- }
- }
-
- /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
- * decremented in do_quit, which caused problems and fixed here
- *
- * Now, we create the user struture before calling this to fix some user tracking issues,
- * so we must increment this here no matter what because it will either be
- * decremented when the user is killed or quits - Adam
- */
- ++session->count;
-
- if (kill && !exempt)
- {
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (OperServ)
- {
- if (!sle_reason.empty())
- {
- Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip.addr());
- u->SendMessage(OperServ, message);
- }
- if (!sle_detailsloc.empty())
- u->SendMessage(OperServ, sle_detailsloc);
- }
-
- ++session->hits;
-
- const Anope::string &akillmask = "*@" + session->addr.mask();
- if (max_session_kill && session->hits >= max_session_kill && akills && !akills->HasEntry(akillmask))
- {
- XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID());
- akills->AddXLine(x);
- akills->Send(NULL, x);
- Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
- }
- else
- {
- u->Kill(OperServ, "Session limit exceeded");
- }
- }
- }
- else
- {
- session = new Session(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- }
- }
-
- void OnUserQuit(User *u, const Anope::string &msg) anope_override
- {
- if (!session_limit || !u->server || u->server->IsULined())
- return;
-
- SessionService::SessionMap &sessions = this->ss.GetSessions();
- SessionService::SessionMap::iterator sit = this->ss.FindSessionIterator(u->ip);
-
- if (sit == sessions.end())
- return;
-
- Session *session = sit->second;
-
- if (session->count > 1)
- {
- --session->count;
- return;
- }
-
- delete session;
- sessions.erase(sit);
- }
-
- void OnExpireTick() anope_override
- {
- if (Anope::NoExpire)
- return;
- for (unsigned i = this->ss.GetExceptions().size(); i > 0; --i)
- {
- Exception *e = this->ss.GetExceptions()[i - 1];
-
- if (!e->expires || e->expires > Anope::CurTime)
- continue;
- BotInfo *OperServ = Config->GetClient("OperServ");
- Log(OperServ, "expire/exception") << "Session exception for " << e->mask << " has expired.";
- this->ss.DelException(e);
- delete e;
- }
- }
-};
-
-MODULE_INIT(OSSession)
diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp
deleted file mode 100644
index 306100cea..000000000
--- a/modules/commands/os_stats.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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/os_session.h"
-
-struct Stats : Serializable
-{
- static Stats *me;
-
- Stats() : Serializable("Stats")
- {
- me = this;
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["maxusercnt"] << MaxUserCount;
- data["maxusertime"] << MaxUserTime;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- data["maxusercnt"] >> MaxUserCount;
- data["maxusertime"] >> MaxUserTime;
- return me;
- }
-};
-
-Stats *Stats::me;
-
-/**
- * Count servers connected to server s
- * @param s The server to start counting from
- * @return Amount of servers connected to server s
- **/
-static int stats_count_servers(Server *s)
-{
- if (!s)
- return 0;
-
- int count = 1;
-
- if (!s->GetLinks().empty())
- for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
- count += stats_count_servers(s->GetLinks()[i]);
-
- return count;
-}
-
-class CommandOSStats : public Command
-{
- ServiceReference<XLineManager> akills, snlines, sqlines;
- private:
- void DoStatsAkill(CommandSource &source)
- {
- int timeout;
- if (akills)
- {
- /* AKILLs */
- source.Reply(_("Current number of AKILLs: \002%d\002"), akills->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default AKILL expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default AKILL expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default AKILL expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default AKILL expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default AKILL expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default AKILL expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default AKILL expiry time: \002No expiration\002"));
- }
- if (snlines)
- {
- /* SNLINEs */
- source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default SNLINE expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default SNLINE expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default SNLINE expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default SNLINE expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default SNLINE expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default SNLINE expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default SNLINE expiry time: \002No expiration\002"));
- }
- if (sqlines)
- {
- /* SQLINEs */
- source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default SQLINE expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default SQLINE expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default SQLINE expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default SQLINE expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default SQLINE expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default SQLINE expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default SQLINE expiry time: \002No expiration\002"));
- }
- }
-
- void DoStatsReset(CommandSource &source)
- {
- MaxUserCount = UserListByNick.size();
- source.Reply(_("Statistics reset."));
- return;
- }
-
- void DoStatsUptime(CommandSource &source)
- {
- time_t uptime = Anope::CurTime - Anope::StartTime;
- source.Reply(_("Current users: \002%d\002 (\002%d\002 ops)"), UserListByNick.size(), OperCount);
- source.Reply(_("Maximum users: \002%d\002 (%s)"), MaxUserCount, Anope::strftime(MaxUserTime, source.GetAccount()).c_str());
- source.Reply(_("Services up %s."), Anope::Duration(uptime, source.GetAccount()).c_str());
-
- return;
- }
-
- void DoStatsUplink(CommandSource &source)
- {
- Anope::string buf;
- for (std::set<Anope::string>::iterator it = Servers::Capab.begin(); it != Servers::Capab.end(); ++it)
- buf += " " + *it;
- if (!buf.empty())
- buf.erase(buf.begin());
-
- source.Reply(_("Uplink server: %s"), Me->GetLinks().front()->GetName().c_str());
- source.Reply(_("Uplink capab: %s"), buf.c_str());
- source.Reply(_("Servers found: %d"), stats_count_servers(Me->GetLinks().front()));
- return;
- }
-
- template<typename T> void GetHashStats(const T& map, size_t& entries, size_t& buckets, size_t& max_chain)
- {
- entries = map.size(), buckets = map.bucket_count(), max_chain = 0;
- for (size_t i = 0; i < buckets; ++i)
- if (map.bucket_size(i) > max_chain)
- max_chain = map.bucket_size(i);
- }
-
- void DoStatsHash(CommandSource &source)
- {
- size_t entries, buckets, max_chain;
-
- GetHashStats(UserListByNick, entries, buckets, max_chain);
- source.Reply(_("Users (nick): %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- if (!UserListByUID.empty())
- {
- GetHashStats(UserListByUID, entries, buckets, max_chain);
- source.Reply(_("Users (uid): %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
- }
-
- GetHashStats(ChannelList, entries, buckets, max_chain);
- source.Reply(_("Channels: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*RegisteredChannelList, entries, buckets, max_chain);
- source.Reply(_("Registered channels: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*NickAliasList, entries, buckets, max_chain);
- source.Reply(_("Registered nicknames: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*NickCoreList, entries, buckets, max_chain);
- source.Reply(_("Registered nick groups: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- if (session_service)
- {
- GetHashStats(session_service->GetSessions(), entries, buckets, max_chain);
- source.Reply(_("Sessions: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
- }
- }
-
- public:
- CommandOSStats(Module *creator) : Command(creator, "operserv/stats", 0, 1),
- akills("XLineManager", "xlinemanager/sgline"), snlines("XLineManager", "xlinemanager/snline"), sqlines("XLineManager", "xlinemanager/sqline")
- {
- this->SetDesc(_("Show status of Services and network"));
- this->SetSyntax("[AKILL | HASH | UPLINK | UPTIME | ALL | RESET]");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string extra = !params.empty() ? params[0] : "";
-
- Log(LOG_ADMIN, source, this) << extra;
-
- if (extra.equals_ci("RESET"))
- return this->DoStatsReset(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("AKILL"))
- this->DoStatsAkill(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("HASH"))
- this->DoStatsHash(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("UPLINK"))
- this->DoStatsUplink(source);
-
- if (extra.empty() || extra.equals_ci("ALL") || extra.equals_ci("UPTIME"))
- this->DoStatsUptime(source);
-
- if (!extra.empty() && !extra.equals_ci("ALL") && !extra.equals_ci("AKILL") && !extra.equals_ci("HASH") && !extra.equals_ci("UPLINK") && !extra.equals_ci("UPTIME"))
- source.Reply(_("Unknown STATS option: \002%s\002"), extra.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without any option, shows the current number of users online,\n"
- "and the highest number of users online since Services was\n"
- "started, and the length of time Services has been running.\n"
- " \n"
- "With the \002AKILL\002 option, displays the current size of the\n"
- "AKILL list and the current default expiry time.\n"
- " \n"
- "The \002RESET\002 option currently resets the maximum user count\n"
- "to the number of users currently present on the network.\n"
- " \n"
- "The \002UPLINK\002 option displays information about the current\n"
- "server Anope uses as an uplink to the network.\n"
- " \n"
- "The \002HASH\002 option displays information about the hash maps.\n"
- " \n"
- "The \002ALL\002 option displays all of the above statistics."));
- return true;
- }
-};
-
-class OSStats : public Module
-{
- CommandOSStats commandosstats;
- Serialize::Type stats_type;
- Stats stats_saver;
-
- public:
- OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosstats(this), stats_type("Stats", Stats::Unserialize)
- {
-
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (UserListByNick.size() == MaxUserCount && Anope::CurTime == MaxUserTime)
- stats_saver.QueueUpdate();
- }
-};
-
-MODULE_INIT(OSStats)
diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp
deleted file mode 100644
index 0de21ce02..000000000
--- a/modules/commands/os_sxline.cpp
+++ /dev/null
@@ -1,732 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 SXLineDelCallback : public NumberList
-{
- XLineManager *xlm;
- Command *command;
- CommandSource &source;
- unsigned deleted;
- public:
- SXLineDelCallback(XLineManager *x, Command *c, CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, true), xlm(x), command(c), source(_source), deleted(0)
- {
- }
-
- ~SXLineDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on the %s list."), source.command.c_str());
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from the %s list."), source.command.c_str());
- else
- source.Reply(_("Deleted %d entries from the %s list."), deleted, source.command.c_str());
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- XLine *x = this->xlm->GetEntry(number - 1);
-
- if (!x)
- return;
-
- Log(LOG_ADMIN, source, command) << "to remove " << x->mask << " from the list";
-
- ++deleted;
- DoDel(this->xlm, source, x);
- }
-
- static void DoDel(XLineManager *xlm, CommandSource &source, XLine *x)
- {
- xlm->DelXLine(x);
- }
-};
-
-class CommandOSSXLineBase : public Command
-{
- private:
- virtual XLineManager* xlm() = 0;
-
- virtual void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) = 0;
-
- void OnDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
-
- if (!this->xlm() || this->xlm()->GetList().empty())
- {
- source.Reply(_("%s list is empty."), source.command.c_str());
- return;
- }
-
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- SXLineDelCallback list(this->xlm(), this, source, mask);
- list.Process();
- }
- else
- {
- XLine *x = this->xlm()->HasEntry(mask);
-
- if (!x)
- {
- source.Reply(_("\002%s\002 not found on the %s list."), mask.c_str(), source.command.c_str());
- return;
- }
-
- FOREACH_MOD(OnDelXLine, (source, x, this->xlm()));
-
- SXLineDelCallback::DoDel(this->xlm(), source, x);
- source.Reply(_("\002%s\002 deleted from the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "to remove " << mask << " from the list";
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- if (!this->xlm() || this->xlm()->GetList().empty())
- {
- source.Reply(_("%s list is empty."), source.command.c_str());
- return;
- }
-
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class SXLineListCallback : public NumberList
- {
- XLineManager *xlm;
- CommandSource &source;
- ListFormatter &list;
- public:
- SXLineListCallback(XLineManager *x, CommandSource &_source, ListFormatter &_list, const Anope::string &numlist) : NumberList(numlist, false), xlm(x), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- const XLine *x = this->xlm->GetEntry(number - 1);
-
- if (!x)
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Mask"] = x->mask;
- entry["By"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- sl_list(this->xlm(), source, list, mask);
- sl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = this->xlm()->GetCount(); i < end; ++i)
- {
- const XLine *x = this->xlm()->GetEntry(i);
-
- if (mask.empty() || mask.equals_ci(x->mask) || mask == x->id || Anope::Match(x->mask, mask, false, true))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = x->mask;
- entry["By"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on the %s list."), source.command.c_str());
- else
- {
- source.Reply(_("Current %s list:"), source.command.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void OnList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void OnView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires"));
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- list.AddColumn(_("ID"));
- list.AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void OnClear(CommandSource &source)
- {
- FOREACH_MOD(OnDelXLine, (source, NULL, this->xlm()));
-
- for (unsigned i = this->xlm()->GetCount(); i > 0; --i)
- {
- XLine *x = this->xlm()->GetEntry(i - 1);
- this->xlm()->DelXLine(x);
- }
-
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("The %s list has been cleared."), source.command.c_str());
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
- public:
- CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 4)
- {
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Manipulate the %s list")), source.command.upper().c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (cmd.equals_ci("ADD"))
- return this->OnAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->OnDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->OnList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->OnView(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->OnClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0;
-};
-
-class CommandOSSNLine : public CommandOSSXLineBase
-{
- XLineManager *xlm()
- {
- return this->snlines;
- }
-
- void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->xlm())
- return;
-
- unsigned last_param = 2;
- Anope::string param, expiry;
-
- param = params.size() > 1 ? params[1] : "";
- if (!param.empty() && param[0] == '+')
- {
- expiry = param;
- param = params.size() > 2 ? params[2] : "";
- last_param = 3;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (param.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string rest = param;
- if (params.size() > last_param)
- rest += " " + params[last_param];
-
- if (rest.find(':') == Anope::string::npos)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- sepstream sep(rest, ':');
- Anope::string mask;
- sep.GetToken(mask);
- Anope::string reason = sep.GetRemaining();
-
- if (mask.empty() || reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- /* Clean up the last character of the mask if it is a space
- * See bug #761
- */
- unsigned masklen = mask.length();
- if (mask[masklen - 1] == ' ')
- mask.erase(masklen - 1);
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("/.*?") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (this->xlm()->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to " << source.command << " " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!this->xlm()->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, this->xlm()));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- this->xlm()->AddXLine(x);
-
- if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes"))
- {
- Anope::string rreason = "G-Lined: " + reason;
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *user = it->second;
-
- if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
- user->Kill(Me, rreason);
- }
-
- this->xlm()->Send(NULL, x);
- }
-
- source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- ServiceReference<XLineManager> snlines;
- public:
- CommandOSSNLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/snline"), snlines("XLineManager", "xlinemanager/snline")
- {
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the SNLINE list. If\n"
- "a user with a realname matching an SNLINE mask attempts to\n"
- "connect, Services will not allow it to pursue his IRC\n"
- "session."));
- source.Reply(_(" \n"
- "\002SNLINE ADD\002 adds the given realname mask to the SNLINE\n"
- "list for the given reason (which \002must\002 be given).\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an SNLINE which does not expire, use \037+0\037. If the\n"
- "realname mask to be added starts with a \037+\037, an expiry time must\n"
- "be given, even if it is the same as the default. The\n"
- "current SNLINE default expiry time can be found with the\n"
- "\002STATS AKILL\002 command.\n"
- " \n"
- "\002Note\002: because the realname mask may contain spaces, the\n"
- "separator between it and the reason is a colon."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(" \n"
- "The \002SNLINE DEL\002 command removes the given mask from the\n"
- "SNLINE list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002SNLINE LIST\002 command displays the SNLINE list.\n"
- "If 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"
- " \002SNLINE LIST 2-5,7-9\002\n"
- " Lists SNLINE entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002SNLINE VIEW\002 is a more verbose version of \002SNLINE LIST\002, and\n"
- "will show who added an SNLINE, the date it was added, and when\n"
- "it expires, as well as the realname mask and reason.\n"
- " \n"
- "\002SNLINE CLEAR\002 clears all entries of the SNLINE list."));
- return true;
- }
-};
-
-class CommandOSSQLine : public CommandOSSXLineBase
-{
- XLineManager *xlm()
- {
- return this->sqlines;
- }
-
- void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->xlm())
- return;
-
- unsigned last_param = 2;
- Anope::string expiry, mask;
-
- mask = params.size() > 1 ? params[1] : "";
- if (!mask.empty() && mask[0] == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2] : "";
- last_param = 3;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (last_param == 2 && params.size() > 3)
- reason += " " + params[3];
-
- if (mask.empty() || reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("./?*") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (this->xlm()->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!this->sqlines->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, this->xlm()));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- this->xlm()->AddXLine(x);
-
- if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes"))
- {
- Anope::string rreason = "Q-Lined: " + reason;
-
- if (mask[0] == '#')
- {
- for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
- {
- Channel *c = cit->second;
-
- if (!Anope::Match(c->name, mask, false, true))
- continue;
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (!user->HasMode("OPER") && user->server != Me)
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- c->Kick(NULL, users[i], "%s", reason.c_str());
- }
- }
- else
- {
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *user = it->second;
-
- if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
- user->Kill(Me, rreason);
- }
- }
-
- this->xlm()->Send(NULL, x);
- }
-
- source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- ServiceReference<XLineManager> sqlines;
- public:
- CommandOSSQLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/sqline"), sqlines("XLineManager", "xlinemanager/sqline")
- {
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the SQLINE list. If\n"
- "a user with a nick matching an SQLINE mask attempts to\n"
- "connect, Services will not allow it to pursue his IRC\n"
- "session.\n"
- "If the first character of the mask is #, services will\n"
- "prevent the use of matching channels. If the mask is a\n"
- "regular expression, the expression will be matched against\n"
- "channels too."));
- source.Reply(_(" \n"
- "\002SQLINE ADD\002 adds the given (nick's) mask to the SQLINE\n"
- "list for the given reason (which \002must\002 be given).\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an SQLINE which does not expire, use \037+0\037.\n"
- "If the mask to be added starts with a \037+\037, an expiry time\n"
- "must be given, even if it is the same as the default. The\n"
- "current SQLINE default expiry time can be found with the\n"
- "\002STATS AKILL\002 command."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(" \n"
- "The \002SQLINE DEL\002 command removes the given mask from the\n"
- "SQLINE list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002SQLINE LIST\002 command displays the SQLINE list.\n"
- "If 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"
- " \002SQLINE LIST 2-5,7-9\002\n"
- " Lists SQLINE entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002SQLINE VIEW\002 is a more verbose version of \002SQLINE LIST\002, and\n"
- "will show who added an SQLINE, the date it was added, and when\n"
- "it expires, as well as the mask and reason.\n"
- " \n"
- "\002SQLINE CLEAR\002 clears all entries of the SQLINE list."));
- return true;
- }
-};
-
-class OSSXLine : public Module
-{
- CommandOSSNLine commandossnline;
- CommandOSSQLine commandossqline;
-
- public:
- OSSXLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandossnline(this), commandossqline(this)
- {
- }
-};
-
-MODULE_INIT(OSSXLine)
diff --git a/modules/commands/os_update.cpp b/modules/commands/os_update.cpp
deleted file mode 100644
index 5fac1b063..000000000
--- a/modules/commands/os_update.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 CommandOSUpdate : public Command
-{
- public:
- CommandOSUpdate(Module *creator) : Command(creator, "operserv/update", 0, 0)
- {
- this->SetDesc(_("Force the Services databases to be updated immediately"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Log(LOG_ADMIN, source, this);
- source.Reply(_("Updating databases."));
- Anope::SaveDatabases();
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to update all database files as soon as you\n"
- "send the command."));
- return true;
- }
-};
-
-class OSUpdate : public Module
-{
- CommandOSUpdate commandosupdate;
-
- public:
- OSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosupdate(this)
- {
-
- }
-};
-
-MODULE_INIT(OSUpdate)
diff --git a/modules/database/CMakeLists.txt b/modules/database/CMakeLists.txt
new file mode 100644
index 000000000..9a236d6d0
--- /dev/null
+++ b/modules/database/CMakeLists.txt
@@ -0,0 +1,2 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
+build_modules_dependencies(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
deleted file mode 100644
index 171573d1c..000000000
--- a/modules/database/db_flatfile.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- *
- * (C) 2003-2016 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"
-
-#ifndef _WIN32
-#include <sys/wait.h>
-#endif
-
-class SaveData : public Serialize::Data
-{
- public:
- Anope::string last;
- std::fstream *fs;
-
- SaveData() : fs(NULL) { }
-
- std::iostream& operator[](const Anope::string &key) anope_override
- {
- if (key != last)
- {
- *fs << "\nDATA " << key << " ";
- last = key;
- }
-
- return *fs;
- }
-};
-
-class LoadData : public Serialize::Data
-{
- public:
- std::fstream *fs;
- unsigned int id;
- std::map<Anope::string, Anope::string> data;
- std::stringstream ss;
- bool read;
-
- LoadData() : fs(NULL), id(0), read(false) { }
-
- std::iostream& operator[](const Anope::string &key) anope_override
- {
- if (!read)
- {
- for (Anope::string token; std::getline(*this->fs, token.str());)
- {
- if (token.find("ID ") == 0)
- {
- try
- {
- this->id = convertTo<unsigned int>(token.substr(3));
- }
- catch (const ConvertException &) { }
-
- continue;
- }
- else if (token.find("DATA ") != 0)
- break;
-
- size_t sp = token.find(' ', 5); // Skip DATA
- if (sp != Anope::string::npos)
- data[token.substr(5, sp - 5)] = token.substr(sp + 1);
- }
-
- read = true;
- }
-
- ss.clear();
- this->ss << this->data[key];
- return this->ss;
- }
-
- std::set<Anope::string> KeySet() const anope_override
- {
- std::set<Anope::string> keys;
- for (std::map<Anope::string, Anope::string>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- keys.insert(it->first);
- return keys;
- }
-
- size_t Hash() const anope_override
- {
- size_t hash = 0;
- for (std::map<Anope::string, Anope::string>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- if (!it->second.empty())
- hash ^= Anope::hash_cs()(it->second);
- return hash;
- }
-
- void Reset()
- {
- id = 0;
- read = false;
- data.clear();
- }
-};
-
-class DBFlatFile : public Module, public Pipe
-{
- /* Day the last backup was on */
- int last_day;
- /* Backup file names */
- std::map<Anope::string, std::list<Anope::string> > backups;
- bool loaded;
-
- int child_pid;
-
- void BackupDatabase()
- {
- tm *tm = localtime(&Anope::CurTime);
-
- if (tm->tm_mday != last_day)
- {
- last_day = tm->tm_mday;
-
- const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder();
-
- std::set<Anope::string> dbs;
- dbs.insert(Config->GetModule(this)->Get<const Anope::string>("database", "anope.db"));
-
- for (unsigned i = 0; i < type_order.size(); ++i)
- {
- Serialize::Type *stype = Serialize::Type::Find(type_order[i]);
-
- if (stype && stype->GetOwner())
- dbs.insert("module_" + stype->GetOwner()->name + ".db");
- }
-
-
- for (std::set<Anope::string>::const_iterator it = dbs.begin(), it_end = dbs.end(); it != it_end; ++it)
- {
- const Anope::string &oldname = Anope::DataDir + "/" + *it;
- Anope::string newname = Anope::DataDir + "/backups/" + *it + "-" + stringify(tm->tm_year + 1900) + Anope::printf("-%02i-", tm->tm_mon + 1) + Anope::printf("%02i", tm->tm_mday);
-
- /* Backup already exists or no database to backup */
- if (Anope::IsFile(newname) || !Anope::IsFile(oldname))
- continue;
-
- Log(LOG_DEBUG) << "db_flatfile: Attempting to rename " << *it << " to " << newname;
- if (rename(oldname.c_str(), newname.c_str()))
- {
- Anope::string err = Anope::LastError();
- Log(this) << "Unable to back up database " << *it << " (" << err << ")!";
-
- if (!Config->GetModule(this)->Get<bool>("nobackupokay"))
- {
- Anope::Quitting = true;
- Anope::QuitReason = "Unable to back up database " + *it + " (" + err + ")";
- }
-
- continue;
- }
-
- backups[*it].push_back(newname);
-
- unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups");
- if (keepbackups > 0 && backups[*it].size() > keepbackups)
- {
- unlink(backups[*it].front().c_str());
- backups[*it].pop_front();
- }
- }
- }
- }
-
- public:
- DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), loaded(false), child_pid(-1)
- {
-
- }
-
-#ifndef _WIN32
- void OnRestart() anope_override
- {
- OnShutdown();
- }
-
- void OnShutdown() anope_override
- {
- if (child_pid > -1)
- {
- Log(this) << "Waiting for child to exit...";
-
- int status;
- waitpid(child_pid, &status, 0);
-
- Log(this) << "Done";
- }
- }
-#endif
-
- void OnNotify() anope_override
- {
- char buf[512];
- int i = this->Read(buf, sizeof(buf) - 1);
- if (i <= 0)
- return;
- buf[i] = 0;
-
- child_pid = -1;
-
- if (!*buf)
- {
- Log(this) << "Finished saving databases";
- return;
- }
-
- Log(this) << "Error saving databases: " << buf;
-
- if (!Config->GetModule(this)->Get<bool>("nobackupokay"))
- Anope::Quitting = true;
- }
-
- EventReturn OnLoadDatabase() anope_override
- {
- const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder();
- std::set<Anope::string> tried_dbs;
-
- const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database", "anope.db");
-
- std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
- if (!fd.is_open())
- {
- Log(this) << "Unable to open " << db_name << " for reading!";
- return EVENT_STOP;
- }
-
- std::map<Anope::string, std::vector<std::streampos> > positions;
-
- for (Anope::string buf; std::getline(fd, buf.str());)
- if (buf.find("OBJECT ") == 0)
- positions[buf.substr(7)].push_back(fd.tellg());
-
- LoadData ld;
- ld.fs = &fd;
-
- for (unsigned i = 0; i < type_order.size(); ++i)
- {
- Serialize::Type *stype = Serialize::Type::Find(type_order[i]);
- if (!stype || stype->GetOwner())
- continue;
-
- std::vector<std::streampos> &pos = positions[stype->GetName()];
-
- for (unsigned j = 0; j < pos.size(); ++j)
- {
- fd.clear();
- fd.seekg(pos[j]);
-
- Serializable *obj = stype->Unserialize(NULL, ld);
- if (obj != NULL)
- obj->id = ld.id;
- ld.Reset();
- }
- }
-
- fd.close();
-
- loaded = true;
- return EVENT_STOP;
- }
-
-
- void OnSaveDatabase() anope_override
- {
- if (child_pid > -1)
- {
- Log(this) << "Database save is already in progress!";
- return;
- }
-
- BackupDatabase();
-
- int i = -1;
-#ifndef _WIN32
- if (!Anope::Quitting && Config->GetModule(this)->Get<bool>("fork"))
- {
- i = fork();
- if (i > 0)
- {
- child_pid = i;
- return;
- }
- else if (i < 0)
- Log(this) << "Unable to fork for database save";
- }
-#endif
-
- try
- {
- std::map<Module *, std::fstream *> databases;
-
- /* First open the databases of all of the registered types. This way, if we have a type with 0 objects, that database will be properly cleared */
- for (std::map<Anope::string, Serialize::Type *>::const_iterator it = Serialize::Type::GetTypes().begin(), it_end = Serialize::Type::GetTypes().end(); it != it_end; ++it)
- {
- Serialize::Type *s_type = it->second;
-
- if (databases[s_type->GetOwner()])
- continue;
-
- Anope::string db_name;
- if (s_type->GetOwner())
- db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db";
- else
- db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database", "anope.db");
-
- if (Anope::IsFile(db_name))
- rename(db_name.c_str(), (db_name + ".tmp").c_str());
-
- std::fstream *fs = databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
-
- if (!fs->is_open())
- Log(this) << "Unable to open " << db_name << " for writing";
- }
-
- SaveData data;
- const std::list<Serializable *> &items = Serializable::GetItems();
- for (std::list<Serializable *>::const_iterator it = items.begin(), it_end = items.end(); it != it_end; ++it)
- {
- Serializable *base = *it;
- Serialize::Type *s_type = base->GetSerializableType();
-
- data.fs = databases[s_type->GetOwner()];
- if (!data.fs || !data.fs->is_open())
- continue;
-
- *data.fs << "OBJECT " << s_type->GetName();
- if (base->id)
- *data.fs << "\nID " << base->id;
- base->Serialize(data);
- *data.fs << "\nEND\n";
- }
-
- for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it)
- {
- std::fstream *f = it->second;
- const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : Config->GetModule(this)->Get<const Anope::string>("database", "anope.db"));
-
- if (!f->is_open() || !f->good())
- {
- this->Write("Unable to write database " + db_name);
-
- f->close();
-
- if (Anope::IsFile((db_name + ".tmp").c_str()))
- rename((db_name + ".tmp").c_str(), db_name.c_str());
- }
- else
- {
- f->close();
- unlink((db_name + ".tmp").c_str());
- }
-
- delete f;
- }
- }
- catch (...)
- {
- if (i)
- throw;
- }
-
- if (!i)
- {
- this->Notify();
- exit(0);
- }
- }
-
- /* Load just one type. Done if a module is reloaded during runtime */
- void OnSerializeTypeCreate(Serialize::Type *stype) anope_override
- {
- if (!loaded)
- return;
-
- Anope::string db_name;
- if (stype->GetOwner())
- db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db";
- else
- db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database", "anope.db");
-
- std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
- if (!fd.is_open())
- {
- Log(this) << "Unable to open " << db_name << " for reading!";
- return;
- }
-
- LoadData ld;
- ld.fs = &fd;
-
- for (Anope::string buf; std::getline(fd, buf.str());)
- {
- if (buf == "OBJECT " + stype->GetName())
- {
- stype->Unserialize(NULL, ld);
- ld.Reset();
- }
- }
-
- fd.close();
- }
-};
-
-MODULE_INIT(DBFlatFile)
-
-
diff --git a/modules/database/db_redis.cpp b/modules/database/db_redis.cpp
deleted file mode 100644
index db12a2c5f..000000000
--- a/modules/database/db_redis.cpp
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/redis.h"
-
-using namespace Redis;
-
-class DatabaseRedis;
-static DatabaseRedis *me;
-
-class Data : public Serialize::Data
-{
- public:
- std::map<Anope::string, std::stringstream *> data;
-
- ~Data()
- {
- for (std::map<Anope::string, std::stringstream *>::iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- delete it->second;
- }
-
- std::iostream& operator[](const Anope::string &key) anope_override
- {
- std::stringstream* &stream = data[key];
- if (!stream)
- stream = new std::stringstream();
- return *stream;
- }
-
- std::set<Anope::string> KeySet() const anope_override
- {
- std::set<Anope::string> keys;
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- keys.insert(it->first);
- return keys;
- }
-
- size_t Hash() const anope_override
- {
- size_t hash = 0;
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- if (!it->second->str().empty())
- hash ^= Anope::hash_cs()(it->second->str());
- return hash;
- }
-};
-
-class TypeLoader : public Interface
-{
- Anope::string type;
- public:
- TypeLoader(Module *creator, const Anope::string &t) : Interface(creator), type(t) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class ObjectLoader : public Interface
-{
- Anope::string type;
- int64_t id;
-
- public:
- ObjectLoader(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class IDInterface : public Interface
-{
- Reference<Serializable> o;
- public:
- IDInterface(Module *creator, Serializable *obj) : Interface(creator), o(obj) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class Deleter : public Interface
-{
- Anope::string type;
- int64_t id;
- public:
- Deleter(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class Updater : public Interface
-{
- Anope::string type;
- int64_t id;
- public:
- Updater(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class ModifiedObject : public Interface
-{
- Anope::string type;
- int64_t id;
- public:
- ModifiedObject(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class SubscriptionListener : public Interface
-{
- public:
- SubscriptionListener(Module *creator) : Interface(creator) { }
-
- void OnResult(const Reply &r) anope_override;
-};
-
-class DatabaseRedis : public Module, public Pipe
-{
- SubscriptionListener sl;
- std::set<Serializable *> updated_items;
-
- public:
- ServiceReference<Provider> redis;
-
- DatabaseRedis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), sl(this)
- {
- me = this;
-
- }
-
- /* Insert or update an object */
- void InsertObject(Serializable *obj)
- {
- Serialize::Type *t = obj->GetSerializableType();
-
- /* If there is no id yet for this object, get one */
- if (!obj->id)
- redis->SendCommand(new IDInterface(this, obj), "INCR id:" + t->GetName());
- else
- {
- Data data;
- obj->Serialize(data);
-
- if (obj->IsCached(data))
- return;
-
- obj->UpdateCache(data);
-
- std::vector<Anope::string> args;
- args.push_back("HGETALL");
- args.push_back("hash:" + t->GetName() + ":" + stringify(obj->id));
-
- /* Get object attrs to clear before updating */
- redis->SendCommand(new Updater(this, t->GetName(), obj->id), args);
- }
- }
-
- void OnNotify() anope_override
- {
- for (std::set<Serializable *>::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it)
- {
- Serializable *s = *it;
-
- this->InsertObject(s);
- }
-
- this->updated_items.clear();
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->redis = ServiceReference<Provider>("Redis::Provider", block->Get<const Anope::string>("engine", "redis/main"));
- }
-
- EventReturn OnLoadDatabase() anope_override
- {
- const std::vector<Anope::string> type_order = Serialize::Type::GetTypeOrder();
- for (unsigned i = 0; i < type_order.size(); ++i)
- {
- Serialize::Type *sb = Serialize::Type::Find(type_order[i]);
- this->OnSerializeTypeCreate(sb);
- }
-
- while (redis->BlockAndProcess());
-
- redis->Subscribe(&this->sl, "__keyspace@*__:hash:*");
-
- return EVENT_STOP;
- }
-
- void OnSerializeTypeCreate(Serialize::Type *sb) anope_override
- {
- if (!redis)
- return;
-
- std::vector<Anope::string> args;
- args.push_back("SMEMBERS");
- args.push_back("ids:" + sb->GetName());
-
- redis->SendCommand(new TypeLoader(this, sb->GetName()), args);
- }
-
- void OnSerializableConstruct(Serializable *obj) anope_override
- {
- this->updated_items.insert(obj);
- this->Notify();
- }
-
- void OnSerializableDestruct(Serializable *obj) anope_override
- {
- Serialize::Type *t = obj->GetSerializableType();
-
- std::vector<Anope::string> args;
- args.push_back("HGETALL");
- args.push_back("hash:" + t->GetName() + ":" + stringify(obj->id));
-
- /* Get all of the attributes for this object */
- redis->SendCommand(new Deleter(this, t->GetName(), obj->id), args);
-
- this->updated_items.erase(obj);
- t->objects.erase(obj->id);
- this->Notify();
- }
-
- void OnSerializableUpdate(Serializable *obj) anope_override
- {
- this->updated_items.insert(obj);
- this->Notify();
- }
-};
-
-void TypeLoader::OnResult(const Reply &r)
-{
- if (r.type != Reply::MULTI_BULK || !me->redis)
- {
- delete this;
- return;
- }
-
- for (unsigned i = 0; i < r.multi_bulk.size(); ++i)
- {
- const Reply *reply = r.multi_bulk[i];
-
- if (reply->type != Reply::BULK)
- continue;
-
- int64_t id;
- try
- {
- id = convertTo<int64_t>(reply->bulk);
- }
- catch (const ConvertException &)
- {
- continue;
- }
-
- std::vector<Anope::string> args;
- args.push_back("HGETALL");
- args.push_back("hash:" + this->type + ":" + stringify(id));
-
- me->redis->SendCommand(new ObjectLoader(me, this->type, id), args);
- }
-
- delete this;
-}
-
-void ObjectLoader::OnResult(const Reply &r)
-{
- Serialize::Type *st = Serialize::Type::Find(this->type);
-
- if (r.type != Reply::MULTI_BULK || r.multi_bulk.empty() || !me->redis || !st)
- {
- delete this;
- return;
- }
-
- Data data;
-
- for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
- {
- const Reply *key = r.multi_bulk[i],
- *value = r.multi_bulk[i + 1];
-
- data[key->bulk] << value->bulk;
- }
-
- Serializable* &obj = st->objects[this->id];
- obj = st->Unserialize(obj, data);
- if (obj)
- {
- obj->id = this->id;
- obj->UpdateCache(data);
- }
-
- delete this;
-}
-
-void IDInterface::OnResult(const Reply &r)
-{
- if (!o || r.type != Reply::INT || !r.i)
- {
- delete this;
- return;
- }
-
- Serializable* &obj = o->GetSerializableType()->objects[r.i];
- if (obj)
- /* This shouldn't be possible */
- obj->id = 0;
-
- o->id = r.i;
- obj = o;
-
- /* Now that we have the id, insert this object for real */
- anope_dynamic_static_cast<DatabaseRedis *>(this->owner)->InsertObject(o);
-
- delete this;
-}
-
-void Deleter::OnResult(const Reply &r)
-{
- if (r.type != Reply::MULTI_BULK || !me->redis || r.multi_bulk.empty())
- {
- delete this;
- return;
- }
-
- /* Transaction start */
- me->redis->StartTransaction();
-
- std::vector<Anope::string> args;
- args.push_back("DEL");
- args.push_back("hash:" + this->type + ":" + stringify(this->id));
-
- /* Delete hash object */
- me->redis->SendCommand(NULL, args);
-
- args.clear();
- args.push_back("SREM");
- args.push_back("ids:" + this->type);
- args.push_back(stringify(this->id));
-
- /* Delete id from ids set */
- me->redis->SendCommand(NULL, args);
-
- for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
- {
- const Reply *key = r.multi_bulk[i],
- *value = r.multi_bulk[i + 1];
-
- args.clear();
- args.push_back("SREM");
- args.push_back("value:" + this->type + ":" + key->bulk + ":" + value->bulk);
- args.push_back(stringify(this->id));
-
- /* Delete value -> object id */
- me->redis->SendCommand(NULL, args);
- }
-
- /* Transaction end */
- me->redis->CommitTransaction();
-
- delete this;
-}
-
-void Updater::OnResult(const Reply &r)
-{
- Serialize::Type *st = Serialize::Type::Find(this->type);
-
- if (!st)
- {
- delete this;
- return;
- }
-
- Serializable *obj = st->objects[this->id];
- if (!obj)
- {
- delete this;
- return;
- }
-
- Data data;
- obj->Serialize(data);
-
- /* Transaction start */
- me->redis->StartTransaction();
-
- for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
- {
- const Reply *key = r.multi_bulk[i],
- *value = r.multi_bulk[i + 1];
-
- std::vector<Anope::string> args;
- args.push_back("SREM");
- args.push_back("value:" + this->type + ":" + key->bulk + ":" + value->bulk);
- args.push_back(stringify(this->id));
-
- /* Delete value -> object id */
- me->redis->SendCommand(NULL, args);
- }
-
- /* Add object id to id set for this type */
- std::vector<Anope::string> args;
- args.push_back("SADD");
- args.push_back("ids:" + this->type);
- args.push_back(stringify(obj->id));
- me->redis->SendCommand(NULL, args);
-
- args.clear();
- args.push_back("HMSET");
- args.push_back("hash:" + this->type + ":" + stringify(obj->id));
-
- typedef std::map<Anope::string, std::stringstream *> items;
- for (items::iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- const Anope::string &key = it->first;
- std::stringstream *value = it->second;
-
- args.push_back(key);
- args.push_back(value->str());
-
- std::vector<Anope::string> args2;
-
- args2.push_back("SADD");
- args2.push_back("value:" + this->type + ":" + key + ":" + value->str());
- args2.push_back(stringify(obj->id));
-
- /* Add to value -> object id set */
- me->redis->SendCommand(NULL, args2);
- }
-
- ++obj->redis_ignore;
-
- /* Add object */
- me->redis->SendCommand(NULL, args);
-
- /* Transaction end */
- me->redis->CommitTransaction();
-
- delete this;
-}
-
-void SubscriptionListener::OnResult(const Reply &r)
-{
- /*
- * [May 15 13:59:35.645839 2013] Debug: pmessage
- * [May 15 13:59:35.645866 2013] Debug: __keyspace@*__:anope:hash:*
- * [May 15 13:59:35.645880 2013] Debug: __keyspace@0__:anope:hash:type:id
- * [May 15 13:59:35.645893 2013] Debug: hset
- */
- if (r.multi_bulk.size() != 4)
- return;
-
- size_t sz = r.multi_bulk[2]->bulk.find(':');
- if (sz == Anope::string::npos)
- return;
-
- const Anope::string &key = r.multi_bulk[2]->bulk.substr(sz + 1),
- &op = r.multi_bulk[3]->bulk;
-
- sz = key.rfind(':');
- if (sz == Anope::string::npos)
- return;
-
- const Anope::string &id = key.substr(sz + 1);
-
- size_t sz2 = key.rfind(':', sz - 1);
- if (sz2 == Anope::string::npos)
- return;
- const Anope::string &type = key.substr(sz2 + 1, sz - sz2 - 1);
-
- Serialize::Type *s_type = Serialize::Type::Find(type);
-
- if (s_type == NULL)
- return;
-
- uint64_t obj_id;
- try
- {
- obj_id = convertTo<uint64_t>(id);
- }
- catch (const ConvertException &)
- {
- return;
- }
-
- if (op == "hset" || op == "hdel")
- {
- Serializable *s = s_type->objects[obj_id];
-
- if (s && s->redis_ignore)
- {
- --s->redis_ignore;
- Log(LOG_DEBUG) << "redis: notify: got modify for object id " << obj_id << " of type " << type << ", but I am ignoring it";
- }
- else
- {
- Log(LOG_DEBUG) << "redis: notify: got modify for object id " << obj_id << " of type " << type;
-
- std::vector<Anope::string> args;
- args.push_back("HGETALL");
- args.push_back("hash:" + type + ":" + id);
-
- me->redis->SendCommand(new ModifiedObject(me, type, obj_id), args);
- }
- }
- else if (op == "del")
- {
- Serializable* &s = s_type->objects[obj_id];
- if (s == NULL)
- return;
-
- Log(LOG_DEBUG) << "redis: notify: deleting object id " << obj_id << " of type " << type;
-
- Data data;
-
- s->Serialize(data);
-
- /* Transaction start */
- me->redis->StartTransaction();
-
- typedef std::map<Anope::string, std::stringstream *> items;
- for (items::iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- const Anope::string &k = it->first;
- std::stringstream *value = it->second;
-
- std::vector<Anope::string> args;
- args.push_back("SREM");
- args.push_back("value:" + type + ":" + k + ":" + value->str());
- args.push_back(id);
-
- /* Delete value -> object id */
- me->redis->SendCommand(NULL, args);
- }
-
- std::vector<Anope::string> args;
- args.push_back("SREM");
- args.push_back("ids:" + type);
- args.push_back(stringify(s->id));
-
- /* Delete object from id set */
- me->redis->SendCommand(NULL, args);
-
- /* Transaction end */
- me->redis->CommitTransaction();
-
- delete s;
- s = NULL;
- }
-}
-
-void ModifiedObject::OnResult(const Reply &r)
-{
- Serialize::Type *st = Serialize::Type::Find(this->type);
-
- if (!st)
- {
- delete this;
- return;
- }
-
- Serializable* &obj = st->objects[this->id];
-
- /* Transaction start */
- me->redis->StartTransaction();
-
- /* Erase old object values */
- if (obj)
- {
- Data data;
-
- obj->Serialize(data);
-
- typedef std::map<Anope::string, std::stringstream *> items;
- for (items::iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- const Anope::string &key = it->first;
- std::stringstream *value = it->second;
-
- std::vector<Anope::string> args;
- args.push_back("SREM");
- args.push_back("value:" + st->GetName() + ":" + key + ":" + value->str());
- args.push_back(stringify(this->id));
-
- /* Delete value -> object id */
- me->redis->SendCommand(NULL, args);
- }
- }
-
- Data data;
-
- for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
- {
- const Reply *key = r.multi_bulk[i],
- *value = r.multi_bulk[i + 1];
-
- data[key->bulk] << value->bulk;
- }
-
- obj = st->Unserialize(obj, data);
- if (obj)
- {
- obj->id = this->id;
- obj->UpdateCache(data);
-
- /* Insert new object values */
- typedef std::map<Anope::string, std::stringstream *> items;
- for (items::iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- const Anope::string &key = it->first;
- std::stringstream *value = it->second;
-
- std::vector<Anope::string> args;
- args.push_back("SADD");
- args.push_back("value:" + st->GetName() + ":" + key + ":" + value->str());
- args.push_back(stringify(obj->id));
-
- /* Add to value -> object id set */
- me->redis->SendCommand(NULL, args);
- }
-
- std::vector<Anope::string> args;
- args.push_back("SADD");
- args.push_back("ids:" + st->GetName());
- args.push_back(stringify(obj->id));
-
- /* Add to type -> id set */
- me->redis->SendCommand(NULL, args);
- }
-
- /* Transaction end */
- me->redis->CommitTransaction();
-
- delete this;
-}
-
-MODULE_INIT(DatabaseRedis)
diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp
deleted file mode 100644
index 15501bc5f..000000000
--- a/modules/database/db_sql.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- *
- * (C) 2003-2016 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/sql.h"
-
-using namespace SQL;
-
-class SQLSQLInterface : public Interface
-{
- public:
- SQLSQLInterface(Module *o) : Interface(o) { }
-
- void OnResult(const Result &r) anope_override
- {
- Log(LOG_DEBUG) << "SQL successfully executed query: " << r.finished_query;
- }
-
- void OnError(const Result &r) anope_override
- {
- if (!r.GetQuery().query.empty())
- Log(LOG_DEBUG) << "Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "Error executing query: " << r.GetError();
- }
-};
-
-class ResultSQLSQLInterface : public SQLSQLInterface
-{
- Reference<Serializable> obj;
-
-public:
- ResultSQLSQLInterface(Module *o, Serializable *ob) : SQLSQLInterface(o), obj(ob) { }
-
- void OnResult(const Result &r) anope_override
- {
- SQLSQLInterface::OnResult(r);
- if (r.GetID() > 0 && this->obj)
- this->obj->id = r.GetID();
- delete this;
- }
-
- void OnError(const Result &r) anope_override
- {
- SQLSQLInterface::OnError(r);
- delete this;
- }
-};
-
-class DBSQL : public Module, public Pipe
-{
- ServiceReference<Provider> sql;
- SQLSQLInterface sqlinterface;
- Anope::string prefix;
- bool import;
-
- std::set<Serializable *> updated_items;
- bool shutting_down;
- bool loading_databases;
- bool loaded;
- bool imported;
-
- void RunBackground(const Query &q, Interface *iface = NULL)
- {
- if (!this->sql)
- {
- static time_t last_warn = 0;
- if (last_warn + 300 < Anope::CurTime)
- {
- last_warn = Anope::CurTime;
- Log(this) << "db_sql: Unable to execute query, is SQL configured correctly?";
- }
- }
- else if (!Anope::Quitting)
- {
- if (iface == NULL)
- iface = &this->sqlinterface;
- this->sql->Run(iface, q);
- }
- else
- this->sql->RunQuery(q);
- }
-
- public:
- DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false), loaded(false), imported(false)
- {
-
-
- if (ModuleManager::FindModule("db_sql_live") != NULL)
- throw ModuleException("db_sql can not be loaded after db_sql_live");
- }
-
- void OnNotify() anope_override
- {
- for (std::set<Serializable *>::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it)
- {
- Serializable *obj = *it;
-
- if (this->sql)
- {
- Data data;
- obj->Serialize(data);
-
- if (obj->IsCached(data))
- continue;
-
- obj->UpdateCache(data);
-
- /* If we didn't load these objects and we don't want to import just update the cache and continue */
- if (!this->loaded && !this->imported && !this->import)
- continue;
-
- Serialize::Type *s_type = obj->GetSerializableType();
- if (!s_type)
- continue;
-
- std::vector<Query> create = this->sql->CreateTable(this->prefix + s_type->GetName(), data);
- for (unsigned i = 0; i < create.size(); ++i)
- this->RunBackground(create[i]);
-
- Query insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, data);
- if (this->imported)
- this->RunBackground(insert, new ResultSQLSQLInterface(this, obj));
- else
- {
- /* We are importing objects from another database module, so don't do asynchronous
- * queries in case the core has to shut down, it will cut short the import
- */
- Result r = this->sql->RunQuery(insert);
- if (r.GetID() > 0)
- obj->id = r.GetID();
- }
- }
- }
-
- this->updated_items.clear();
- this->imported = true;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->sql = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string>("engine"));
- this->prefix = block->Get<const Anope::string>("prefix", "anope_db_");
- this->import = block->Get<bool>("import");
- }
-
- void OnShutdown() anope_override
- {
- this->shutting_down = true;
- this->OnNotify();
- }
-
- void OnRestart() anope_override
- {
- this->OnShutdown();
- }
-
- EventReturn OnLoadDatabase() anope_override
- {
- if (!this->sql)
- {
- Log(this) << "Unable to load databases, is SQL configured correctly?";
- return EVENT_CONTINUE;
- }
-
- this->loading_databases = true;
-
- const std::vector<Anope::string> type_order = Serialize::Type::GetTypeOrder();
- for (unsigned i = 0; i < type_order.size(); ++i)
- {
- Serialize::Type *sb = Serialize::Type::Find(type_order[i]);
- this->OnSerializeTypeCreate(sb);
- }
-
- this->loading_databases = false;
- this->loaded = true;
-
- return EVENT_STOP;
- }
-
- void OnSerializableConstruct(Serializable *obj) anope_override
- {
- if (this->shutting_down || this->loading_databases)
- return;
- obj->UpdateTS();
- this->updated_items.insert(obj);
- this->Notify();
- }
-
- void OnSerializableDestruct(Serializable *obj) anope_override
- {
- if (this->shutting_down)
- return;
- Serialize::Type *s_type = obj->GetSerializableType();
- if (s_type && obj->id > 0)
- this->RunBackground("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id));
- this->updated_items.erase(obj);
- }
-
- void OnSerializableUpdate(Serializable *obj) anope_override
- {
- if (this->shutting_down || obj->IsTSCached())
- return;
- obj->UpdateTS();
- this->updated_items.insert(obj);
- this->Notify();
- }
-
- void OnSerializeTypeCreate(Serialize::Type *sb) anope_override
- {
- if (!this->loading_databases && !this->loaded)
- return;
-
- Query query("SELECT * FROM `" + this->prefix + sb->GetName() + "`");
- Result res = this->sql->RunQuery(query);
-
- for (int j = 0; j < res.Rows(); ++j)
- {
- Data data;
-
- const std::map<Anope::string, Anope::string> &row = res.Row(j);
- for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
- data[rit->first] << rit->second;
-
- Serializable *obj = sb->Unserialize(NULL, data);
- try
- {
- if (obj)
- obj->id = convertTo<unsigned int>(res.Get(j, "id"));
- }
- catch (const ConvertException &)
- {
- Log(this) << "Unable to convert id for object #" << j << " of type " << sb->GetName();
- }
-
- if (obj)
- {
- /* The Unserialize operation is destructive so rebuild the data for UpdateCache.
- * Also the old data may contain columns that we don't use, so we reserialize the
- * object to know for sure our cache is consistent
- */
-
- Data data2;
- obj->Serialize(data2);
- obj->UpdateCache(data2); /* We know this is the most up to date copy */
- }
- }
- }
-};
-
-MODULE_INIT(DBSQL)
-
diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp
deleted file mode 100644
index 7dfde3d02..000000000
--- a/modules/database/db_sql_live.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- *
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/sql.h"
-
-using namespace SQL;
-
-class DBMySQL : public Module, public Pipe
-{
- private:
- Anope::string prefix;
- ServiceReference<Provider> SQL;
- time_t lastwarn;
- bool ro;
- bool init;
- std::set<Serializable *> updated_items;
-
- bool CheckSQL()
- {
- if (SQL)
- {
- if (Anope::ReadOnly && this->ro)
- {
- Anope::ReadOnly = this->ro = false;
- Log() << "Found SQL again, going out of readonly mode...";
- }
-
- return true;
- }
- else
- {
- if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout", "5m") > lastwarn)
- {
- Log() << "Unable to locate SQL reference, going to readonly...";
- Anope::ReadOnly = this->ro = true;
- this->lastwarn = Anope::CurTime;
- }
-
- return false;
- }
- }
-
- bool CheckInit()
- {
- return init && SQL;
- }
-
- void RunQuery(const Query &query)
- {
- /* Can this be threaded? */
- this->RunQueryResult(query);
- }
-
- Result RunQueryResult(const Query &query)
- {
- if (this->CheckSQL())
- {
- Result res = SQL->RunQuery(query);
- if (!res.GetError().empty())
- Log(LOG_DEBUG) << "SQL-live got error " << res.GetError() << " for " + res.finished_query;
- else
- Log(LOG_DEBUG) << "SQL-live got " << res.Rows() << " rows for " << res.finished_query;
- return res;
- }
- throw SQL::Exception("No SQL!");
- }
-
- public:
- DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), SQL("", "")
- {
- this->lastwarn = 0;
- this->ro = false;
- this->init = false;
-
-
- if (ModuleManager::FindFirstOf(DATABASE) != this)
- throw ModuleException("If db_sql_live is loaded it must be the first database module loaded.");
- }
-
- void OnNotify() anope_override
- {
- if (!this->CheckInit())
- return;
-
- for (std::set<Serializable *>::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it)
- {
- Serializable *obj = *it;
-
- if (obj && this->SQL)
- {
- Data data;
- obj->Serialize(data);
-
- if (obj->IsCached(data))
- continue;
-
- obj->UpdateCache(data);
-
- Serialize::Type *s_type = obj->GetSerializableType();
- if (!s_type)
- continue;
-
- std::vector<Query> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), data);
- for (unsigned i = 0; i < create.size(); ++i)
- this->RunQueryResult(create[i]);
-
- Result res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, data));
- if (res.GetID() && obj->id != res.GetID())
- {
- /* In this case obj is new, so place it into the object map */
- obj->id = res.GetID();
- s_type->objects[obj->id] = obj;
- }
- }
- }
-
- this->updated_items.clear();
- }
-
- EventReturn OnLoadDatabase() anope_override
- {
- init = true;
- return EVENT_STOP;
- }
-
- void OnShutdown() anope_override
- {
- init = false;
- }
-
- void OnRestart() anope_override
- {
- init = false;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->SQL = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string>("engine"));
- this->prefix = block->Get<const Anope::string>("prefix", "anope_db_");
- }
-
- void OnSerializableConstruct(Serializable *obj) anope_override
- {
- if (!this->CheckInit())
- return;
- obj->UpdateTS();
- this->updated_items.insert(obj);
- this->Notify();
- }
-
- void OnSerializableDestruct(Serializable *obj) anope_override
- {
- if (!this->CheckInit())
- return;
- Serialize::Type *s_type = obj->GetSerializableType();
- if (s_type)
- {
- if (obj->id > 0)
- this->RunQuery("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id));
- s_type->objects.erase(obj->id);
- }
- this->updated_items.erase(obj);
- }
-
- void OnSerializeCheck(Serialize::Type *obj) anope_override
- {
- if (!this->CheckInit() || obj->GetTimestamp() == Anope::CurTime)
- return;
-
- Query query("SELECT * FROM `" + this->prefix + obj->GetName() + "` WHERE (`timestamp` >= " + this->SQL->FromUnixtime(obj->GetTimestamp()) + " OR `timestamp` IS NULL)");
-
- obj->UpdateTimestamp();
-
- Result res = this->RunQueryResult(query);
-
- bool clear_null = false;
- for (int i = 0; i < res.Rows(); ++i)
- {
- const std::map<Anope::string, Anope::string> &row = res.Row(i);
-
- unsigned int id;
- try
- {
- id = convertTo<unsigned int>(res.Get(i, "id"));
- }
- catch (const ConvertException &)
- {
- Log(LOG_DEBUG) << "Unable to convert id from " << obj->GetName();
- continue;
- }
-
- if (res.Get(i, "timestamp").empty())
- {
- clear_null = true;
- std::map<uint64_t, Serializable *>::iterator it = obj->objects.find(id);
- if (it != obj->objects.end())
- delete it->second; // This also removes this object from the map
- }
- else
- {
- Data data;
-
- for (std::map<Anope::string, Anope::string>::const_iterator it = row.begin(), it_end = row.end(); it != it_end; ++it)
- data[it->first] << it->second;
-
- Serializable *s = NULL;
- std::map<uint64_t, Serializable *>::iterator it = obj->objects.find(id);
- if (it != obj->objects.end())
- s = it->second;
-
- Serializable *new_s = obj->Unserialize(s, data);
- if (new_s)
- {
- // If s == new_s then s->id == new_s->id
- if (s != new_s)
- {
- new_s->id = id;
- obj->objects[id] = new_s;
-
- /* The Unserialize operation is destructive so rebuild the data for UpdateCache.
- * Also the old data may contain columns that we don't use, so we reserialize the
- * object to know for sure our cache is consistent
- */
-
- Data data2;
- new_s->Serialize(data2);
- new_s->UpdateCache(data2); /* We know this is the most up to date copy */
- }
- }
- else
- {
- if (!s)
- this->RunQuery("UPDATE `" + prefix + obj->GetName() + "` SET `timestamp` = " + this->SQL->FromUnixtime(obj->GetTimestamp()) + " WHERE `id` = " + stringify(id));
- else
- delete s;
- }
- }
- }
-
- if (clear_null)
- {
- query = "DELETE FROM `" + this->prefix + obj->GetName() + "` WHERE `timestamp` IS NULL";
- this->RunQuery(query);
- }
- }
-
- void OnSerializableUpdate(Serializable *obj) anope_override
- {
- if (!this->CheckInit() || obj->IsTSCached())
- return;
- obj->UpdateTS();
- this->updated_items.insert(obj);
- this->Notify();
- }
-};
-
-MODULE_INIT(DBMySQL)
-
diff --git a/modules/database/flatfile.cpp b/modules/database/flatfile.cpp
new file mode 100644
index 000000000..b45a89d44
--- /dev/null
+++ b/modules/database/flatfile.cpp
@@ -0,0 +1,218 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class DBFlatFile : public Module
+ , public EventHook<Event::LoadDatabase>
+ , public EventHook<Event::SaveDatabase>
+{
+ /* Day the last backup was on */
+ int last_day;
+ /* Backup file names */
+ std::map<Anope::string, std::list<Anope::string> > backups;
+ bool loaded;
+
+ void BackupDatabase()
+ {
+ tm *tm = localtime(&Anope::CurTime);
+
+ if (tm->tm_mday != last_day)
+ {
+ last_day = tm->tm_mday;
+
+ const std::map<Anope::string, Serialize::TypeBase *> &types = Serialize::TypeBase::GetTypes();
+
+ std::set<Anope::string> dbs;
+ dbs.insert(Config->GetModule(this)->Get<Anope::string>("database", "anope.db"));
+
+ for (const std::pair<Anope::string, Serialize::TypeBase *> &p : types)
+ {
+ Serialize::TypeBase *stype = p.second;
+
+ if (stype->GetOwner())
+ dbs.insert("module_" + stype->GetOwner()->name + ".db");
+ }
+
+
+ for (std::set<Anope::string>::const_iterator it = dbs.begin(), it_end = dbs.end(); it != it_end; ++it)
+ {
+ const Anope::string &oldname = Anope::DataDir + "/" + *it;
+ Anope::string newname = Anope::DataDir + "/backups/" + *it + "-" + stringify(tm->tm_year + 1900) + Anope::printf("-%02i-", tm->tm_mon + 1) + Anope::printf("%02i", tm->tm_mday);
+
+ /* Backup already exists or no database to backup */
+ if (Anope::IsFile(newname) || !Anope::IsFile(oldname))
+ continue;
+
+ Log(LOG_DEBUG) << "db_flatfile: Attempting to rename " << *it << " to " << newname;
+ if (rename(oldname.c_str(), newname.c_str()))
+ {
+ Anope::string err = Anope::LastError();
+ Log(this) << "Unable to back up database " << *it << " (" << err << ")!";
+
+ if (!Config->GetModule(this)->Get<bool>("nobackupokay"))
+ {
+ Anope::Quitting = true;
+ Anope::QuitReason = "Unable to back up database " + *it + " (" + err + ")";
+ }
+
+ continue;
+ }
+
+ backups[*it].push_back(newname);
+
+ unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups");
+ if (keepbackups > 0 && backups[*it].size() > keepbackups)
+ {
+ unlink(backups[*it].front().c_str());
+ backups[*it].pop_front();
+ }
+ }
+ }
+ }
+
+ public:
+ DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
+ , EventHook<Event::LoadDatabase>(this)
+ , EventHook<Event::SaveDatabase>(this)
+ , last_day(0)
+ , loaded(false)
+ {
+
+ }
+
+ EventReturn OnLoadDatabase() override
+ {
+ const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<Anope::string>("database", "anope.db");
+
+ std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
+ if (!fd.is_open())
+ {
+ Log(this) << "Unable to open " << db_name << " for reading!";
+ return EVENT_STOP;
+ }
+
+ Serialize::TypeBase *type = nullptr;
+ Serialize::Object *obj = nullptr;
+ for (Anope::string buf; std::getline(fd, buf.str());)
+ {
+ if (buf.find("OBJECT ") == 0)
+ {
+ Anope::string t = buf.substr(7);
+ if (obj)
+ Log(LOG_DEBUG) << "obj != null but got OBJECT";
+ if (type)
+ Log(LOG_DEBUG) << "type != null but got OBJECT";
+ type = Serialize::TypeBase::Find(t);
+ obj = nullptr;
+ }
+ else if (buf.find("ID ") == 0)
+ {
+ if (!type || obj)
+ continue;
+
+ try
+ {
+ Serialize::ID id = convertTo<Serialize::ID>(buf.substr(3));
+ obj = type->Require(id);
+ }
+ catch (const ConvertException &)
+ {
+ Log(LOG_DEBUG) << "Unable to parse object id " << buf.substr(3);
+ }
+ }
+ else if (buf.find("DATA ") == 0)
+ {
+ if (!type)
+ continue;
+
+ if (!obj)
+ obj = type->Create();
+
+ size_t sp = buf.find(' ', 5); // Skip DATA
+ if (sp == Anope::string::npos)
+ continue;
+
+ Anope::string key = buf.substr(5, sp - 5), value = buf.substr(sp + 1);
+
+ Serialize::FieldBase *field = type->GetField(key);
+ if (field)
+ field->UnserializeFromString(obj, value);
+ }
+ else if (buf.find("END") == 0)
+ {
+ type = nullptr;
+ obj = nullptr;
+ }
+ }
+
+ fd.close();
+
+ loaded = true;
+ return EVENT_STOP;
+ }
+
+
+ void OnSaveDatabase() override
+ {
+ BackupDatabase();
+
+ Anope::string db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<Anope::string>("database", "anope.db");
+
+ if (Anope::IsFile(db_name))
+ rename(db_name.c_str(), (db_name + ".tmp").c_str());
+
+ std::fstream f(db_name.c_str(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
+
+ if (!f.is_open())
+ {
+ Log(this) << "Unable to open " << db_name << " for writing";
+ }
+ else
+ {
+ for (std::pair<Serialize::ID, Serialize::Object *> p : Serialize::objects)
+ {
+ Serialize::Object *object = p.second;
+ Serialize::TypeBase *s_type = object->GetSerializableType();
+
+ f << "OBJECT " << s_type->GetName() << "\n";
+ f << "ID " << object->id << "\n";
+ for (Serialize::FieldBase *field : s_type->GetFields())
+ if (field->HasFieldS(object)) // for ext
+ f << "DATA " << field->serialize_name << " " << field->SerializeToString(object) << "\n";
+ f << "END\n";
+ }
+ }
+
+ if (!f.is_open() || !f.good())
+ {
+ f.close();
+ rename((db_name + ".tmp").c_str(), db_name.c_str());
+ }
+ else
+ {
+ f.close();
+ unlink((db_name + ".tmp").c_str());
+ }
+ }
+};
+
+MODULE_INIT(DBFlatFile)
+
+
diff --git a/modules/database/db_old.cpp b/modules/database/old.cpp
index 00524fdc3..640b45973 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/old.cpp
@@ -1,23 +1,36 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+/* Dependencies: anope_chanserv.access */
+
#include "module.h"
-#include "modules/os_session.h"
-#include "modules/bs_kick.h"
-#include "modules/cs_mode.h"
-#include "modules/bs_badwords.h"
-#include "modules/os_news.h"
-#include "modules/suspend.h"
-#include "modules/os_forbid.h"
-#include "modules/cs_entrymsg.h"
+#include "modules/operserv/session.h"
+#include "modules/botserv/kick.h"
+#include "modules/chanserv/mode.h"
+#include "modules/botserv/badwords.h"
+#include "modules/operserv/news.h"
+#include "modules/operserv/forbid.h"
+#include "modules/chanserv/entrymsg.h"
+#include "modules/nickserv/suspend.h"
+#include "modules/chanserv/suspend.h"
+#include "modules/chanserv/access.h"
+#include "modules/nickserv/access.h"
#define READ(x) \
if (true) \
@@ -94,6 +107,18 @@ else \
#define OLD_NEWS_OPER 1
#define OLD_NEWS_RANDOM 2
+enum
+{
+ TTB_BOLDS,
+ TTB_COLORS,
+ TTB_REVERSES,
+ TTB_UNDERLINES,
+ TTB_BADWORDS,
+ TTB_CAPS,
+ TTB_FLOOD,
+ TTB_REPEAT,
+};
+
static struct mlock_info
{
char c;
@@ -143,21 +168,25 @@ enum
LANG_PL /* Polish */
};
-static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status, uint32_t *limit, Anope::string *key)
+static void process_mlock(ChanServ::Channel *ci, uint32_t lock, bool status, uint32_t *limit, Anope::string *key)
{
- ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
+ ServiceReference<ModeLocks> mlocks;
+
+ if (!mlocks)
+ return;
+
for (unsigned i = 0; i < (sizeof(mlock_infos) / sizeof(mlock_info)); ++i)
if (lock & mlock_infos[i].m)
{
ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock_infos[i].c);
- if (cm && ml)
+ if (cm)
{
if (limit && mlock_infos[i].c == 'l')
- ml->SetMLock(cm, status, stringify(*limit));
+ mlocks->SetMLock(ci, cm, status, stringify(*limit));
else if (key && mlock_infos[i].c == 'k')
- ml->SetMLock(cm, status, *key);
+ mlocks->SetMLock(ci, cm, status, *key);
else
- ml->SetMLock(cm, status);
+ mlocks->SetMLock(ci, cm, status);
}
}
}
@@ -435,7 +464,8 @@ int read_int32(int32_t *ret, dbFILE *f)
static void LoadNicks()
{
- ServiceReference<ForbidService> forbid("ForbidService", "forbid");
+ if (!NickServ::service)
+ return;
dbFILE *f = open_db_read("NickServ", "nick.db", 14);
if (f == NULL)
return;
@@ -445,27 +475,33 @@ static void LoadNicks()
Anope::string buffer;
READ(read_string(buffer, f));
- NickCore *nc = new NickCore(buffer);
+
+ NickServ::Account *nc = Serialize::New<NickServ::Account *>();
+ nc->SetDisplay(buffer);
const Anope::string settings[] = { "killprotect", "kill_quick", "ns_secure", "ns_private", "hide_email",
"hide_mask", "hide_quit", "memo_signon", "memo_receive", "autoop", "msg", "ns_keepmodes" };
for (unsigned j = 0; j < sizeof(settings) / sizeof(Anope::string); ++j)
- nc->Shrink<bool>(settings[j].upper());
+ nc->UnsetS<bool>(settings[j].upper());
char pwbuf[32];
READ(read_buffer(pwbuf, f));
if (hashm == "plain")
- my_b64_encode(pwbuf, nc->pass);
+ {
+ Anope::string p;
+ my_b64_encode(pwbuf, p);
+ nc->SetPassword(p);
+ }
else if (hashm == "md5" || hashm == "oldmd5")
- nc->pass = Hex(pwbuf, 16);
+ nc->SetPassword(Hex(pwbuf, 16));
else if (hashm == "sha1")
- nc->pass = Hex(pwbuf, 20);
+ nc->SetPassword(Hex(pwbuf, 20));
else
- nc->pass = Hex(pwbuf, strlen(pwbuf));
- nc->pass = hashm + ":" + nc->pass;
+ nc->SetPassword(Hex(pwbuf, strlen(pwbuf)));
+ nc->SetPassword(hashm + ":" + nc->GetPassword());
READ(read_string(buffer, f));
- nc->email = buffer;
+ nc->SetEmail(buffer);
READ(read_string(buffer, f));
if (!buffer.empty())
@@ -480,122 +516,134 @@ static void LoadNicks()
READ(read_uint32(&u32, f));
if (u32 & OLD_NI_KILLPROTECT)
- nc->Extend<bool>("KILLPROTECT");
+ nc->SetS<bool>("KILLPROTECT", true);
if (u32 & OLD_NI_SECURE)
- nc->Extend<bool>("NS_SECURE");
+ nc->SetS<bool>("NS_SECURE", true);
if (u32 & OLD_NI_MSG)
- nc->Extend<bool>("MSG");
+ nc->SetS<bool>("MSG", true);
if (u32 & OLD_NI_MEMO_HARDMAX)
- nc->Extend<bool>("MEMO_HARDMAX");
+ nc->SetS<bool>("MEMO_HARDMAX", true);
if (u32 & OLD_NI_MEMO_SIGNON)
- nc->Extend<bool>("MEMO_SIGNON");
+ nc->SetS<bool>("MEMO_SIGNON", true);
if (u32 & OLD_NI_MEMO_RECEIVE)
- nc->Extend<bool>("MEMO_RECEIVE");
+ nc->SetS<bool>("MEMO_RECEIVE", true);
if (u32 & OLD_NI_PRIVATE)
- nc->Extend<bool>("NS_PRIVATE");
+ nc->SetS<bool>("NS_PRIVATE", true);
if (u32 & OLD_NI_HIDE_EMAIL)
- nc->Extend<bool>("HIDE_EMAIL");
+ nc->SetS<bool>("HIDE_EMAIL", true);
if (u32 & OLD_NI_HIDE_MASK)
- nc->Extend<bool>("HIDE_MASK");
+ nc->SetS<bool>("HIDE_MASK", true);
if (u32 & OLD_NI_HIDE_QUIT)
- nc->Extend<bool>("HIDE_QUIT");
+ nc->SetS<bool>("HIDE_QUIT", true);
if (u32 & OLD_NI_KILL_QUICK)
- nc->Extend<bool>("KILL_QUICK");
+ nc->SetS<bool>("KILL_QUICK", true);
if (u32 & OLD_NI_KILL_IMMED)
- nc->Extend<bool>("KILL_IMMED");
+ nc->SetS<bool>("KILL_IMMED", true);
if (u32 & OLD_NI_MEMO_MAIL)
- nc->Extend<bool>("MEMO_MAIL");
+ nc->SetS<bool>("MEMO_MAIL", true);
if (u32 & OLD_NI_HIDE_STATUS)
- nc->Extend<bool>("HIDE_STATUS");
+ nc->SetS<bool>("HIDE_STATUS", true);
if (u32 & OLD_NI_SUSPENDED)
{
- SuspendInfo si;
- si.what = nc->display;
- si.when = si.expires = 0;
- nc->Extend("NS_SUSPENDED", si);
+ NSSuspendInfo *si = Serialize::New<NSSuspendInfo *>();
+ if (si)
+ {
+ si->SetAccount(nc);
+ }
}
if (!(u32 & OLD_NI_AUTOOP))
- nc->Extend<bool>("AUTOOP");
+ nc->SetS<bool>("AUTOOP", true);
uint16_t u16;
READ(read_uint16(&u16, f));
switch (u16)
{
case LANG_ES:
- nc->language = "es_ES";
+ nc->SetLanguage("es_ES");
break;
case LANG_PT:
- nc->language = "pt_PT";
+ nc->SetLanguage("pt_PT");
break;
case LANG_FR:
- nc->language = "fr_FR";
+ nc->SetLanguage("fr_FR");
break;
case LANG_TR:
- nc->language = "tr_TR";
+ nc->SetLanguage("tr_TR");
break;
case LANG_IT:
- nc->language = "it_IT";
+ nc->SetLanguage("it_IT");
break;
case LANG_DE:
- nc->language = "de_DE";
+ nc->SetLanguage("de_DE");
break;
case LANG_CAT:
- nc->language = "ca_ES"; // yes, iso639 defines catalan as CA
+ nc->SetLanguage("ca_ES"); // yes, iso639 defines catalan as CA
break;
case LANG_GR:
- nc->language = "el_GR";
+ nc->SetLanguage("el_GR");
break;
case LANG_NL:
- nc->language = "nl_NL";
+ nc->SetLanguage("nl_NL");
break;
case LANG_RU:
- nc->language = "ru_RU";
+ nc->SetLanguage("ru_RU");
break;
case LANG_HUN:
- nc->language = "hu_HU";
+ nc->SetLanguage("hu_HU");
break;
case LANG_PL:
- nc->language = "pl_PL";
+ nc->SetLanguage("pl_PL");
break;
case LANG_EN_US:
case LANG_JA_JIS:
case LANG_JA_EUC:
case LANG_JA_SJIS: // these seem to be unused
default:
- nc->language = "en";
+ nc->SetLanguage("en");
}
READ(read_uint16(&u16, f));
for (uint16_t j = 0; j < u16; ++j)
{
READ(read_string(buffer, f));
- nc->access.push_back(buffer);
+
+ NickAccess *a = Serialize::New<NickAccess *>();
+ if (a)
+ {
+ a->SetAccount(nc);
+ a->SetMask(buffer);
+ }
}
int16_t i16;
READ(read_int16(&i16, f));
- READ(read_int16(&nc->memos.memomax, f));
+ READ(read_int16(&i16, f));
+ MemoServ::MemoInfo *mi = nc->GetMemos();
+ if (mi)
+ mi->SetMemoMax(i16);
for (int16_t j = 0; j < i16; ++j)
{
- Memo *m = new Memo;
+ MemoServ::Memo *m = Serialize::New<MemoServ::Memo *>();
READ(read_uint32(&u32, f));
uint16_t flags;
READ(read_uint16(&flags, f));
int32_t tmp32;
READ(read_int32(&tmp32, f));
- m->time = tmp32;
+ if (m)
+ m->SetTime(tmp32);
char sbuf[32];
READ(read_buffer(sbuf, f));
- m->sender = sbuf;
- READ(read_string(m->text, f));
- m->owner = nc->display;
- nc->memos.memos->push_back(m);
- m->mi = &nc->memos;
+ if (m)
+ m->SetSender(sbuf);
+ Anope::string text;
+ READ(read_string(text, f));
+ if (m)
+ m->SetText(text);
}
READ(read_uint16(&u16, f));
READ(read_int16(&i16, f));
- Log(LOG_DEBUG) << "Loaded NickCore " << nc->display;
+ Log(LOG_DEBUG) << "Loaded NickServ::Account " << nc->GetDisplay();
}
for (int i = 0; i < 1024; ++i)
@@ -620,7 +668,7 @@ static void LoadNicks()
Anope::string core;
READ(read_string(core, f));
- NickCore *nc = NickCore::Find(core);
+ NickServ::Account *nc = NickServ::FindAccount(core);
if (nc == NULL)
{
Log() << "Skipping coreless nick " << nick << " with core " << core;
@@ -629,41 +677,38 @@ static void LoadNicks()
if (tmpu16 & OLD_NS_VERBOTEN)
{
- if (!forbid)
+ if (nc->GetDisplay().find_first_of("?*") != Anope::string::npos)
{
delete nc;
continue;
}
- if (nc->display.find_first_of("?*") != Anope::string::npos)
+ ForbidData *d = Serialize::New<ForbidData *>();
+ if (d)
{
- delete nc;
- continue;
+ d->SetMask(nc->GetDisplay());
+ d->SetCreator(last_usermask);
+ d->SetReason(last_realname);
+ d->SetType(FT_NICK);
}
-
- ForbidData *d = forbid->CreateForbid();
- d->mask = nc->display;
- d->creator = last_usermask;
- d->reason = last_realname;
- d->expires = 0;
- d->created = 0;
- d->type = FT_NICK;
+
delete nc;
- forbid->AddForbid(d);
continue;
}
- NickAlias *na = new NickAlias(nick, nc);
- na->last_usermask = last_usermask;
- na->last_realname = last_realname;
- na->last_quit = last_quit;
- na->time_registered = time_registered;
- na->last_seen = last_seen;
+ NickServ::Nick *na = Serialize::New<NickServ::Nick *>();
+ na->SetNick(nick);
+ na->SetAccount(nc);
+ na->SetLastUsermask(last_usermask);
+ na->SetLastRealname(last_realname);
+ na->SetLastQuit(last_quit);
+ na->SetTimeRegistered(time_registered);
+ na->SetLastSeen(last_seen);
if (tmpu16 & OLD_NS_NO_EXPIRE)
- na->Extend<bool>("NS_NO_EXPIRE");
+ na->SetS<bool>("NS_NO_EXPIRE", true);
- Log(LOG_DEBUG) << "Loaded NickAlias " << na->nick;
+ Log(LOG_DEBUG) << "Loaded NickServ::Nick " << na->GetNick();
}
close_db(f); /* End of section Ia */
@@ -686,7 +731,7 @@ static void LoadVHosts()
READ(read_string(creator, f));
READ(read_int32(&vtime, f));
- NickAlias *na = NickAlias::Find(nick);
+ NickServ::Nick *na = NickServ::FindNick(nick);
if (na == NULL)
{
Log() << "Removing vhost for non-existent nick " << nick;
@@ -695,7 +740,7 @@ static void LoadVHosts()
na->SetVhost(ident, host, creator, vtime);
- Log() << "Loaded vhost for " << na->nick;
+ Log() << "Loaded vhost for " << na->GetNick();
}
close_db(f);
@@ -721,13 +766,13 @@ static void LoadBots()
READ(read_int32(&created, f));
READ(read_int16(&chancount, f));
- BotInfo *bi = BotInfo::Find(nick, true);
+ ServiceBot *bi = ServiceBot::Find(nick, true);
if (!bi)
- bi = new BotInfo(nick, user, host, real);
- bi->created = created;
+ bi = new ServiceBot(nick, user, host, real);
+ bi->bi->SetCreated(created);
if (flags & OLD_BI_PRIVATE)
- bi->oper_only = true;
+ bi->bi->SetOperOnly(true);
Log(LOG_DEBUG) << "Loaded bot " << bi->nick;
}
@@ -737,7 +782,13 @@ static void LoadBots()
static void LoadChannels()
{
- ServiceReference<ForbidService> forbid("ForbidService", "forbid");
+ ServiceReference<BadWords> badwords;
+ ServiceReference<ChanServ::ChanServService> chanserv;
+
+ if (!chanserv)
+ return;
+
+ ServiceReference<ForbidService> forbid;
dbFILE *f = open_db_read("ChanServ", "chan.db", 16);
if (f == NULL)
return;
@@ -748,87 +799,92 @@ static void LoadChannels()
Anope::string buffer;
char namebuf[64];
READ(read_buffer(namebuf, f));
- ChannelInfo *ci = new ChannelInfo(namebuf);
+ ChanServ::Channel *ci = Serialize::New<ChanServ::Channel *>();
+ ci->SetName(namebuf);
const Anope::string settings[] = { "keeptopic", "peace", "cs_private", "restricted", "cs_secure", "secureops", "securefounder",
"signkick", "signkick_level", "topiclock", "persist", "noautoop", "cs_keepmodes" };
for (unsigned j = 0; j < sizeof(settings) / sizeof(Anope::string); ++j)
- ci->Shrink<bool>(settings[j].upper());
+ ci->UnsetS<bool>(settings[j].upper());
READ(read_string(buffer, f));
- ci->SetFounder(NickCore::Find(buffer));
+ ci->SetFounder(NickServ::FindAccount(buffer));
READ(read_string(buffer, f));
- ci->SetSuccessor(NickCore::Find(buffer));
+ ci->SetSuccessor(NickServ::FindAccount(buffer));
char pwbuf[32];
READ(read_buffer(pwbuf, f));
- READ(read_string(ci->desc, f));
+ Anope::string desc;
+ READ(read_string(desc, f));
+ ci->SetDesc(desc);
READ(read_string(buffer, f));
READ(read_string(buffer, f));
int32_t tmp32;
READ(read_int32(&tmp32, f));
- ci->time_registered = tmp32;
+ ci->SetTimeRegistered(tmp32);
READ(read_int32(&tmp32, f));
- ci->last_used = tmp32;
+ ci->SetLastUsed(tmp32);
- READ(read_string(ci->last_topic, f));
+ Anope::string last_topic;
+ READ(read_string(last_topic, f));
+ ci->SetLastTopic(last_topic);
READ(read_buffer(pwbuf, f));
- ci->last_topic_setter = pwbuf;
+ ci->SetLastTopicSetter(pwbuf);
READ(read_int32(&tmp32, f));
- ci->last_topic_time = tmp32;
+ ci->SetLastTopicTime(tmp32);
uint32_t tmpu32;
READ(read_uint32(&tmpu32, f));
// Temporary flags cleanup
tmpu32 &= ~0x80000000;
if (tmpu32 & OLD_CI_KEEPTOPIC)
- ci->Extend<bool>("KEEPTOPIC");
+ ci->SetS<bool>("KEEPTOPIC", true);
if (tmpu32 & OLD_CI_SECUREOPS)
- ci->Extend<bool>("SECUREOPS");
+ ci->SetS<bool>("SECUREOPS", true);
if (tmpu32 & OLD_CI_PRIVATE)
- ci->Extend<bool>("CS_PRIVATE");
+ ci->SetS<bool>("CS_PRIVATE", true);
if (tmpu32 & OLD_CI_TOPICLOCK)
- ci->Extend<bool>("TOPICLOCK");
+ ci->SetS<bool>("TOPICLOCK", true);
if (tmpu32 & OLD_CI_RESTRICTED)
- ci->Extend<bool>("RESTRICTED");
+ ci->SetS<bool>("RESTRICTED", true);
if (tmpu32 & OLD_CI_PEACE)
- ci->Extend<bool>("PEACE");
+ ci->SetS<bool>("PEACE", true);
if (tmpu32 & OLD_CI_SECURE)
- ci->Extend<bool>("CS_SECURE");
+ ci->SetS<bool>("CS_SECURE", true);
if (tmpu32 & OLD_CI_NO_EXPIRE)
- ci->Extend<bool>("CS_NO_EXPIRE");
+ ci->SetS<bool>("CS_NO_EXPIRE", true);
if (tmpu32 & OLD_CI_MEMO_HARDMAX)
- ci->Extend<bool>("MEMO_HARDMAX");
+ ci->SetS<bool>("MEMO_HARDMAX", true);
if (tmpu32 & OLD_CI_SECUREFOUNDER)
- ci->Extend<bool>("SECUREFOUNDER");
+ ci->SetS<bool>("SECUREFOUNDER", true);
if (tmpu32 & OLD_CI_SIGNKICK)
- ci->Extend<bool>("SIGNKICK");
+ ci->SetS<bool>("SIGNKICK", true);
if (tmpu32 & OLD_CI_SIGNKICK_LEVEL)
- ci->Extend<bool>("SIGNKICK_LEVEL");
+ ci->SetS<bool>("SIGNKICK_LEVEL", true);
Anope::string forbidby, forbidreason;
READ(read_string(forbidby, f));
READ(read_string(forbidreason, f));
if (tmpu32 & OLD_CI_SUSPENDED)
{
- SuspendInfo si;
- si.what = ci->name;
- si.by = forbidby;
- si.reason = forbidreason;
- si.when = si.expires = 0;
- ci->Extend("CS_SUSPENDED", si);
+ CSSuspendInfo *si = Serialize::New<CSSuspendInfo *>();
+ if (si)
+ {
+ si->SetChannel(ci);
+ si->SetBy(forbidby);
+ }
}
bool forbid_chan = tmpu32 & OLD_CI_VERBOTEN;
int16_t tmp16;
READ(read_int16(&tmp16, f));
- ci->bantype = tmp16;
+ ci->SetBanType(tmp16);
READ(read_int16(&tmp16, f));
if (tmp16 > 36)
@@ -838,17 +894,16 @@ static void LoadChannels()
int16_t level;
READ(read_int16(&level, f));
- if (level == ACCESS_INVALID)
- level = ACCESS_FOUNDER;
+ if (level == ChanServ::ACCESS_INVALID)
+ level = ChanServ::ACCESS_FOUNDER;
if (j == 10 && level < 0) // NOJOIN
- ci->Shrink<bool>("RESTRICTED"); // If CSDefRestricted was enabled this can happen
+ ci->UnsetS<bool>("RESTRICTED"); // If CSDefRestricted was enabled this can happen
ci->SetLevel(GetLevelName(j), level);
}
bool xop = tmpu32 & OLD_CI_XOP;
- ServiceReference<AccessProvider> provider_access("AccessProvider", "access/access"), provider_xop("AccessProvider", "access/xop");
uint16_t tmpu16;
READ(read_uint16(&tmpu16, f));
for (uint16_t j = 0; j < tmpu16; ++j)
@@ -857,19 +912,19 @@ static void LoadChannels()
READ(read_uint16(&in_use, f));
if (in_use)
{
- ChanAccess *access = NULL;
-
+ ChanServ::ChanAccess *access = NULL;
+
if (xop)
{
- if (provider_xop)
- access = provider_xop->Create();
+ access = Serialize::New<XOPChanAccess *>();
}
else
- if (provider_access)
- access = provider_access->Create();
+ {
+ access = Serialize::New<AccessChanAccess *>();
+ }
if (access)
- access->ci = ci;
+ access->SetChannel(ci);
int16_t level;
READ(read_int16(&level, f));
@@ -900,16 +955,19 @@ static void LoadChannels()
Anope::string mask;
READ(read_string(mask, f));
if (access)
- access->SetMask(mask, ci);
+ {
+ access->SetMask(mask);
+ NickServ::Nick *na = NickServ::FindNick(mask);
+ if (na)
+ na->SetAccount(na->GetAccount());
+ }
READ(read_int32(&tmp32, f));
if (access)
{
- access->last_seen = tmp32;
- access->creator = "Unknown";
- access->created = Anope::CurTime;
-
- ci->AddAccess(access);
+ access->SetLastSeen(tmp32);
+ access->SetCreator("Unknown");
+ access->SetCreated(Anope::CurTime);
}
}
}
@@ -943,74 +1001,67 @@ static void LoadChannels()
READ(read_string(buffer, f)); // +L
READ(read_int16(&tmp16, f));
- READ(read_int16(&ci->memos.memomax, f));
+ READ(read_int16(&tmp16, f));
+ MemoServ::MemoInfo *mi = ci->GetMemos();
+ if (mi)
+ mi->SetMemoMax(tmp16);
for (int16_t j = 0; j < tmp16; ++j)
{
READ(read_uint32(&tmpu32, f));
READ(read_uint16(&tmpu16, f));
- Memo *m = new Memo;
+ MemoServ::Memo *m = Serialize::New<MemoServ::Memo *>();
READ(read_int32(&tmp32, f));
- m->time = tmp32;
+ if (m)
+ m->SetTime(tmp32);
char sbuf[32];
READ(read_buffer(sbuf, f));
- m->sender = sbuf;
- READ(read_string(m->text, f));
- m->owner = ci->name;
- ci->memos.memos->push_back(m);
- m->mi = &ci->memos;
+ if (m)
+ m->SetSender(sbuf);
+ Anope::string text;
+ READ(read_string(text, f));
+ if (m)
+ m->SetText(text);
}
READ(read_string(buffer, f));
if (!buffer.empty())
{
- EntryMessageList *eml = ci->Require<EntryMessageList>("entrymsg");
- if (eml)
+ EntryMsg *e = Serialize::New<EntryMsg *>();
+ if (e)
{
- EntryMsg *e = eml->Create();
-
- e->chan = ci->name;
- e->creator = "Unknown";
- e->message = buffer;
- e->when = Anope::CurTime;
-
- (*eml)->push_back(e);
+ e->SetChannel(ci);
+ e->SetCreator("Unknown");
+ e->SetMessage(buffer);
+ e->SetWhen(Anope::CurTime);
}
}
READ(read_string(buffer, f));
- ci->bi = BotInfo::Find(buffer, true);
+ ci->SetBot(ServiceBot::Find(buffer, true));
READ(read_int32(&tmp32, f));
if (tmp32 & OLD_BS_DONTKICKOPS)
- ci->Extend<bool>("BS_DONTKICKOPS");
+ ci->SetS<bool>("BS_DONTKICKOPS", true);
if (tmp32 & OLD_BS_DONTKICKVOICES)
- ci->Extend<bool>("BS_DONTKICKVOICES");
+ ci->SetS<bool>("BS_DONTKICKVOICES", true);
if (tmp32 & OLD_BS_FANTASY)
- ci->Extend<bool>("BS_FANTASY");
+ ci->SetS<bool>("BS_FANTASY", true);
if (tmp32 & OLD_BS_GREET)
- ci->Extend<bool>("BS_GREET");
+ ci->SetS<bool>("BS_GREET", true);
if (tmp32 & OLD_BS_NOBOT)
- ci->Extend<bool>("BS_NOBOT");
+ ci->SetS<bool>("BS_NOBOT", true);
- KickerData *kd = ci->Require<KickerData>("kickerdata");
+ KickerData *kd = GetKickerData(ci);
if (kd)
{
- if (tmp32 & OLD_BS_KICK_BOLDS)
- kd->bolds = true;
- if (tmp32 & OLD_BS_KICK_COLORS)
- kd->colors = true;
- if (tmp32 & OLD_BS_KICK_REVERSES)
- kd->reverses = true;
- if (tmp32 & OLD_BS_KICK_UNDERLINES)
- kd->underlines = true;
- if (tmp32 & OLD_BS_KICK_BADWORDS)
- kd->badwords = true;
- if (tmp32 & OLD_BS_KICK_CAPS)
- kd->caps = true;
- if (tmp32 & OLD_BS_KICK_FLOOD)
- kd->flood = true;
- if (tmp32 & OLD_BS_KICK_REPEAT)
- kd->repeat = true;
+ kd->SetBolds(tmp32 & OLD_BS_KICK_BOLDS);
+ kd->SetColors(tmp32 & OLD_BS_KICK_COLORS);
+ kd->SetReverses(tmp32 & OLD_BS_KICK_REVERSES);
+ kd->SetUnderlines(tmp32 & OLD_BS_KICK_UNDERLINES);
+ kd->SetBadwords(tmp32 & OLD_BS_KICK_BADWORDS);
+ kd->SetCaps(tmp32 & OLD_BS_KICK_CAPS);
+ kd->SetFlood(tmp32 & OLD_BS_KICK_FLOOD);
+ kd->SetRepeat(tmp32 & OLD_BS_KICK_REPEAT);
}
READ(read_int16(&tmp16, f));
@@ -1018,27 +1069,51 @@ static void LoadChannels()
{
int16_t ttb;
READ(read_int16(&ttb, f));
- if (j < TTB_SIZE && kd)
- kd->ttb[j] = ttb;
+ switch (j)
+ {
+ case TTB_BOLDS:
+ kd->SetTTBBolds(ttb);
+ break;
+ case TTB_COLORS:
+ kd->SetTTBColors(ttb);
+ break;
+ case TTB_REVERSES:
+ kd->SetTTBReverses(ttb);
+ break;
+ case TTB_UNDERLINES:
+ kd->SetTTBUnderlines(ttb);
+ break;
+ case TTB_BADWORDS:
+ kd->SetTTBBadwords(ttb);
+ break;
+ case TTB_CAPS:
+ kd->SetTTBCaps(ttb);
+ break;
+ case TTB_FLOOD:
+ kd->SetTTBFlood(ttb);
+ break;
+ case TTB_REPEAT:
+ kd->SetTTBRepeat(ttb);
+ break;
+ }
}
READ(read_int16(&tmp16, f));
if (kd)
- kd->capsmin = tmp16;
+ kd->SetCapsMin(tmp16);
READ(read_int16(&tmp16, f));
if (kd)
- kd->capspercent = tmp16;
+ kd->SetCapsPercent(tmp16);
READ(read_int16(&tmp16, f));
if (kd)
- kd->floodlines = tmp16;
+ kd->SetFloodLines(tmp16);
READ(read_int16(&tmp16, f));
if (kd)
- kd->floodsecs = tmp16;
+ kd->SetFloodSecs(tmp16);
READ(read_int16(&tmp16, f));
if (kd)
- kd->repeattimes = tmp16;
+ kd->SetRepeatTimes(tmp16);
- BadWords *bw = ci->Require<BadWords>("badwords");
READ(read_uint16(&tmpu16, f));
for (uint16_t j = 0; j < tmpu16; ++j)
{
@@ -1058,38 +1133,33 @@ static void LoadChannels()
else if (type == 3)
bwtype = BW_END;
- if (bw)
- bw->AddBadWord(buffer, bwtype);
+ if (badwords)
+ badwords->AddBadWord(ci, buffer, bwtype);
}
}
if (forbid_chan)
{
- if (!forbid)
+ if (ci->GetName().find_first_of("?*") != Anope::string::npos)
{
delete ci;
continue;
}
- if (ci->name.find_first_of("?*") != Anope::string::npos)
+ ForbidData *d = Serialize::New<ForbidData *>();
+ if (d)
{
- delete ci;
- continue;
+ d->SetMask(ci->GetName());
+ d->SetCreator(forbidby);
+ d->SetReason(forbidreason);
+ d->SetType(FT_CHAN);
}
-
- ForbidData *d = forbid->CreateForbid();
- d->mask = ci->name;
- d->creator = forbidby;
- d->reason = forbidreason;
- d->expires = 0;
- d->created = 0;
- d->type = FT_CHAN;
+
delete ci;
- forbid->AddForbid(d);
continue;
}
- Log(LOG_DEBUG) << "Loaded channel " << ci->name;
+ Log(LOG_DEBUG) << "Loaded channel " << ci->GetName();
}
close_db(f);
@@ -1104,9 +1174,8 @@ static void LoadOper()
XLineManager *akill, *sqline, *snline, *szline;
akill = sqline = snline = szline = NULL;
- for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
+ for (XLineManager *xl : XLineManager::XLineManagers)
{
- XLineManager *xl = *it;
if (xl->Type() == 'G')
akill = xl;
else if (xl->Type() == 'Q')
@@ -1138,8 +1207,14 @@ static void LoadOper()
if (!akill)
continue;
- XLine *x = new XLine(user + "@" + host, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(user + "@" + host);
+ x->SetBy(by);
+ x->SetExpires(expires);
+ x->SetReason(reason);
+ x->SetID(XLineManager::GenerateUID());
+ x->SetCreated(seton);
+
akill->AddXLine(x);
}
@@ -1158,8 +1233,14 @@ static void LoadOper()
if (!snline)
continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(by);
+ x->SetExpires(expires);
+ x->SetReason(reason);
+ x->SetID(XLineManager::GenerateUID());
+ x->SetCreated(seton);
+
snline->AddXLine(x);
}
@@ -1178,8 +1259,14 @@ static void LoadOper()
if (!sqline)
continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(by);
+ x->SetExpires(expires);
+ x->SetReason(reason);
+ x->SetID(XLineManager::GenerateUID());
+ x->SetCreated(seton);
+
sqline->AddXLine(x);
}
@@ -1198,8 +1285,14 @@ static void LoadOper()
if (!szline)
continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(by);
+ x->SetExpires(expires);
+ x->SetReason(reason);
+ x->SetID(XLineManager::GenerateUID());
+ x->SetCreated(seton);
+
szline->AddXLine(x);
}
@@ -1208,13 +1301,10 @@ static void LoadOper()
static void LoadExceptions()
{
- if (!session_service)
- return;
-
dbFILE *f = open_db_read("OperServ", "exception.db", 9);
if (f == NULL)
return;
-
+
int16_t num;
READ(read_int16(&num, f));
for (int i = 0; i < num; ++i)
@@ -1231,14 +1321,16 @@ static void LoadExceptions()
READ(read_int32(&time, f));
READ(read_int32(&expires, f));
- Exception *exception = session_service->CreateException();
- exception->mask = mask;
- exception->limit = limit;
- exception->who = who;
- exception->time = time;
- exception->expires = expires;
- exception->reason = reason;
- session_service->AddException(exception);
+ Exception *e = Serialize::New<Exception *>();
+ if (e)
+ {
+ e->SetMask(mask);
+ e->SetLimit(limit);
+ e->SetWho(who);
+ e->SetTime(time);
+ e->SetExpires(expires);
+ e->SetReason(reason);
+ }
}
close_db(f);
@@ -1246,9 +1338,6 @@ static void LoadExceptions()
static void LoadNews()
{
- if (!news_service)
- return;
-
dbFILE *f = open_db_read("OperServ", "news.db", 9);
if (f == NULL)
@@ -1260,60 +1349,68 @@ static void LoadNews()
for (int16_t i = 0; i < n; i++)
{
int16_t type;
- NewsItem *ni = news_service->CreateNewsItem();
+ NewsItem *ni = Serialize::New<NewsItem *>();
+
+ if (!ni)
+ break;
READ(read_int16(&type, f));
switch (type)
{
case OLD_NEWS_LOGON:
- ni->type = NEWS_LOGON;
+ ni->SetNewsType(NEWS_LOGON);
break;
case OLD_NEWS_OPER:
- ni->type = NEWS_OPER;
+ ni->SetNewsType(NEWS_OPER);
break;
case OLD_NEWS_RANDOM:
- ni->type = NEWS_RANDOM;
+ ni->SetNewsType(NEWS_RANDOM);
break;
}
int32_t unused;
READ(read_int32(&unused, f));
- READ(read_string(ni->text, f));
+ Anope::string text;
+ READ(read_string(text, f));
+ ni->SetText(text);
char who[32];
READ(read_buffer(who, f));
- ni->who = who;
+ ni->SetWho(who);
int32_t tmp;
READ(read_int32(&tmp, f));
- ni->time = tmp;
-
- news_service->AddNewsItem(ni);
+ ni->SetTime(tmp);
}
close_db(f);
}
class DBOld : public Module
+ , public EventHook<Event::LoadDatabase>
+ , public EventHook<Event::UplinkSync>
{
- PrimitiveExtensibleItem<uint32_t> mlock_on, mlock_off, mlock_limit;
- PrimitiveExtensibleItem<Anope::string> mlock_key;
+ ExtensibleItem<uint32_t> mlock_on, mlock_off, mlock_limit; // XXX these are no longer required because of confmodes
+ ExtensibleItem<Anope::string> mlock_key;
public:
- DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR),
- mlock_on(this, "mlock_on"), mlock_off(this, "mlock_off"), mlock_limit(this, "mlock_limit"), mlock_key(this, "mlock_key")
+ DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
+ , EventHook<Event::LoadDatabase>(this)
+ , EventHook<Event::UplinkSync>(this)
+ , mlock_on(this, "mlock_on")
+ , mlock_off(this, "mlock_off")
+ , mlock_limit(this, "mlock_limit")
+ , mlock_key(this, "mlock_key")
{
-
-
- hashm = Config->GetModule(this)->Get<const Anope::string>("hash");
+ hashm = Config->GetModule(this)->Get<Anope::string>("hash");
if (hashm != "md5" && hashm != "oldmd5" && hashm != "sha1" && hashm != "plain" && hashm != "sha256")
throw ModuleException("Invalid hash method");
}
- EventReturn OnLoadDatabase() anope_override
+ EventReturn OnLoadDatabase() override
{
LoadNicks();
LoadVHosts();
@@ -1326,11 +1423,13 @@ class DBOld : public Module
return EVENT_STOP;
}
- void OnUplinkSync(Server *s) anope_override
+ void OnUplinkSync(Server *s) override
{
- for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
+ if (!ChanServ::service)
+ return;
+ for (auto& it : ChanServ::service->GetChannels())
{
- ChannelInfo *ci = it->second;
+ ChanServ::Channel *ci = it.second;
uint32_t *limit = mlock_limit.Get(ci);
Anope::string *key = mlock_key.Get(ci);
@@ -1357,5 +1456,10 @@ class DBOld : public Module
}
};
+template<> void ModuleInfo<DBOld>(ModuleDef *def)
+{
+ def->Depends("chanserv.access");
+}
+
MODULE_INIT(DBOld)
diff --git a/modules/database/redis.cpp b/modules/database/redis.cpp
new file mode 100644
index 000000000..21f7ca960
--- /dev/null
+++ b/modules/database/redis.cpp
@@ -0,0 +1,445 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/redis.h"
+
+using namespace Redis;
+
+class DatabaseRedis;
+static DatabaseRedis *me;
+
+class TypeLoader : public Interface
+{
+ Serialize::TypeBase *type;
+
+ public:
+ TypeLoader(Module *creator, Serialize::TypeBase *t) : Interface(creator), type(t) { }
+
+ void OnResult(const Reply &r) override;
+};
+
+class ObjectLoader : public Interface
+{
+ Serialize::Object *obj;
+
+ public:
+ ObjectLoader(Module *creator, Serialize::Object *s) : Interface(creator), obj(s) { }
+
+ void OnResult(const Reply &r) override;
+};
+
+class FieldLoader : public Interface
+{
+ Serialize::Object *obj;
+ Serialize::FieldBase *field;
+
+ public:
+ FieldLoader(Module *creator, Serialize::Object *o, Serialize::FieldBase *f) : Interface(creator), obj(o), field(f) { }
+
+ void OnResult(const Reply &) override;
+};
+
+class SubscriptionListener : public Interface
+{
+ public:
+ SubscriptionListener(Module *creator) : Interface(creator) { }
+
+ void OnResult(const Reply &r) override;
+};
+
+class DatabaseRedis : public Module
+ , public EventHook<Event::LoadDatabase>
+ , public EventHook<Event::SerializeEvents>
+{
+ SubscriptionListener sl;
+
+ public:
+ ServiceReference<Provider> redis;
+
+ DatabaseRedis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
+ , EventHook<Event::LoadDatabase>(this)
+ , EventHook<Event::SerializeEvents>(this)
+ , sl(this)
+ {
+ me = this;
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ this->redis = ServiceReference<Provider>(block->Get<Anope::string>("engine", "redis/main"));
+ }
+
+ EventReturn OnLoadDatabase() override
+ {
+ if (!redis)
+ return EVENT_STOP;
+
+ const std::map<Anope::string, Serialize::TypeBase *> &types = Serialize::TypeBase::GetTypes();
+ for (const std::pair<Anope::string, Serialize::TypeBase *> &p : types)
+ this->OnSerializeTypeCreate(p.second);
+
+ while (redis->BlockAndProcess());
+
+ redis->Subscribe(&this->sl, "anope");
+
+ return EVENT_STOP;
+ }
+
+ void OnSerializeTypeCreate(Serialize::TypeBase *sb)
+ {
+ std::vector<Anope::string> args = { "SMEMBERS", "ids:" + sb->GetName() };
+
+ redis->SendCommand(new TypeLoader(this, sb), args);
+ }
+
+ EventReturn OnSerializeList(Serialize::TypeBase *type, std::vector<Serialize::ID> &ids) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeFind(Serialize::TypeBase *type, Serialize::FieldBase *field, const Anope::string &value, Serialize::ID &id) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeGet(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &value) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeGetRefs(Serialize::Object *object, Serialize::TypeBase *type, std::vector<Serialize::Edge> &) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeDeref(Serialize::ID id, Serialize::TypeBase *type) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeGetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &type, Serialize::ID &value) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeSet(Serialize::Object *object, Serialize::FieldBase *field, const Anope::string &value) override
+ {
+ std::vector<Anope::string> args;
+
+ redis->StartTransaction();
+
+ const Anope::string &old = field->SerializeToString(object);
+ args = { "SREM", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + old, stringify(object->id) };
+ redis->SendCommand(nullptr, args);
+
+ // add object to type set
+ args = { "SADD", "ids:" + object->GetSerializableType()->GetName(), stringify(object->id) };
+ redis->SendCommand(nullptr, args);
+
+ // add key to key set
+ args = { "SADD", "keys:" + stringify(object->id), field->serialize_name };
+ redis->SendCommand(nullptr, args);
+
+ // set value
+ args = { "SET", "values:" + stringify(object->id) + ":" + field->serialize_name, value };
+ redis->SendCommand(nullptr, args);
+
+ // lookup
+ args = { "SADD", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + value, stringify(object->id) };
+ redis->SendCommand(nullptr, args);
+
+ redis->CommitTransaction();
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeSetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Serialize::Object *value) override
+ {
+ return OnSerializeSet(object, field, stringify(value->id));
+ }
+
+ EventReturn OnSerializeUnset(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ std::vector<Anope::string> args;
+
+ redis->StartTransaction();
+
+ const Anope::string &old = field->SerializeToString(object);
+ args = { "SREM", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + old, stringify(object->id) };
+ redis->SendCommand(nullptr, args);
+
+ // remove field from set
+ args = { "SREM", "keys:" + stringify(object->id), field->serialize_name };
+ redis->SendCommand(nullptr, args);
+
+ redis->CommitTransaction();
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializeUnsetSerializable(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ return OnSerializeUnset(object, field);
+ }
+
+ EventReturn OnSerializeHasField(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializableGetId(Serialize::ID &id) override
+ {
+ std::vector<Anope::string> args = { "INCR", "id" };
+
+ auto f = [&](const Reply &r)
+ {
+ id = r.i;
+ };
+
+ FInterface inter(this, f);
+ redis->SendCommand(&inter, args);
+ while (redis->BlockAndProcess());
+ return EVENT_ALLOW;
+ }
+
+ void OnSerializableCreate(Serialize::Object *) override
+ {
+ }
+
+ void OnSerializableDelete(Serialize::Object *obj) override
+ {
+ std::vector<Anope::string> args;
+
+ redis->StartTransaction();
+
+ for (Serialize::FieldBase *field : obj->GetSerializableType()->GetFields())
+ {
+ Anope::string value = field->SerializeToString(obj);
+
+ args = { "SREM", "lookup:" + obj->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + value, stringify(obj->id) };
+ redis->SendCommand(nullptr, args);
+
+ args = { "DEL", "values:" + stringify(obj->id) + ":" + field->serialize_name };
+ redis->SendCommand(nullptr, args);
+
+ args = { "SREM", "keys:" + stringify(obj->id), field->serialize_name };
+ redis->SendCommand(nullptr, args);
+ }
+
+ args = { "SREM", "ids:" + obj->GetSerializableType()->GetName(), stringify(obj->id) };
+ redis->SendCommand(nullptr, args);
+
+ redis->CommitTransaction();
+ }
+};
+
+void TypeLoader::OnResult(const Reply &r)
+{
+ if (r.type != Reply::MULTI_BULK || !me->redis)
+ {
+ delete this;
+ return;
+ }
+
+ for (unsigned i = 0; i < r.multi_bulk.size(); ++i)
+ {
+ const Reply *reply = r.multi_bulk[i];
+
+ if (reply->type != Reply::BULK)
+ continue;
+
+ int64_t id;
+ try
+ {
+ id = convertTo<int64_t>(reply->bulk);
+ }
+ catch (const ConvertException &)
+ {
+ continue;
+ }
+
+ Serialize::Object *obj = type->Require(id);
+ if (obj == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: Unable to require object #" << id << " of type " << type->GetName();
+ continue;
+ }
+
+ std::vector<Anope::string> args = { "SMEMBERS", "keys:" + stringify(id) };
+
+ me->redis->SendCommand(new ObjectLoader(me, obj), args);
+ }
+
+ delete this;
+}
+
+void ObjectLoader::OnResult(const Reply &r)
+{
+ if (r.type != Reply::MULTI_BULK || r.multi_bulk.empty() || !me->redis)
+ {
+ delete this;
+ return;
+ }
+
+ Serialize::TypeBase *type = obj->GetSerializableType();
+
+ for (Reply *reply : r.multi_bulk)
+ {
+ const Anope::string &key = reply->bulk;
+ Serialize::FieldBase *field = type->GetField(key);
+
+ if (field == nullptr)
+ continue;
+
+ std::vector<Anope::string> args = { "GET", "values:" + stringify(obj->id) + ":" + key };
+
+ me->redis->SendCommand(new FieldLoader(me, obj, field), args);
+ }
+
+ delete this;
+}
+
+void FieldLoader::OnResult(const Reply &r)
+{
+ Log(LOG_DEBUG_2) << "redis: Setting field " << field->serialize_name << " of object #" << obj->id << " of type " << obj->GetSerializableType()->GetName() << " to " << r.bulk;
+ field->UnserializeFromString(obj, r.bulk);
+
+ delete this;
+}
+
+void SubscriptionListener::OnResult(const Reply &r)
+{
+ /*
+ * message
+ * anope
+ * message
+ *
+ * set 4 email adam@anope.org
+ * unset 4 email
+ * create 4 NickCore
+ * delete 4
+ */
+
+ const Anope::string &message = r.multi_bulk[2]->bulk;
+ Anope::string command;
+ spacesepstream sep(message);
+
+ sep.GetToken(command);
+
+ if (command == "set" || command == "unset")
+ {
+ Anope::string sid, key, value;
+
+ sep.GetToken(sid);
+ sep.GetToken(key);
+ value = sep.GetRemaining();
+
+ Serialize::ID id;
+ try
+ {
+ id = convertTo<Serialize::ID>(sid);
+ }
+ catch (const ConvertException &ex)
+ {
+ Log(LOG_DEBUG) << "redis: unable to get id for SL update key " << sid;
+ return;
+ }
+
+ Serialize::Object *obj = Serialize::GetID(id);
+ if (obj == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: pmessage for unknown object #" << id;
+ return;
+ }
+
+ Serialize::FieldBase *field = obj->GetSerializableType()->GetField(key);
+ if (field == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: pmessage for unknown field of object #" << id << ": " << key;
+ return;
+ }
+
+ Log(LOG_DEBUG_2) << "redis: Setting field " << field->serialize_name << " of object #" << obj->id << " of type " << obj->GetSerializableType()->GetName() << " to " << value;
+ field->UnserializeFromString(obj, value);
+ }
+ else if (command == "create")
+ {
+ Anope::string sid, stype;
+
+ sep.GetToken(sid);
+ sep.GetToken(stype);
+
+ Serialize::ID id;
+ try
+ {
+ id = convertTo<Serialize::ID>(sid);
+ }
+ catch (const ConvertException &ex)
+ {
+ Log(LOG_DEBUG) << "redis: unable to get id for SL update key " << sid;
+ return;
+ }
+
+ Serialize::TypeBase *type = Serialize::TypeBase::Find(stype);
+ if (type == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: pmessage create for nonexistant type " << stype;
+ return;
+ }
+
+ Serialize::Object *obj = type->Require(id);
+ if (obj == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: require for pmessage create type " << type->GetName() << " id #" << id << " returned nullptr";
+ return;
+ }
+ }
+ else if (command == "delete")
+ {
+ Anope::string sid;
+
+ sep.GetToken(sid);
+
+ Serialize::ID id;
+ try
+ {
+ id = convertTo<Serialize::ID>(sid);
+ }
+ catch (const ConvertException &ex)
+ {
+ Log(LOG_DEBUG) << "redis: unable to get id for SL update key " << sid;
+ return;
+ }
+
+ Serialize::Object *obj = Serialize::GetID(id);
+ if (obj == nullptr)
+ {
+ Log(LOG_DEBUG) << "redis: message for unknown object #" << id;
+ return;
+ }
+
+ obj->Delete();
+ }
+ else
+ Log(LOG_DEBUG) << "redis: unknown message: " << message;
+}
+
+MODULE_INIT(DatabaseRedis)
diff --git a/modules/database/sql.cpp b/modules/database/sql.cpp
new file mode 100644
index 000000000..d7ed1963a
--- /dev/null
+++ b/modules/database/sql.cpp
@@ -0,0 +1,445 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/sql.h"
+
+using namespace SQL;
+
+class DBMySQL : public Module, public Pipe
+ , public EventHook<Event::SerializeEvents>
+{
+ private:
+ bool transaction = false;
+ bool inited = false;
+ Anope::string prefix;
+ ServiceReference<Provider> SQL;
+ std::unordered_multimap<Serialize::Object *, Serialize::FieldBase *> cache;
+
+ void CacheMiss(Serialize::Object *object, Serialize::FieldBase *field)
+ {
+ cache.insert(std::make_pair(object, field));
+ }
+
+ bool IsCacheMiss(Serialize::Object *object, Serialize::FieldBase *field)
+ {
+ auto range = cache.equal_range(object);
+ for (auto it = range.first; it != range.second; ++it)
+ if (it->second == field)
+ return true;
+ return false;
+ }
+
+ Result Run(const Query &query)
+ {
+ if (!SQL)
+ return Result();
+
+ if (!inited)
+ {
+ inited = true;
+ for (const Query &q : SQL->InitSchema(prefix))
+ SQL->RunQuery(q);
+ }
+
+ Log(LOG_DEBUG_2) << query.Unsafe();
+
+ return SQL->RunQuery(query);
+ }
+
+ void StartTransaction()
+ {
+ if (!SQL || transaction)
+ return;
+
+ Run(SQL->BeginTransaction());
+
+ transaction = true;
+ Notify();
+ }
+
+ void Commit()
+ {
+ if (!SQL || !transaction)
+ return;
+
+ Run(SQL->Commit());
+
+ transaction = false;
+ }
+
+ public:
+ DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
+ , EventHook<Event::SerializeEvents>(this)
+ {
+ }
+
+ void OnNotify() override
+ {
+ Commit();
+ Serialize::Clear();
+ cache.clear();
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ this->SQL = ServiceReference<Provider>(block->Get<Anope::string>("engine"));
+ this->prefix = block->Get<Anope::string>("prefix", "anope_db_");
+ inited = false;
+ }
+
+ EventReturn OnSerializeList(Serialize::TypeBase *type, std::vector<Serialize::ID> &ids) override
+ {
+ StartTransaction();
+
+ ids.clear();
+
+ Query query = "SELECT `id` FROM `" + prefix + type->GetName() + "`";
+ Result res = Run(query);
+ for (int i = 0; i < res.Rows(); ++i)
+ {
+ Serialize::ID id = convertTo<Serialize::ID>(res.Get(i, "id"));
+ ids.push_back(id);
+ }
+
+ return EVENT_ALLOW;
+ }
+
+ EventReturn OnSerializeFind(Serialize::TypeBase *type, Serialize::FieldBase *field, const Anope::string &value, Serialize::ID &id) override
+ {
+ if (!SQL)
+ return EVENT_CONTINUE;
+
+ StartTransaction();
+
+ for (Query &q : SQL->CreateTable(prefix, type->GetName()))
+ Run(q);
+
+ for (Query &q : SQL->AlterTable(prefix, type->GetName(), field->serialize_name, false))
+ Run(q);
+
+ for (const Query &q : SQL->CreateIndex(prefix + type->GetName(), field->serialize_name))
+ Run(q);
+
+ Query query("SELECT `id` FROM `" + prefix + type->GetName() + "` WHERE `" + field->serialize_name + "` = @value@");
+ query.SetValue("value", value);
+ Result res = Run(query);
+ if (res.Rows())
+ try
+ {
+ id = convertTo<Serialize::ID>(res.Get(0, "id"));
+ return EVENT_ALLOW;
+ }
+ catch (const ConvertException &)
+ {
+ }
+ return EVENT_CONTINUE;
+ }
+
+ private:
+ bool GetValue(Serialize::Object *object, Serialize::FieldBase *field, SQL::Result::Value &v)
+ {
+ StartTransaction();
+
+ Query query = "SELECT `" + field->serialize_name + "` FROM `" + prefix + object->GetSerializableType()->GetName() + "` WHERE `id` = @id@";
+ query.SetValue("id", object->id);
+ Result res = Run(query);
+
+ if (res.Rows() == 0)
+ return false;
+
+ v = res.GetValue(0, field->serialize_name);
+ return true;
+ }
+
+ public:
+ EventReturn OnSerializeGet(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &value) override
+ {
+ SQL::Result::Value v;
+
+ if (IsCacheMiss(object, field))
+ return EVENT_CONTINUE;
+
+ if (!GetValue(object, field, v))
+ {
+ CacheMiss(object, field);
+ return EVENT_CONTINUE;
+ }
+
+ value = v.value;
+ return EVENT_ALLOW;
+ }
+
+ EventReturn OnSerializeGetRefs(Serialize::Object *object, Serialize::TypeBase *type, std::vector<Serialize::Edge> &edges) override
+ {
+ StartTransaction();
+
+ edges.clear();
+
+ Query query;
+ if (type)
+ query = "SELECT field," + prefix + "edges.id,other_id,j1.type,j2.type AS other_type FROM `" + prefix + "edges` "
+ "JOIN `" + prefix + "objects` AS j1 ON " + prefix + "edges.id = j1.id "
+ "JOIN `" + prefix + "objects` AS j2 ON " + prefix + "edges.other_id = j2.id "
+ "WHERE "
+ " (" + prefix + "edges.id = @id@ AND j2.type = @other_type@) "
+ "OR"
+ " (other_id = @id@ AND j1.type = @other_type@)";
+ else
+ query = "SELECT field," + prefix + "edges.id,other_id,j1.type,j2.type AS other_type FROM `" + prefix + "edges` "
+ "JOIN `" + prefix + "objects` AS j1 ON " + prefix + "edges.id = j1.id "
+ "JOIN `" + prefix + "objects` AS j2 ON " + prefix + "edges.other_id = j2.id "
+ "WHERE " + prefix + "edges.id = @id@ OR other_id = @id@";
+
+ query.SetValue("type", object->GetSerializableType()->GetName());
+ query.SetValue("id", object->id);
+ if (type)
+ query.SetValue("other_type", type->GetName());
+
+ Result res = Run(query);
+ for (int i = 0; i < res.Rows(); ++i)
+ {
+ Serialize::ID id = convertTo<Serialize::ID>(res.Get(i, "id")); // object edge is on
+
+ if (id == object->id)
+ {
+ // we want other type, this is my edge
+ Anope::string t = res.Get(i, "other_type");
+ Anope::string f = res.Get(i, "field");
+ id = convertTo<Serialize::ID>(res.Get(i, "other_id"));
+
+ Serialize::FieldBase *obj_field = object->GetSerializableType()->GetField(f);
+ if (obj_field == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to find field " << f << " on " << object->GetSerializableType()->GetName();
+ continue;
+ }
+
+ Serialize::TypeBase *obj_type = Serialize::TypeBase::Find(t);
+ if (obj_type == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to find type " << t;
+ continue;
+ }
+
+ Serialize::Object *other = obj_type->Require(id);
+ if (other == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to require id " << id << " type " << obj_type->GetName();
+ continue;
+ }
+
+ edges.emplace_back(other, obj_field, true);
+ }
+ else
+ {
+ // edge to me
+ Anope::string t = res.Get(i, "type");
+ Anope::string f = res.Get(i, "field");
+
+ Serialize::TypeBase *obj_type = Serialize::TypeBase::Find(t);
+ if (obj_type == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to find type " << t;
+ continue;
+ }
+
+ Serialize::FieldBase *obj_field = obj_type->GetField(f);
+ if (obj_field == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to find field " << f << " on " << obj_type->GetName();
+ continue;
+ }
+
+ Serialize::Object *other = obj_type->Require(id);
+ if (other == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to require id " << id << " type " << obj_type->GetName();
+ continue;
+ }
+
+ // other type, other field,
+ edges.emplace_back(other, obj_field, false);
+ }
+ }
+
+ return EVENT_ALLOW;
+ }
+
+ EventReturn OnSerializeDeref(Serialize::ID id, Serialize::TypeBase *type) override
+ {
+ StartTransaction();
+
+ Query query = "SELECT `id` FROM `" + prefix + type->GetName() + "` WHERE `id` = @id@";
+ query.SetValue("id", id);
+ Result res = Run(query);
+ if (res.Rows() == 0)
+ return EVENT_CONTINUE;
+ return EVENT_ALLOW;
+ }
+
+ EventReturn OnSerializeGetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &type, Serialize::ID &value) override
+ {
+ StartTransaction();
+
+ Query query = "SELECT `" + field->serialize_name + "`,j1.type AS " + field->serialize_name + "_type FROM `" + prefix + object->GetSerializableType()->GetName() + "` "
+ "JOIN `" + prefix + "objects` AS j1 ON " + prefix + object->GetSerializableType()->GetName() + "." + field->serialize_name + " = j1.id "
+ "WHERE " + prefix + object->GetSerializableType()->GetName() + ".id = @id@";
+ query.SetValue("id", object->id);
+ Result res = Run(query);
+
+ if (res.Rows() == 0)
+ return EVENT_CONTINUE;
+
+ type = res.Get(0, field->serialize_name + "_type");
+ try
+ {
+ value = convertTo<Serialize::ID>(res.Get(0, field->serialize_name));
+ }
+ catch (const ConvertException &ex)
+ {
+ return EVENT_STOP;
+ }
+
+ return EVENT_ALLOW;
+ }
+
+ private:
+ void DoSet(Serialize::Object *object, Serialize::FieldBase *field, bool is_object, const Anope::string *value)
+ {
+ if (!SQL)
+ return;
+
+ StartTransaction();
+
+ for (Query &q : SQL->CreateTable(prefix, object->GetSerializableType()->GetName()))
+ Run(q);
+
+ for (Query &q : SQL->AlterTable(prefix, object->GetSerializableType()->GetName(), field->serialize_name, is_object))
+ Run(q);
+
+ Query q;
+ q.SetValue("id", object->id);
+ if (value)
+ q.SetValue(field->serialize_name, *value);
+ else
+ q.SetNull(field->serialize_name);
+
+ for (Query &q2 : SQL->Replace(prefix + object->GetSerializableType()->GetName(), q, { "id" }))
+ Run(q2);
+ }
+
+ public:
+ EventReturn OnSerializeSet(Serialize::Object *object, Serialize::FieldBase *field, const Anope::string &value) override
+ {
+ DoSet(object, field, false, &value);
+ return EVENT_STOP;
+ }
+
+ EventReturn OnSerializeSetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Serialize::Object *value) override
+ {
+ if (!SQL)
+ return EVENT_CONTINUE;
+
+ StartTransaction();
+
+ if (value)
+ {
+ Anope::string v = stringify(value->id);
+ DoSet(object, field, true, &v);
+
+ Query query;
+ query.SetValue("field", field->serialize_name);
+ query.SetValue("id", object->id);
+ query.SetValue("other_id", value->id);
+
+ for (Query &q : SQL->Replace(prefix + "edges", query, { "id", "field" }))
+ Run(q);
+ }
+ else
+ {
+ DoSet(object, field, true, nullptr);
+
+ Query query("DELETE FROM `" + prefix + "edges` WHERE `id` = @id@ AND `field` = @field@");
+ query.SetValue("id", object->id);
+ query.SetValue("field", field->serialize_name);
+ Run(query);
+ }
+
+ return EVENT_STOP;
+ }
+
+ EventReturn OnSerializeUnset(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ DoSet(object, field, false, nullptr);
+ return EVENT_STOP;
+ }
+
+ EventReturn OnSerializeUnsetSerializable(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ DoSet(object, field, true, nullptr);
+
+ Query query("DELETE FROM `" + prefix + "edges` WHERE `id` = @id@ AND `field` = @field@");
+ query.SetValue("id", object->id);
+ query.SetValue("field", field->serialize_name);
+ Run(query);
+
+ return EVENT_STOP;
+ }
+
+ EventReturn OnSerializeHasField(Serialize::Object *object, Serialize::FieldBase *field) override
+ {
+ SQL::Result::Value v;
+
+ return GetValue(object, field, v) && !v.null ? EVENT_STOP : EVENT_CONTINUE;
+ }
+
+ EventReturn OnSerializableGetId(Serialize::ID &id) override
+ {
+ if (!SQL)
+ return EVENT_CONTINUE;
+
+ StartTransaction();
+
+ id = SQL->GetID(prefix);
+ return EVENT_ALLOW;
+ }
+
+ void OnSerializableCreate(Serialize::Object *object) override
+ {
+ StartTransaction();
+
+ Query q = Query("INSERT INTO `" + prefix + "objects` (`id`,`type`) VALUES (@id@, @type@)");
+ q.SetValue("id", object->id);
+ q.SetValue("type", object->GetSerializableType()->GetName());
+ Run(q);
+ }
+
+ void OnSerializableDelete(Serialize::Object *object) override
+ {
+ StartTransaction();
+
+ Query query("DELETE FROM `" + prefix + object->GetSerializableType()->GetName() + "` WHERE `id` = " + stringify(object->id));
+ Run(query);
+ }
+};
+
+MODULE_INIT(DBMySQL)
+
diff --git a/modules/m_dns.cpp b/modules/dns.cpp
index 93f09246e..523b4044d 100644
--- a/modules/m_dns.cpp
+++ b/modules/dns.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -109,7 +117,7 @@ class Packet : public Query
return name;
}
-
+
Question UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos)
{
Question question;
@@ -212,7 +220,7 @@ class Packet : public Query
unsigned short id;
/* Flags on the packet */
unsigned short flags;
-
+
Packet(Manager *m, sockaddrs *a) : manager(m), id(0), flags(0)
{
if (a)
@@ -248,7 +256,7 @@ class Packet : public Query
for (unsigned i = 0; i < qdcount; ++i)
this->questions.push_back(this->UnpackQuestion(input, len, packet_pos));
-
+
for (unsigned i = 0; i < ancount; ++i)
this->answers.push_back(this->UnpackResourceRecord(input, len, packet_pos));
@@ -270,7 +278,7 @@ class Packet : public Query
{
if (output_size < HEADER_LENGTH)
throw SocketException("Unable to pack packet");
-
+
unsigned short pos = 0;
output[pos++] = this->id >> 8;
@@ -433,7 +441,7 @@ class Packet : public Query
l = htonl(manager->GetSerial());
memcpy(&output[pos], &l, 4);
pos += 4;
-
+
l = htonl(refresh); // Refresh
memcpy(&output[pos], &l, 4);
pos += 4;
@@ -459,7 +467,7 @@ class Packet : public Query
break;
}
}
-
+
return pos;
}
};
@@ -478,7 +486,7 @@ namespace DNS
class TCPSocket : public ListenSocket
{
Manager *manager;
-
+
public:
/* A TCP client */
class Client : public ClientSocket, public Timer, public ReplySocket
@@ -487,7 +495,7 @@ class TCPSocket : public ListenSocket
Packet *packet;
unsigned char packet_buffer[524];
int length;
-
+
public:
Client(Manager *m, TCPSocket *l, int fd, const sockaddrs &addr) : Socket(fd, l->IsIPv6()), ClientSocket(l, addr), Timer(5),
manager(m), packet(NULL), length(0)
@@ -500,18 +508,18 @@ class TCPSocket : public ListenSocket
Log(LOG_DEBUG_2) << "Resolver: Exiting client from " << clientaddr.addr();
delete packet;
}
-
+
/* Times out after a few seconds */
- void Tick(time_t) anope_override { }
+ void Tick(time_t) override { }
- void Reply(Packet *p) anope_override
+ void Reply(Packet *p) override
{
delete packet;
packet = p;
SocketEngine::Change(this, true, SF_WRITABLE);
}
- bool ProcessRead() anope_override
+ bool ProcessRead() override
{
Log(LOG_DEBUG_2) << "Resolver: Reading from DNS TCP socket";
@@ -531,7 +539,7 @@ class TCPSocket : public ListenSocket
return true;
}
- bool ProcessWrite() anope_override
+ bool ProcessWrite() override
{
Log(LOG_DEBUG_2) << "Resolver: Writing to DNS TCP socket";
@@ -560,13 +568,13 @@ class TCPSocket : public ListenSocket
};
TCPSocket(Manager *m, const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos), ListenSocket(ip, port, ip.find(':') != Anope::string::npos), manager(m) { }
-
- ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_override
+
+ ClientSocket *OnAccept(int fd, const sockaddrs &addr) override
{
return new Client(this->manager, this, fd, addr);
}
};
-
+
/* Listens for UDP requests */
class UDPSocket : public ReplySocket
{
@@ -581,16 +589,16 @@ class UDPSocket : public ReplySocket
for (unsigned i = 0; i < packets.size(); ++i)
delete packets[i];
}
-
- void Reply(Packet *p) anope_override
+
+ void Reply(Packet *p) override
{
packets.push_back(p);
SocketEngine::Change(this, true, SF_WRITABLE);
}
-
+
std::deque<Packet *>& GetPackets() { return packets; }
-
- bool ProcessRead() anope_override
+
+ bool ProcessRead() override
{
Log(LOG_DEBUG_2) << "Resolver: Reading from DNS UDP socket";
@@ -600,8 +608,8 @@ class UDPSocket : public ReplySocket
int length = recvfrom(this->GetFD(), reinterpret_cast<char *>(&packet_buffer), sizeof(packet_buffer), 0, &from_server.sa, &x);
return this->manager->HandlePacket(this, packet_buffer, length, &from_server);
}
-
- bool ProcessWrite() anope_override
+
+ bool ProcessWrite() override
{
Log(LOG_DEBUG_2) << "Resolver: Writing to DNS UDP socket";
@@ -623,7 +631,7 @@ class UDPSocket : public ReplySocket
if (packets.empty())
SocketEngine::Change(this, false, SF_WRITABLE);
-
+
return true;
}
};
@@ -638,7 +646,7 @@ class NotifySocket : public Socket
SocketEngine::Change(this, true, SF_WRITABLE);
}
- bool ProcessWrite() anope_override
+ bool ProcessWrite() override
{
if (!packet)
return false;
@@ -665,7 +673,7 @@ class MyManager : public Manager, public Timer
{
uint32_t serial;
- typedef TR1NS::unordered_map<Question, Query, Question::hash> cache_map;
+ typedef std::unordered_map<Question, Query, Question::hash> cache_map;
cache_map cache;
TCPSocket *tcpsock;
@@ -689,7 +697,7 @@ class MyManager : public Manager, public Timer
delete tcpsock;
for (std::map<unsigned short, Request *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end;)
- {
+ {
Request *request = it->second;
++it;
@@ -749,7 +757,7 @@ class MyManager : public Manager, public Timer
}
public:
- void Process(Request *req) anope_override
+ void Process(Request *req) override
{
Log(LOG_DEBUG_2) << "Resolver: Processing request to lookup " << req->name << ", of type " << req->type;
@@ -767,7 +775,7 @@ class MyManager : public Manager, public Timer
this->requests[req->id] = req;
req->SetSecs(timeout);
-
+
Packet *p = new Packet(this, &this->addrs);
p->flags = QUERYFLAGS_RD;
p->id = req->id;
@@ -776,12 +784,12 @@ class MyManager : public Manager, public Timer
this->udpsock->Reply(p);
}
- void RemoveRequest(Request *req) anope_override
+ void RemoveRequest(Request *req) override
{
this->requests.erase(req->id);
}
- bool HandlePacket(ReplySocket *s, const unsigned char *const packet_buffer, int length, sockaddrs *from) anope_override
+ bool HandlePacket(ReplySocket *s, const unsigned char *const packet_buffer, int length, sockaddrs *from) override
{
if (length < Packet::HEADER_LENGTH)
return true;
@@ -840,7 +848,7 @@ class MyManager : public Manager, public Timer
}
}
- FOREACH_MOD(OnDnsRequest, (recv_packet, packet));
+ EventManager::Get()->Dispatch(&Event::DnsRequest::OnDnsRequest, recv_packet, packet);
for (unsigned i = 0; i < recv_packet.questions.size(); ++i)
{
@@ -928,17 +936,17 @@ class MyManager : public Manager, public Timer
request->OnLookupComplete(&recv_packet);
this->AddCache(recv_packet);
}
-
+
delete request;
return true;
}
- void UpdateSerial() anope_override
+ void UpdateSerial() override
{
serial = Anope::CurTime;
}
- void Notify(const Anope::string &zone) anope_override
+ void Notify(const Anope::string &zone) override
{
/* notify slaves of the update */
for (unsigned i = 0; i < notify.size(); ++i)
@@ -969,12 +977,12 @@ class MyManager : public Manager, public Timer
}
}
- uint32_t GetSerial() const anope_override
+ uint32_t GetSerial() const override
{
return serial;
}
- void Tick(time_t now) anope_override
+ void Tick(time_t now) override
{
Log(LOG_DEBUG_2) << "Resolver: Purging DNS cache";
@@ -989,7 +997,7 @@ class MyManager : public Manager, public Timer
this->cache.erase(it);
}
}
-
+
private:
/** Add a record to the dns cache
* @param r The record
@@ -1017,10 +1025,11 @@ class MyManager : public Manager, public Timer
return false;
}
-
+
};
class ModuleDNS : public Module
+ , public EventHook<Event::ModuleUnload>
{
MyManager manager;
@@ -1031,7 +1040,9 @@ class ModuleDNS : public Module
std::vector<std::pair<Anope::string, short> > notify;
public:
- ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), manager(this)
+ ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::ModuleUnload>(this)
+ , manager(this)
{
}
@@ -1048,16 +1059,16 @@ class ModuleDNS : public Module
}
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
- nameserver = block->Get<const Anope::string>("nameserver", "127.0.0.1");
+ nameserver = block->Get<Anope::string>("nameserver", "127.0.0.1");
timeout = block->Get<time_t>("timeout", "5");
- ip = block->Get<const Anope::string>("ip", "0.0.0.0");
+ ip = block->Get<Anope::string>("ip", "0.0.0.0");
port = block->Get<int>("port", "53");
- admin = block->Get<const Anope::string>("admin", "admin@example.com");
- nameservers = block->Get<const Anope::string>("nameservers", "ns1.example.com");
+ admin = block->Get<Anope::string>("admin", "admin@example.com");
+ nameservers = block->Get<Anope::string>("nameservers", "ns1.example.com");
refresh = block->Get<int>("refresh", "3600");
for (int i = 0; i < block->CountBlock("notify"); ++i)
@@ -1114,7 +1125,7 @@ class ModuleDNS : public Module
}
}
- void OnModuleUnload(User *u, Module *m) anope_override
+ void OnModuleUnload(User *u, Module *m) override
{
for (std::map<unsigned short, Request *>::iterator it = this->manager.requests.begin(), it_end = this->manager.requests.end(); it != it_end;)
{
diff --git a/modules/m_dnsbl.cpp b/modules/dnsbl.cpp
index aa24e5ba6..a2c8a4380 100644
--- a/modules/m_dnsbl.cpp
+++ b/modules/dnsbl.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -11,9 +22,6 @@
using namespace DNS;
-static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
-static ServiceReference<Manager> dnsmanager("DNS::Manager", "dns/manager");
-
struct Blacklist
{
struct Reply
@@ -43,14 +51,15 @@ struct Blacklist
class DNSBLResolver : public Request
{
+ ServiceReference<XLineManager> &akills;
Reference<User> user;
Blacklist blacklist;
bool add_to_akill;
public:
- DNSBLResolver(Module *c, User *u, const Blacklist &b, const Anope::string &host, bool add_akill) : Request(dnsmanager, c, host, QUERY_A, true), user(u), blacklist(b), add_to_akill(add_akill) { }
+ DNSBLResolver(ServiceReference<XLineManager> &a, Module *c, DNS::Manager *manager, User *u, const Blacklist &b, const Anope::string &host, bool add_akill) : Request(manager, c, host, QUERY_A, true), akills(a), user(u), blacklist(b), add_to_akill(add_akill) { }
- void OnLookupComplete(const Query *record) anope_override
+ void OnLookupComplete(const Query *record) override
{
if (!user || user->Quitting())
return;
@@ -78,11 +87,19 @@ class DNSBLResolver : public Request
reason = reason.replace_all_cs("%h", user->host);
reason = reason.replace_all_cs("%i", addr);
reason = reason.replace_all_cs("%r", reply ? reply->reason : "");
- reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
+ reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
- BotInfo *OperServ = Config->GetClient("OperServ");
+ ServiceBot *OperServ = Config->GetClient("OperServ");
Log(creator, "dnsbl", OperServ) << user->GetMask() << " (" << addr << ") appears in " << this->blacklist.name;
- XLine *x = new XLine("*@" + addr, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID());
+
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask("*@" + addr);
+ x->SetBy(OperServ ? OperServ->nick : "m_dnsbl");
+ x->SetCreated(Anope::CurTime);
+ x->SetExpires(Anope::CurTime + this->blacklist.bantime);
+ x->SetReason(reason);
+ x->SetID(XLineManager::GenerateUID());
+
if (this->add_to_akill && akills)
{
akills->AddXLine(x);
@@ -97,20 +114,25 @@ class DNSBLResolver : public Request
};
class ModuleDNSBL : public Module
+ , public EventHook<Event::UserConnect>
{
+ ServiceReference<DNS::Manager> manager;
std::vector<Blacklist> blacklists;
std::set<Anope::string> exempts;
bool check_on_connect;
bool check_on_netburst;
bool add_to_akill;
+ ServiceReference<XLineManager> akill;
public:
ModuleDNSBL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA)
+ , EventHook<Event::UserConnect>(this)
+ , akill("sgline")
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
this->check_on_connect = block->Get<bool>("check_on_connect");
@@ -149,9 +171,9 @@ class ModuleDNSBL : public Module
this->exempts.insert(block->Get<Anope::string>("ip"));
}
- void OnUserConnect(User *user, bool &exempt) anope_override
+ void OnUserConnect(User *user, bool &exempt) override
{
- if (exempt || user->Quitting() || (!this->check_on_connect && !Me->IsSynced()) || !dnsmanager)
+ if (exempt || user->Quitting() || (!this->check_on_connect && !Me->IsSynced()) || !manager)
return;
if (!this->check_on_netburst && !user->server->IsSynced())
@@ -179,8 +201,8 @@ class ModuleDNSBL : public Module
DNSBLResolver *res = NULL;
try
{
- res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill);
- dnsmanager->Process(res);
+ res = new DNSBLResolver(akill, this, manager, user, b, dnsbl_host, this->add_to_akill);
+ manager->Process(res);
}
catch (const SocketException &ex)
{
diff --git a/modules/encryption/CMakeLists.txt b/modules/encryption/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/encryption/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/encryption/enc_bcrypt.cpp b/modules/encryption/bcrypt.cpp
index a30b925b0..622fef745 100644
--- a/modules/encryption/enc_bcrypt.cpp
+++ b/modules/encryption/bcrypt.cpp
@@ -1,11 +1,23 @@
-/* Module for providing bcrypt hashing
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * This program is free but copyrighted software; see the file COPYING for
- * details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/*
* Most of the code in this file is taken from
* http://openwall.com/crypt/crypt_blowfish-1.2.tar.gz
*/
@@ -839,8 +851,11 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
#include "module.h"
#include "modules/encryption.h"
+#include "modules/nickserv.h"
class EBCRYPT : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
{
unsigned int rounds;
@@ -873,8 +888,10 @@ class EBCRYPT : public Module
}
public:
- EBCRYPT(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR),
- rounds(10)
+ EBCRYPT(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ , rounds(10)
{
// Test a pre-calculated hash
bool test = Compare("Test!", "$2a$10$x9AQFAQScY0v9KF2suqkEOepsHFrG.CXHbIXI.1F28SfSUb56A/7K");
@@ -886,28 +903,28 @@ class EBCRYPT : public Module
throw ModuleException("BCrypt could not load!");
}
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
{
dest = "bcrypt:" + Generate(src, Salt());
Log(LOG_DEBUG_2) << "(enc_bcrypt) hashed password from [" << src << "] to [" << dest << "]";
return EVENT_ALLOW;
}
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
{
- const NickAlias *na = NickAlias::Find(req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
if (na == NULL)
return;
- NickCore *nc = na->nc;
+ NickServ::Account *nc = na->GetAccount();
- size_t pos = nc->pass.find(':');
+ size_t pos = nc->GetPassword().find(':');
if (pos == Anope::string::npos)
return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ Anope::string hash_method(nc->GetPassword().begin(), nc->GetPassword().begin() + pos);
if (hash_method != "bcrypt")
return;
- if (Compare(req->GetPassword(), nc->pass.substr(7)))
+ if (Compare(req->GetPassword(), nc->GetPassword().substr(7)))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
@@ -916,24 +933,28 @@ class EBCRYPT : public Module
unsigned int hashrounds = 0;
try
{
- size_t roundspos = nc->pass.find('$', 11);
+ size_t roundspos = nc->GetPassword().find('$', 11);
if (roundspos == Anope::string::npos)
throw ConvertException("Could not find hashrounds");
- hashrounds = convertTo<unsigned int>(nc->pass.substr(11, roundspos - 11));
+ hashrounds = convertTo<unsigned int>(nc->GetPassword().substr(11, roundspos - 11));
}
catch (const ConvertException &)
{
- Log(this) << "Could not get the round size of a hash. This is probably a bug. Hash: " << nc->pass;
+ Log(this) << "Could not get the round size of a hash. This is probably a bug. Hash: " << nc->GetPassword();
}
if (ModuleManager::FindFirstOf(ENCRYPTION) != this || (hashrounds && hashrounds != rounds))
- Anope::Encrypt(req->GetPassword(), nc->pass);
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
req->Success(this);
}
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
rounds = block->Get<unsigned int>("rounds", "10");
diff --git a/modules/encryption/enc_none.cpp b/modules/encryption/enc_none.cpp
deleted file mode 100644
index 0302316f7..000000000
--- a/modules/encryption/enc_none.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Module for plain text encryption.
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * This program is free but copyrighted software; see the file COPYING for
- * details.
- */
-
-#include "module.h"
-
-class ENone : public Module
-{
- public:
- ENone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
- {
-
- }
-
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
- {
- Anope::string buf = "plain:";
- Anope::string cpass;
- Anope::B64Encode(src, cpass);
- buf += cpass;
- Log(LOG_DEBUG_2) << "(enc_none) hashed password from [" << src << "] to [" << buf << "]";
- dest = buf;
- return EVENT_ALLOW;
- }
-
- EventReturn OnDecrypt(const Anope::string &hashm, const Anope::string &src, Anope::string &dest) anope_override
- {
- if (!hashm.equals_cs("plain"))
- return EVENT_CONTINUE;
- size_t pos = src.find(':');
- Anope::string buf = src.substr(pos + 1);
- Anope::B64Decode(buf, dest);
- return EVENT_ALLOW;
- }
-
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
- {
- const NickAlias *na = NickAlias::Find(req->GetAccount());
- if (na == NULL)
- return;
- NickCore *nc = na->nc;
-
- size_t pos = nc->pass.find(':');
- if (pos == Anope::string::npos)
- return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
- if (!hash_method.equals_cs("plain"))
- return;
-
- Anope::string buf;
- this->OnEncrypt(req->GetPassword(), buf);
- if (nc->pass.equals_cs(buf))
- {
- /* if we are NOT the first module in the list,
- * we want to re-encrypt the pass with the new encryption
- */
- if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
- Anope::Encrypt(req->GetPassword(), nc->pass);
- req->Success(this);
- }
- }
-};
-
-MODULE_INIT(ENone)
diff --git a/modules/encryption/enc_md5.cpp b/modules/encryption/md5.cpp
index 1dab95f0b..ca3bfcc9a 100644
--- a/modules/encryption/enc_md5.cpp
+++ b/modules/encryption/md5.cpp
@@ -1,14 +1,26 @@
-/* Module for encryption using MD5.
+/*
+ * Anope IRC Services
*
- * Modified for Anope.
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2006-2016 Anope Team <team@anope.org>
*
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/*
* Taken from IRC Services and is copyright (c) 1996-2002 Andrew Church.
* E-mail: <achurch@achurch.org>
* Parts written by Andrew Kempe and others.
- * This program is free but copyrighted software; see the file COPYING for
- * details.
*/
#include "module.h"
@@ -250,7 +262,7 @@ class MD5Context : public Encryption::Context
* operation, processing another message block, and updating the
* context.
*/
- void Update(const unsigned char *input, size_t len) anope_override
+ void Update(const unsigned char *input, size_t len) override
{
unsigned i, index, partLen;
@@ -284,8 +296,8 @@ class MD5Context : public Encryption::Context
/* MD5 finalization. Ends an MD5 message-digest opera
* the message digest and zeroizing the context.
- */
- void Finalize() anope_override
+ */
+ void Finalize() override
{
unsigned char bits[8];
unsigned index, padLen;
@@ -309,7 +321,7 @@ class MD5Context : public Encryption::Context
memset(this->buffer, 0, sizeof(this->buffer));
}
- Encryption::Hash GetFinalizedHash() anope_override
+ Encryption::Hash GetFinalizedHash() override
{
Encryption::Hash hash;
hash.first = this->digest;
@@ -323,12 +335,12 @@ class MD5Provider : public Encryption::Provider
public:
MD5Provider(Module *creator) : Encryption::Provider(creator, "md5") { }
- Encryption::Context *CreateContext(Encryption::IV *iv) anope_override
+ Encryption::Context *CreateContext(Encryption::IV *iv) override
{
return new MD5Context(iv);
}
- Encryption::IV GetDefaultIV() anope_override
+ Encryption::IV GetDefaultIV() override
{
Encryption::IV iv;
iv.first = md5_iv;
@@ -338,17 +350,22 @@ class MD5Provider : public Encryption::Provider
};
class EMD5 : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
{
MD5Provider md5provider;
public:
- EMD5(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR),
- md5provider(this)
+ EMD5(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ , md5provider(this)
{
-
+ if (ModuleManager::FindFirstOf(ENCRYPTION) == this)
+ throw ModuleException("enc_md5 is deprecated and can not be used as a primary encryption method");
}
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
{
MD5Context context;
@@ -364,29 +381,33 @@ class EMD5 : public Module
return EVENT_ALLOW;
}
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
{
- const NickAlias *na = NickAlias::Find(req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
if (na == NULL)
return;
- NickCore *nc = na->nc;
+ NickServ::Account *nc = na->GetAccount();
- size_t pos = nc->pass.find(':');
+ size_t pos = nc->GetPassword().find(':');
if (pos == Anope::string::npos)
return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ Anope::string hash_method(nc->GetPassword().begin(), nc->GetPassword().begin() + pos);
if (!hash_method.equals_cs("md5"))
return;
Anope::string buf;
this->OnEncrypt(req->GetPassword(), buf);
- if (nc->pass.equals_cs(buf))
+ if (nc->GetPassword().equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
- Anope::Encrypt(req->GetPassword(), nc->pass);
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
req->Success(this);
}
}
diff --git a/modules/encryption/none.cpp b/modules/encryption/none.cpp
new file mode 100644
index 000000000..3b1f49d33
--- /dev/null
+++ b/modules/encryption/none.cpp
@@ -0,0 +1,78 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2006-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class ENone : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
+{
+ public:
+ ENone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ {
+ if (ModuleManager::FindFirstOf(ENCRYPTION) == this)
+ throw ModuleException("enc_none is deprecated and can not be used as a primary encryption method");
+ }
+
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
+ {
+ Anope::string buf = "plain:";
+ Anope::string cpass;
+ Anope::B64Encode(src, cpass);
+ buf += cpass;
+ Log(LOG_DEBUG_2) << "(enc_none) hashed password from [" << src << "] to [" << buf << "]";
+ dest = buf;
+ return EVENT_ALLOW;
+ }
+
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
+ {
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
+ if (na == NULL)
+ return;
+ NickServ::Account *nc = na->GetAccount();
+
+ size_t pos = nc->GetPassword().find(':');
+ if (pos == Anope::string::npos)
+ return;
+ Anope::string hash_method(nc->GetPassword().begin(), nc->GetPassword().begin() + pos);
+ if (!hash_method.equals_cs("plain"))
+ return;
+
+ Anope::string buf;
+ this->OnEncrypt(req->GetPassword(), buf);
+ if (nc->GetPassword().equals_cs(buf))
+ {
+ /* if we are NOT the first module in the list,
+ * we want to re-encrypt the pass with the new encryption
+ */
+ if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
+ req->Success(this);
+ }
+ }
+};
+
+MODULE_INIT(ENone)
diff --git a/modules/encryption/enc_old.cpp b/modules/encryption/old.cpp
index 7c751df93..bfe7131bc 100644
--- a/modules/encryption/enc_old.cpp
+++ b/modules/encryption/old.cpp
@@ -1,32 +1,43 @@
-/* Include file for high-level encryption routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
#include "modules/encryption.h"
-static ServiceReference<Encryption::Provider> md5("Encryption::Provider", "md5");
-
class OldMD5Provider : public Encryption::Provider
{
+ ServiceReference<Encryption::Provider> md5;
+
public:
- OldMD5Provider(Module *creator) : Encryption::Provider(creator, "oldmd5") { }
+ OldMD5Provider(Module *creator) : Encryption::Provider(creator, "oldmd5")
+ , md5("md5")
+ {
+ }
- Encryption::Context *CreateContext(Encryption::IV *iv) anope_override
+ Encryption::Context *CreateContext(Encryption::IV *iv) override
{
if (md5)
return md5->CreateContext(iv);
return NULL;
}
- Encryption::IV GetDefaultIV() anope_override
+ Encryption::IV GetDefaultIV() override
{
if (md5)
return md5->GetDefaultIV();
@@ -35,15 +46,23 @@ class OldMD5Provider : public Encryption::Provider
};
class EOld : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
{
OldMD5Provider oldmd5provider;
+ ServiceReference<Encryption::Provider> md5;
inline static char XTOI(char c) { return c > 9 ? c - 'A' + 10 : c - '0'; }
public:
- EOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR),
- oldmd5provider(this)
+ EOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ , oldmd5provider(this)
+ , md5("md5")
{
+ if (ModuleManager::FindFirstOf(ENCRYPTION) == this)
+ throw ModuleException("enc_old is deprecated and can not be used as a primary encryption method");
ModuleManager::LoadModule("enc_md5", User::Find(creator));
if (!md5)
@@ -51,7 +70,7 @@ class EOld : public Module
}
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
{
if (!md5)
return EVENT_CONTINUE;
@@ -79,29 +98,33 @@ class EOld : public Module
return EVENT_ALLOW;
}
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
{
- const NickAlias *na = NickAlias::Find(req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
if (na == NULL)
return;
- NickCore *nc = na->nc;
+ NickServ::Account *nc = na->GetAccount();
- size_t pos = nc->pass.find(':');
+ size_t pos = nc->GetPassword().find(':');
if (pos == Anope::string::npos)
return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ Anope::string hash_method(nc->GetPassword().begin(), nc->GetPassword().begin() + pos);
if (!hash_method.equals_cs("oldmd5"))
return;
Anope::string buf;
this->OnEncrypt(req->GetPassword(), buf);
- if (nc->pass.equals_cs(buf))
+ if (nc->GetPassword().equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
- Anope::Encrypt(req->GetPassword(), nc->pass);
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
req->Success(this);
}
}
diff --git a/modules/encryption/enc_sha1.cpp b/modules/encryption/sha1.cpp
index b9782bc34..ea108f49c 100644
--- a/modules/encryption/enc_sha1.cpp
+++ b/modules/encryption/sha1.cpp
@@ -1,9 +1,23 @@
/*
+ * Anope IRC Services
*
- * Modified for Anope.
- * (C) 2006-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2006-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
@@ -125,7 +139,7 @@ class SHA1Context : public Encryption::Context
memset(this->digest, 0, sizeof(this->digest));
}
- void Update(const unsigned char *data, size_t len) anope_override
+ void Update(const unsigned char *data, size_t len) override
{
uint32_t i, j;
@@ -146,7 +160,7 @@ class SHA1Context : public Encryption::Context
memcpy(&this->buffer[j], &data[i], len - i);
}
- void Finalize() anope_override
+ void Finalize() override
{
uint32_t i;
unsigned char finalcount[8];
@@ -169,7 +183,7 @@ class SHA1Context : public Encryption::Context
this->Transform(this->buffer);
}
- Encryption::Hash GetFinalizedHash() anope_override
+ Encryption::Hash GetFinalizedHash() override
{
Encryption::Hash hash;
hash.first = this->digest;
@@ -183,12 +197,12 @@ class SHA1Provider : public Encryption::Provider
public:
SHA1Provider(Module *creator) : Encryption::Provider(creator, "sha1") { }
- Encryption::Context *CreateContext(Encryption::IV *iv) anope_override
+ Encryption::Context *CreateContext(Encryption::IV *iv) override
{
return new SHA1Context(iv);
}
- Encryption::IV GetDefaultIV() anope_override
+ Encryption::IV GetDefaultIV() override
{
Encryption::IV iv;
iv.first = sha1_iv;
@@ -198,17 +212,22 @@ class SHA1Provider : public Encryption::Provider
};
class ESHA1 : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
{
SHA1Provider sha1provider;
public:
- ESHA1(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR),
- sha1provider(this)
+ ESHA1(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ , sha1provider(this)
{
-
+ if (ModuleManager::FindFirstOf(ENCRYPTION) == this)
+ throw ModuleException("enc_sha1 is deprecated and can not be used as a primary encryption method");
}
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
{
SHA1Context context;
@@ -224,26 +243,30 @@ class ESHA1 : public Module
return EVENT_ALLOW;
}
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
{
- const NickAlias *na = NickAlias::Find(req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
if (na == NULL)
return;
- NickCore *nc = na->nc;
+ NickServ::Account *nc = na->GetAccount();
- size_t pos = nc->pass.find(':');
+ size_t pos = nc->GetPassword().find(':');
if (pos == Anope::string::npos)
return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ Anope::string hash_method(nc->GetPassword().begin(), nc->GetPassword().begin() + pos);
if (!hash_method.equals_cs("sha1"))
return;
Anope::string buf;
this->OnEncrypt(req->GetPassword(), buf);
- if (nc->pass.equals_cs(buf))
+ if (nc->GetPassword().equals_cs(buf))
{
if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
- Anope::Encrypt(req->GetPassword(), nc->pass);
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
req->Success(this);
}
}
diff --git a/modules/encryption/enc_sha256.cpp b/modules/encryption/sha256.cpp
index 4f111da34..e05629a50 100644
--- a/modules/encryption/enc_sha256.cpp
+++ b/modules/encryption/sha256.cpp
@@ -1,18 +1,20 @@
-/* This module generates and compares password hashes using SHA256 algorithms.
+/*
+ * Anope IRC Services
*
- * If an intruder gets access to your system or uses a brute force attack,
- * salt will not provide much value.
- * IMPORTANT: DATA HASHES CANNOT BE "DECRYPTED" BACK TO PLAIN TEXT.
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Modified for Anope.
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Taken from InspIRCd ( www.inspircd.org )
- * see http://wiki.inspircd.org/Credits
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * This program is free but copyrighted software; see
- * the file COPYING for details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
/* FIPS 180-2 SHA-224/256/384/512 implementation
@@ -55,7 +57,6 @@ static const unsigned SHA256_BLOCK_SIZE = 512 / 8;
inline static uint32_t SHFR(uint32_t x, uint32_t n) { return x >> n; }
inline static uint32_t ROTR(uint32_t x, uint32_t n) { return (x >> n) | (x << ((sizeof(x) << 3) - n)); }
-inline static uint32_t ROTL(uint32_t x, uint32_t n) { return (x << n) | (x >> ((sizeof(x) << 3) - n)); }
inline static uint32_t CH(uint32_t x, uint32_t y, uint32_t z) { return (x & y) ^ (~x & z); }
inline static uint32_t MAJ(uint32_t x, uint32_t y, uint32_t z) { return (x & y) ^ (x & z) ^ (y & z); }
@@ -173,7 +174,7 @@ class SHA256Context : public Encryption::Context
memset(this->digest, 0, sizeof(this->digest));
}
- void Update(const unsigned char *message, size_t mlen) anope_override
+ void Update(const unsigned char *message, size_t mlen) override
{
unsigned tmp_len = SHA256_BLOCK_SIZE - this->len, rem_len = mlen < tmp_len ? mlen : tmp_len;
@@ -195,7 +196,7 @@ class SHA256Context : public Encryption::Context
this->tot_len += (block_nb + 1) << 6;
}
- void Finalize() anope_override
+ void Finalize() override
{
unsigned block_nb = 1 + ((SHA256_BLOCK_SIZE - 9) < (this->len % SHA256_BLOCK_SIZE));
unsigned len_b = (this->tot_len + this->len) << 3;
@@ -208,7 +209,7 @@ class SHA256Context : public Encryption::Context
UNPACK32(this->h[i], &this->digest[i << 2]);
}
- Encryption::Hash GetFinalizedHash() anope_override
+ Encryption::Hash GetFinalizedHash() override
{
Encryption::Hash hash;
hash.first = this->digest;
@@ -222,12 +223,12 @@ class SHA256Provider : public Encryption::Provider
public:
SHA256Provider(Module *creator) : Encryption::Provider(creator, "sha256") { }
- Encryption::Context *CreateContext(Encryption::IV *iv) anope_override
+ Encryption::Context *CreateContext(Encryption::IV *iv) override
{
return new SHA256Context(iv);
}
- Encryption::IV GetDefaultIV() anope_override
+ Encryption::IV GetDefaultIV() override
{
Encryption::IV iv;
iv.first = sha256_h0;
@@ -237,6 +238,8 @@ class SHA256Provider : public Encryption::Provider
};
class ESHA256 : public Module
+ , public EventHook<Event::Encrypt>
+ , public EventHook<Event::CheckAuthentication>
{
SHA256Provider sha256provider;
@@ -273,15 +276,17 @@ class ESHA256 : public Module
}
public:
- ESHA256(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR),
- sha256provider(this)
+ ESHA256(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR)
+ , EventHook<Event::Encrypt>(this)
+ , EventHook<Event::CheckAuthentication>(this)
+ , sha256provider(this)
{
use_iv = false;
}
- EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) anope_override
+ EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
{
if (!use_iv)
NewRandomIV();
@@ -302,31 +307,35 @@ class ESHA256 : public Module
return EVENT_ALLOW;
}
- void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *, NickServ::IdentifyRequest *req) override
{
- const NickAlias *na = NickAlias::Find(req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
if (na == NULL)
return;
- NickCore *nc = na->nc;
+ NickServ::Account *nc = na->GetAccount();
- size_t pos = nc->pass.find(':');
+ size_t pos = nc->GetPassword().find(':');
if (pos == Anope::string::npos)
return;
- Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ Anope::string hash_method(nc->GetPassword().substr(0, pos));
if (!hash_method.equals_cs("sha256"))
return;
- GetIVFromPass(nc->pass);
+ GetIVFromPass(nc->GetPassword());
use_iv = true;
Anope::string buf;
this->OnEncrypt(req->GetPassword(), buf);
- if (nc->pass.equals_cs(buf))
+ if (nc->GetPassword().equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (ModuleManager::FindFirstOf(ENCRYPTION) != this)
- Anope::Encrypt(req->GetPassword(), nc->pass);
+ {
+ Anope::string p;
+ Anope::Encrypt(req->GetPassword(), p);
+ nc->SetPassword(p);
+ }
req->Success(this);
}
}
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/ldap.cpp
index 27bb3ef50..6d4c0bd62 100644
--- a/modules/extra/m_ldap.cpp
+++ b/modules/extra/ldap.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
/* RequiredLibraries: ldap_r,lber */
@@ -270,18 +278,18 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
ldap_unbind_ext(this->con, NULL, NULL);
}
- void BindAsAdmin(LDAPInterface *i) anope_override
+ void BindAsAdmin(LDAPInterface *i) override
{
this->Bind(i, this->admin_binddn, this->admin_pass);
}
- void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) anope_override
+ void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) override
{
LDAPBind *b = new LDAPBind(this, i, who, pass);
QueueRequest(b);
}
- void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) anope_override
+ void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) override
{
if (i == NULL)
throw LDAPException("No interface");
@@ -290,7 +298,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
QueueRequest(s);
}
- void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) anope_override
+ void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) override
{
LDAPAdd *add = new LDAPAdd(this, i, dn, attributes);
QueueRequest(add);
@@ -430,6 +438,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
};
class ModuleLDAP : public Module, public Pipe
+ , public EventHook<Event::ModuleUnload>
{
std::map<Anope::string, LDAPService *> LDAPServices;
@@ -452,7 +461,7 @@ class ModuleLDAP : public Module, public Pipe
LDAPServices.clear();
}
- void OnReload(Configuration::Conf *config) anope_override
+ void OnReload(Configuration::Conf *config) override
{
Configuration::Block *conf = config->GetModule(this);
@@ -465,7 +474,7 @@ class ModuleLDAP : public Module, public Pipe
++it;
for (i = 0; i < conf->CountBlock("ldap"); ++i)
- if (conf->GetBlock("ldap", i)->Get<const Anope::string>("name", "ldap/main") == cname)
+ if (conf->GetBlock("ldap", i)->Get<Anope::string>("name", "ldap/main") == cname)
break;
if (i == conf->CountBlock("ldap"))
@@ -484,13 +493,13 @@ class ModuleLDAP : public Module, public Pipe
{
Configuration::Block *ldap = conf->GetBlock("ldap", i);
- const Anope::string &connname = ldap->Get<const Anope::string>("name", "ldap/main");
+ const Anope::string &connname = ldap->Get<Anope::string>("name", "ldap/main");
if (this->LDAPServices.find(connname) == this->LDAPServices.end())
{
- const Anope::string &server = ldap->Get<const Anope::string>("server", "127.0.0.1");
- const Anope::string &admin_binddn = ldap->Get<const Anope::string>("admin_binddn");
- const Anope::string &admin_password = ldap->Get<const Anope::string>("admin_password");
+ const Anope::string &server = ldap->Get<Anope::string>("server", "127.0.0.1");
+ const Anope::string &admin_binddn = ldap->Get<Anope::string>("admin_binddn");
+ const Anope::string &admin_password = ldap->GetAnope::string>("admin_password");
try
{
@@ -508,7 +517,7 @@ class ModuleLDAP : public Module, public Pipe
}
}
- void OnModuleUnload(User *, Module *m) anope_override
+ void OnModuleUnload(User *, Module *m) override
{
for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it)
{
@@ -545,7 +554,7 @@ class ModuleLDAP : public Module, public Pipe
}
}
- void OnNotify() anope_override
+ void OnNotify() override
{
for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it)
{
@@ -575,7 +584,7 @@ class ModuleLDAP : public Module, public Pipe
delete req;
}
- }
+ }
}
};
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/ldap_authentication.cpp
index 0f18916b6..ef61b6940 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/ldap_authentication.cpp
@@ -1,13 +1,25 @@
/*
+ * Anope IRC Services
*
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
#include "modules/ldap.h"
+#include "modules/nickserv.h"
static Module *me;
@@ -29,7 +41,7 @@ struct IdentifyInfo
{
req->Hold(me);
}
-
+
~IdentifyInfo()
{
req->Release(me);
@@ -53,7 +65,7 @@ class IdentifyInterface : public LDAPInterface
delete this;
}
- void OnResult(const LDAPResult &r) anope_override
+ void OnResult(const LDAPResult &r) override
{
if (!ii->lprov)
return;
@@ -99,20 +111,20 @@ class IdentifyInterface : public LDAPInterface
}
else
{
- NickAlias *na = NickAlias::Find(ii->req->GetAccount());
+ NickServ::Nick *na = NickServ::FindNick(ii->req->GetAccount());
if (na == NULL)
{
- na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount()));
- na->last_realname = ii->user ? ii->user->realname : ii->req->GetAccount();
- FOREACH_MOD(OnNickRegister, (ii->user, na, ii->req->GetPassword()));
- BotInfo *NickServ = Config->GetClient("NickServ");
+ na = new NickServ::Nick(ii->req->GetAccount(), new NickServ::Account(ii->req->GetAccount()));
+ na->SetLastRealname(ii->user ? ii->user->realname : ii->req->GetAccount());
+ NickServ::EventManager::Get()->Dispatch(&NickServ::Event::NickRegister::OnNickRegister, ii->user, na, ii->req->GetPassword());;
+ ServiceBot *NickServ = Config->GetClient("NickServ");
if (ii->user && NickServ)
- ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
+ ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->GetNick().c_str());
}
// encrypt and store the password in the nickcore
- Anope::Encrypt(ii->req->GetPassword(), na->nc->pass);
+ Anope::Encrypt(ii->req->GetPassword(), na->GetAccount()->pass);
- na->nc->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn);
+ na->GetAccount()->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn);
ii->req->Success(me);
}
break;
@@ -122,7 +134,7 @@ class IdentifyInterface : public LDAPInterface
}
}
- void OnError(const LDAPResult &r) anope_override
+ void OnError(const LDAPResult &r) override
{
}
};
@@ -139,7 +151,7 @@ class OnIdentifyInterface : public LDAPInterface
delete this;
}
- void OnResult(const LDAPResult &r) anope_override
+ void OnResult(const LDAPResult &r) override
{
User *u = User::Find(uid);
@@ -151,13 +163,13 @@ class OnIdentifyInterface : public LDAPInterface
const LDAPAttributes &attr = r.get(0);
Anope::string email = attr.get(email_attribute);
- if (!email.equals_ci(u->Account()->email))
+ if (!email.equals_ci(u->Account()->GetEmail()))
{
- u->Account()->email = email;
- BotInfo *NickServ = Config->GetClient("NickServ");
+ u->Account()->GetEmail() = email;
+ ServiceBot *NickServ = Config->GetClient("NickServ");
if (NickServ)
u->SendMessage(NickServ, _("Your email has been updated to \002%s\002"), email.c_str());
- Log(this->owner) << "Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
+ Log(this->owner) << "Updated email address for " << u->nick << " (" << u->Account()->GetDisplay() << ") to " << email;
}
}
catch (const LDAPException &ex)
@@ -166,7 +178,7 @@ class OnIdentifyInterface : public LDAPInterface
}
}
- void OnError(const LDAPResult &r) anope_override
+ void OnError(const LDAPResult &r) override
{
Log(this->owner) << r.error;
}
@@ -177,18 +189,22 @@ class OnRegisterInterface : public LDAPInterface
public:
OnRegisterInterface(Module *m) : LDAPInterface(m) { }
- void OnResult(const LDAPResult &r) anope_override
+ void OnResult(const LDAPResult &r) override
{
Log(this->owner) << "Successfully added newly created account to LDAP";
}
- void OnError(const LDAPResult &r) anope_override
+ void OnError(const LDAPResult &r) override
{
Log(this->owner) << "Error adding newly created account to LDAP: " << r.getError();
}
};
class ModuleLDAPAuthentication : public Module
+ , public EventHook<Event::PreCommand>
+ , public EventHook<Event::CheckAuthentication>
+ , public EventHook<Event::NickIdentify>
+ , public EventHook<NickServ::Event::NickRegister>
{
ServiceReference<LDAPProvider> ldap;
OnRegisterInterface orinterface;
@@ -198,38 +214,39 @@ class ModuleLDAPAuthentication : public Module
Anope::string password_attribute;
Anope::string disable_register_reason;
Anope::string disable_email_reason;
+
public:
- ModuleLDAPAuthentication(const Anope::string &modname, const Anope::string &creator) :
- Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), orinterface(this),
- dn(this, "m_ldap_authentication_dn")
+ ModuleLDAPAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::PreCommand>("OnPreCommand", EventHook<Event::PreCommand>::Priority::FIRST)
+ , EventHook<Event::CheckAuthentication>("OnCheckAuthentication", EventHook<Event::CheckAuthentication>::Priority::FIRST)
+ , EventHook<Event::NickIdentify>("OnNickIdentify", EventHook<Event::NickIdentify>::Priority::FIRST)
+ , EventHook<NickServ::Event::NickRegister>("OnNickRegister", EventHook<NickServ::Event::NickRegister>::Priority::FIRST)
+ , ldap("LDAPProvider", "ldap/main")
+ , orinterface(this)
+ , dn(this, "m_ldap_authentication_dn")
{
me = this;
}
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
-
- void OnReload(Configuration::Conf *config) anope_override
+ void OnReload(Configuration::Conf *config) override
{
Configuration::Block *conf = Config->GetModule(this);
- basedn = conf->Get<const Anope::string>("basedn");
- search_filter = conf->Get<const Anope::string>("search_filter");
- object_class = conf->Get<const Anope::string>("object_class");
- username_attribute = conf->Get<const Anope::string>("username_attribute");
- this->password_attribute = conf->Get<const Anope::string>("password_attribute");
- email_attribute = conf->Get<const Anope::string>("email_attribute");
- this->disable_register_reason = conf->Get<const Anope::string>("disable_register_reason");
- this->disable_email_reason = conf->Get<const Anope::string>("disable_email_reason");
+ basedn = conf->Get<Anope::string>("basedn");
+ search_filter = conf->Get<Anope::string>("search_filter");
+ object_class = conf->Get<Anope::string>("object_class");
+ username_attribute = conf->Get<Anope::string>("username_attribute");
+ this->password_attribute = conf->Get<Anope::string>("password_attribute");
+ email_attribute = conf->Get<Anope::string>("email_attribute");
+ this->disable_register_reason = conf->Get<Anope::string>("disable_register_reason");
+ this->disable_email_reason = conf->Get<Anope::string>("disable_email_reason");
if (!email_attribute.empty())
/* Don't complain to users about how they need to update their email, we will do it for them */
config->GetModule("nickserv")->Set("forceemail", "false");
}
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
{
if (!this->disable_register_reason.empty())
{
@@ -249,7 +266,7 @@ class ModuleLDAPAuthentication : public Module
return EVENT_CONTINUE;
}
- void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *u, IdentifyRequest *req) override
{
if (!this->ldap)
return;
@@ -258,7 +275,7 @@ class ModuleLDAPAuthentication : public Module
this->ldap->BindAsAdmin(new IdentifyInterface(this, ii));
}
- void OnNickIdentify(User *u) anope_override
+ void OnNickIdentify(User *u) override
{
if (email_attribute.empty() || !this->ldap)
return;
@@ -270,7 +287,7 @@ class ModuleLDAPAuthentication : public Module
this->ldap->Search(new OnIdentifyInterface(this, u->GetUID()), *d, "(" + email_attribute + "=*)");
}
- void OnNickRegister(User *, NickAlias *na, const Anope::string &pass) anope_override
+ void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &pass) override
{
if (!this->disable_register_reason.empty() || !this->ldap)
return;
@@ -285,18 +302,18 @@ class ModuleLDAPAuthentication : public Module
attributes[0].values.push_back(object_class);
attributes[1].name = username_attribute;
- attributes[1].values.push_back(na->nick);
+ attributes[1].values.push_back(na->GetNick());
- if (!na->nc->email.empty())
+ if (!na->GetAccount()->GetEmail().empty())
{
attributes[2].name = email_attribute;
- attributes[2].values.push_back(na->nc->email);
+ attributes[2].values.push_back(na->GetAccount()->GetEmail());
}
attributes[3].name = this->password_attribute;
attributes[3].values.push_back(pass);
- Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn;
+ Anope::string new_dn = username_attribute + "=" + na->GetNick() + "," + basedn;
this->ldap->Add(&this->orinterface, new_dn, attributes);
}
};
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/ldap_oper.cpp
index 23ebf1a6b..5157a6f10 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/ldap_oper.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -21,12 +32,12 @@ class IdentifyInterface : public LDAPInterface
{
}
- void OnResult(const LDAPResult &r) anope_override
+ void OnResult(const LDAPResult &r) override
{
if (!u || !u->Account())
return;
- NickCore *nc = u->Account();
+ NickServ::Account *nc = u->Account();
try
{
@@ -46,7 +57,8 @@ class IdentifyInterface : public LDAPInterface
o = new Oper(u->nick, ot);
my_opers.insert(o);
nc->o = o;
- Log(this->owner) << "Tied " << u->nick << " (" << nc->display << ") to opertype " << ot->GetName();
+
+ Log(this->owner) << "Tied " << u->nick << " (" << nc->GetDisplay() << ") to opertype " << ot->GetName();
}
}
catch (const LDAPException &ex)
@@ -60,12 +72,12 @@ class IdentifyInterface : public LDAPInterface
}
nc->o = NULL;
- Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->display << ")";
+ Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->GetDisplay() << ")";
}
}
}
- void OnError(const LDAPResult &r) anope_override
+ void OnError(const LDAPResult &r) override
{
}
@@ -76,6 +88,8 @@ class IdentifyInterface : public LDAPInterface
};
class LDAPOper : public Module
+ , public EventHook<Event::NickIdentify>
+ , public EventHook<Event::DelCore>
{
ServiceReference<LDAPProvider> ldap;
@@ -84,28 +98,29 @@ class LDAPOper : public Module
Anope::string basedn;
Anope::string filter;
public:
- LDAPOper(const Anope::string &modname, const Anope::string &creator) :
- Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main")
+ LDAPOper(const Anope::string &modname, const Anope::string &creator)
+ : Module(modname, creator, EXTRA | VENDOR)
+ , ldap("LDAPProvider", "ldap/main")
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = Config->GetModule(this);
- this->binddn = config->Get<const Anope::string>("binddn");
- this->password = config->Get<const Anope::string>("password");
- this->basedn = config->Get<const Anope::string>("basedn");
- this->filter = config->Get<const Anope::string>("filter");
- opertype_attribute = config->Get<const Anope::string>("opertype_attribute");
+ this->binddn = config->Get<Anope::string>("binddn");
+ this->password = config->Get<Anope::string>("password");
+ this->basedn = config->Get<Anope::string>("basedn");
+ this->filter = config->Get<Anope::string>("filter");
+ opertype_attribute = config->Get<Anope::string>("opertype_attribute");
for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it)
delete *it;
my_opers.clear();
}
- void OnNickIdentify(User *u) anope_override
+ void OnNickIdentify(User *u) override
{
try
{
@@ -115,8 +130,8 @@ class LDAPOper : public Module
throw LDAPException("Could not search LDAP for opertype settings, invalid configuration.");
if (!this->binddn.empty())
- this->ldap->Bind(NULL, this->binddn.replace_all_cs("%a", u->Account()->display), this->password.c_str());
- this->ldap->Search(new IdentifyInterface(this, u), this->basedn, this->filter.replace_all_cs("%a", u->Account()->display));
+ this->ldap->Bind(NULL, this->binddn.replace_all_cs("%a", u->Account()->GetDisplay()), this->password.c_str());
+ this->ldap->Search(new IdentifyInterface(this, u), this->basedn, this->filter.replace_all_cs("%a", u->Account()->GetDisplay()));
}
catch (const LDAPException &ex)
{
@@ -124,7 +139,7 @@ class LDAPOper : public Module
}
}
- void OnDelCore(NickCore *nc) anope_override
+ void OnDelCore(NickServ::Account *nc) override
{
if (nc->o != NULL && my_opers.count(nc->o) > 0)
{
diff --git a/modules/extra/m_regex_pcre.cpp b/modules/extra/m_regex_pcre.cpp
deleted file mode 100644
index fa804c14e..000000000
--- a/modules/extra/m_regex_pcre.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-/* RequiredLibraries: pcre */
-/* RequiredWindowsLibraries: libpcre */
-
-#include "module.h"
-#include <pcre.h>
-
-class PCRERegex : public Regex
-{
- pcre *regex;
-
- public:
- PCRERegex(const Anope::string &expr) : Regex(expr)
- {
- const char *error;
- int erroffset;
- this->regex = pcre_compile(expr.c_str(), PCRE_CASELESS, &error, &erroffset, NULL);
- if (!this->regex)
- throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + error);
- }
-
- ~PCRERegex()
- {
- pcre_free(this->regex);
- }
-
- bool Matches(const Anope::string &str)
- {
- return pcre_exec(this->regex, NULL, str.c_str(), str.length(), 0, 0, NULL, 0) > -1;
- }
-};
-
-class PCRERegexProvider : public RegexProvider
-{
- public:
- PCRERegexProvider(Module *creator) : RegexProvider(creator, "regex/pcre") { }
-
- Regex *Compile(const Anope::string &expression) anope_override
- {
- return new PCRERegex(expression);
- }
-};
-
-class ModuleRegexPCRE : public Module
-{
- PCRERegexProvider pcre_regex_provider;
-
- public:
- ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- pcre_regex_provider(this)
- {
- this->SetPermanent(true);
- }
-
- ~ModuleRegexPCRE()
- {
- for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it)
- {
- XLineManager *xlm = *it;
- const std::vector<XLine *> &xlines = xlm->GetList();
-
- for (unsigned int i = 0; i < xlines.size(); ++i)
- {
- XLine *x = xlines[i];
-
- if (x->regex && dynamic_cast<PCRERegex *>(x->regex))
- {
- delete x->regex;
- x->regex = NULL;
- }
- }
- }
- }
-};
-
-MODULE_INIT(ModuleRegexPCRE)
diff --git a/modules/extra/m_regex_posix.cpp b/modules/extra/m_regex_posix.cpp
deleted file mode 100644
index 2486ddd70..000000000
--- a/modules/extra/m_regex_posix.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include <sys/types.h>
-#include <regex.h>
-
-class POSIXRegex : public Regex
-{
- regex_t regbuf;
-
- public:
- POSIXRegex(const Anope::string &expr) : Regex(expr)
- {
- int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB);
- if (err)
- {
- char buf[BUFSIZE];
- regerror(err, &this->regbuf, buf, sizeof(buf));
- regfree(&this->regbuf);
- throw RegexException("Error in regex " + expr + ": " + buf);
- }
- }
-
- ~POSIXRegex()
- {
- regfree(&this->regbuf);
- }
-
- bool Matches(const Anope::string &str)
- {
- return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0;
- }
-};
-
-class POSIXRegexProvider : public RegexProvider
-{
- public:
- POSIXRegexProvider(Module *creator) : RegexProvider(creator, "regex/posix") { }
-
- Regex *Compile(const Anope::string &expression) anope_override
- {
- return new POSIXRegex(expression);
- }
-};
-
-class ModuleRegexPOSIX : public Module
-{
- POSIXRegexProvider posix_regex_provider;
-
- public:
- ModuleRegexPOSIX(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- posix_regex_provider(this)
- {
- this->SetPermanent(true);
- }
-
- ~ModuleRegexPOSIX()
- {
- for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it)
- {
- XLineManager *xlm = *it;
- const std::vector<XLine *> &xlines = xlm->GetList();
-
- for (unsigned int i = 0; i < xlines.size(); ++i)
- {
- XLine *x = xlines[i];
-
- if (x->regex && dynamic_cast<POSIXRegex *>(x->regex))
- {
- delete x->regex;
- x->regex = NULL;
- }
- }
- }
- }
-};
-
-MODULE_INIT(ModuleRegexPOSIX)
diff --git a/modules/extra/m_regex_tre.cpp b/modules/extra/m_regex_tre.cpp
deleted file mode 100644
index 66411280c..000000000
--- a/modules/extra/m_regex_tre.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-/* RequiredLibraries: tre */
-
-#include "module.h"
-#include <tre/regex.h>
-
-class TRERegex : public Regex
-{
- regex_t regbuf;
-
- public:
- TRERegex(const Anope::string &expr) : Regex(expr)
- {
- int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB);
- if (err)
- {
- char buf[BUFSIZE];
- regerror(err, &this->regbuf, buf, sizeof(buf));
- regfree(&this->regbuf);
- throw RegexException("Error in regex " + expr + ": " + buf);
- }
- }
-
- ~TRERegex()
- {
- regfree(&this->regbuf);
- }
-
- bool Matches(const Anope::string &str)
- {
- return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0;
- }
-};
-
-class TRERegexProvider : public RegexProvider
-{
- public:
- TRERegexProvider(Module *creator) : RegexProvider(creator, "regex/tre") { }
-
- Regex *Compile(const Anope::string &expression) anope_override
- {
- return new TRERegex(expression);
- }
-};
-
-class ModuleRegexTRE : public Module
-{
- TRERegexProvider tre_regex_provider;
-
- public:
- ModuleRegexTRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- tre_regex_provider(this)
- {
- this->SetPermanent(true);
- }
-
- ~ModuleRegexTRE()
- {
- for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it)
- {
- XLineManager *xlm = *it;
- const std::vector<XLine *> &xlines = xlm->GetList();
-
- for (unsigned int i = 0; i < xlines.size(); ++i)
- {
- XLine *x = xlines[i];
-
- if (x->regex && dynamic_cast<TRERegex *>(x->regex))
- {
- delete x->regex;
- x->regex = NULL;
- }
- }
- }
- }
-};
-
-MODULE_INIT(ModuleRegexTRE)
diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp
deleted file mode 100644
index b2b2f2d1e..000000000
--- a/modules/extra/m_sql_oper.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- *
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/sql.h"
-
-struct SQLOper : Oper
-{
- SQLOper(const Anope::string &n, OperType *o) : Oper(n, o) { }
-};
-
-class SQLOperResult : public SQL::Interface
-{
- Reference<User> user;
-
- struct SQLOperResultDeleter
- {
- SQLOperResult *res;
- SQLOperResultDeleter(SQLOperResult *r) : res(r) { }
- ~SQLOperResultDeleter() { delete res; }
- };
-
- void Deoper()
- {
- if (user->Account() && user->Account()->o && dynamic_cast<SQLOper *>(user->Account()->o))
- {
- delete user->Account()->o;
- user->Account()->o = NULL;
-
- Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")";
-
- BotInfo *OperServ = Config->GetClient("OperServ");
- user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase
- }
- }
-
- public:
- SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { }
-
- void OnResult(const SQL::Result &r) anope_override
- {
- SQLOperResultDeleter d(this);
-
- if (!user || !user->Account())
- return;
-
- if (r.Rows() == 0)
- {
- Log(LOG_DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick;
- Deoper();
- return;
- }
-
- Anope::string opertype;
- try
- {
- opertype = r.Get(0, "opertype");
- }
- catch (const SQL::Exception &)
- {
- Log(this->owner) << "Expected column named \"opertype\" but one was not found";
- return;
- }
-
- Log(LOG_DEBUG) << "m_sql_oper: Got result for " << user->nick << ", opertype " << opertype;
-
- Anope::string modes;
- try
- {
- modes = r.Get(0, "modes");
- }
- catch (const SQL::Exception &)
- {
- // Common case here is an exception, but this probably doesn't get this far often
- }
-
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (opertype.empty())
- {
- Deoper();
- return;
- }
-
- OperType *ot = OperType::Find(opertype);
- if (ot == NULL)
- {
- Log(this->owner) << "m_sql_oper: Oper " << user->nick << " has type " << opertype << ", but this opertype does not exist?";
- return;
- }
-
- if (user->Account()->o && !dynamic_cast<SQLOper *>(user->Account()->o))
- {
- Log(this->owner) << "Oper " << user->Account()->display << " has type " << opertype << ", but is already configured as an oper of type " << user->Account()->o->ot->GetName();
- return;
- }
-
- if (!user->Account()->o || user->Account()->o->ot != ot)
- {
- Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype;
-
- delete user->Account()->o;
- user->Account()->o = new SQLOper(user->Account()->display, ot);
- }
-
- if (!user->HasMode("OPER"))
- {
- IRCD->SendOper(user);
-
- if (!modes.empty())
- user->SetModes(OperServ, "%s", modes.c_str());
- }
- }
-
- void OnError(const SQL::Result &r) anope_override
- {
- SQLOperResultDeleter d(this);
- Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError();
- }
-};
-
-class ModuleSQLOper : public Module
-{
- Anope::string engine;
- Anope::string query;
-
- ServiceReference<SQL::Provider> SQL;
-
- public:
- ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
- {
- }
-
- ~ModuleSQLOper()
- {
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- NickCore *nc = it->second;
-
- if (nc->o && dynamic_cast<SQLOper *>(nc->o))
- {
- delete nc->o;
- nc->o = NULL;
- }
- }
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *config = conf->GetModule(this);
-
- this->engine = config->Get<const Anope::string>("engine");
- this->query = config->Get<const Anope::string>("query");
-
- this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine);
- }
-
- void OnNickIdentify(User *u) anope_override
- {
- if (!this->SQL)
- {
- Log() << "Unable to find SQL engine";
- return;
- }
-
- SQL::Query q(this->query);
- q.SetValue("a", u->Account()->display);
- q.SetValue("i", u->ip.addr());
-
- this->SQL->Run(new SQLOperResult(this, u), q);
-
- Log(LOG_DEBUG) << "m_sql_oper: Checking authentication for " << u->Account()->display;
- }
-};
-
-MODULE_INIT(ModuleSQLOper)
diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp
deleted file mode 100644
index d8b76011a..000000000
--- a/modules/extra/m_sqlite.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- *
- * (C) 2011-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-/* RequiredLibraries: sqlite3 */
-/* RequiredWindowsLibraries: sqlite3 */
-
-#include "module.h"
-#include "modules/sql.h"
-#include <sqlite3.h>
-
-using namespace SQL;
-
-/* SQLite3 API, based from InspiRCd */
-
-/** A SQLite result
- */
-class SQLiteResult : public Result
-{
- public:
- SQLiteResult(unsigned int i, const Query &q, const Anope::string &fq) : Result(i, q, fq)
- {
- }
-
- SQLiteResult(const Query &q, const Anope::string &fq, const Anope::string &err) : Result(0, q, fq, err)
- {
- }
-
- void AddRow(const std::map<Anope::string, Anope::string> &data)
- {
- this->entries.push_back(data);
- }
-};
-
-/** A SQLite database, there can be multiple
- */
-class SQLiteService : public Provider
-{
- std::map<Anope::string, std::set<Anope::string> > active_schema;
-
- Anope::string database;
-
- sqlite3 *sql;
-
- Anope::string Escape(const Anope::string &query);
-
- public:
- SQLiteService(Module *o, const Anope::string &n, const Anope::string &d);
-
- ~SQLiteService();
-
- void Run(Interface *i, const Query &query) anope_override;
-
- Result RunQuery(const Query &query);
-
- std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override;
-
- Query BuildInsert(const Anope::string &table, unsigned int id, Data &data);
-
- Query GetTables(const Anope::string &prefix);
-
- Anope::string BuildQuery(const Query &q);
-
- Anope::string FromUnixtime(time_t);
-};
-
-class ModuleSQLite : public Module
-{
- /* SQL connections */
- std::map<Anope::string, SQLiteService *> SQLiteServices;
- public:
- ModuleSQLite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
- {
- }
-
- ~ModuleSQLite()
- {
- for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end(); ++it)
- delete it->second;
- SQLiteServices.clear();
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *config = conf->GetModule(this);
-
- for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();)
- {
- const Anope::string &cname = it->first;
- SQLiteService *s = it->second;
- int i, num;
- ++it;
-
- for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i)
- if (config->GetBlock("sqlite", i)->Get<const Anope::string>("name", "sqlite/main") == cname)
- break;
-
- if (i == num)
- {
- Log(LOG_NORMAL, "sqlite") << "SQLite: Removing server connection " << cname;
-
- delete s;
- this->SQLiteServices.erase(cname);
- }
- }
-
- for (int i = 0; i < config->CountBlock("sqlite"); ++i)
- {
- Configuration::Block *block = config->GetBlock("sqlite", i);
- Anope::string connname = block->Get<const Anope::string>("name", "sqlite/main");
-
- if (this->SQLiteServices.find(connname) == this->SQLiteServices.end())
- {
- Anope::string database = Anope::DataDir + "/" + block->Get<const Anope::string>("database", "anope");
-
- try
- {
- SQLiteService *ss = new SQLiteService(this, connname, database);
- this->SQLiteServices[connname] = ss;
-
- Log(LOG_NORMAL, "sqlite") << "SQLite: Successfully added database " << database;
- }
- catch (const SQL::Exception &ex)
- {
- Log(LOG_NORMAL, "sqlite") << "SQLite: " << ex.GetReason();
- }
- }
- }
- }
-};
-
-SQLiteService::SQLiteService(Module *o, const Anope::string &n, const Anope::string &d)
-: Provider(o, n), database(d), sql(NULL)
-{
- int db = sqlite3_open_v2(database.c_str(), &this->sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
- if (db != SQLITE_OK)
- throw SQL::Exception("Unable to open SQLite database " + database + ": " + sqlite3_errmsg(this->sql));
-}
-
-SQLiteService::~SQLiteService()
-{
- sqlite3_interrupt(this->sql);
- sqlite3_close(this->sql);
-}
-
-void SQLiteService::Run(Interface *i, const Query &query)
-{
- Result res = this->RunQuery(query);
- if (!res.GetError().empty())
- i->OnError(res);
- else
- i->OnResult(res);
-}
-
-Result SQLiteService::RunQuery(const Query &query)
-{
- Anope::string real_query = this->BuildQuery(query);
- sqlite3_stmt *stmt;
- int err = sqlite3_prepare_v2(this->sql, real_query.c_str(), real_query.length(), &stmt, NULL);
- if (err != SQLITE_OK)
- return SQLiteResult(query, real_query, sqlite3_errmsg(this->sql));
-
- std::vector<Anope::string> columns;
- int cols = sqlite3_column_count(stmt);
- columns.resize(cols);
- for (int i = 0; i < cols; ++i)
- columns[i] = sqlite3_column_name(stmt, i);
-
- SQLiteResult result(0, query, real_query);
-
- while ((err = sqlite3_step(stmt)) == SQLITE_ROW)
- {
- std::map<Anope::string, Anope::string> items;
- for (int i = 0; i < cols; ++i)
- {
- const char *data = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
- if (data && *data)
- items[columns[i]] = data;
- }
- result.AddRow(items);
- }
-
- result.id = sqlite3_last_insert_rowid(this->sql);
-
- sqlite3_finalize(stmt);
-
- if (err != SQLITE_DONE)
- return SQLiteResult(query, real_query, sqlite3_errmsg(this->sql));
-
- return result;
-}
-
-std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const Data &data)
-{
- std::vector<Query> queries;
- std::set<Anope::string> &known_cols = this->active_schema[table];
-
- if (known_cols.empty())
- {
- Log(LOG_DEBUG) << "m_sqlite: Fetching columns for " << table;
-
- Result columns = this->RunQuery("PRAGMA table_info(" + table + ")");
- for (int i = 0; i < columns.Rows(); ++i)
- {
- const Anope::string &column = columns.Get(i, "name");
-
- Log(LOG_DEBUG) << "m_sqlite: Column #" << i << " for " << table << ": " << column;
- known_cols.insert(column);
- }
- }
-
- if (known_cols.empty())
- {
- Anope::string query_text = "CREATE TABLE `" + table + "` (`id` INTEGER PRIMARY KEY, `timestamp` timestamp DEFAULT CURRENT_TIMESTAMP";
-
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- known_cols.insert(it->first);
-
- query_text += ", `" + it->first + "` ";
- if (data.GetType(it->first) == Serialize::Data::DT_INT)
- query_text += "int(11)";
- else
- query_text += "text";
- }
-
- query_text += ")";
-
- queries.push_back(query_text);
-
- query_text = "CREATE UNIQUE INDEX `" + table + "_id_idx` ON `" + table + "` (`id`)";
- queries.push_back(query_text);
-
- query_text = "CREATE INDEX `" + table + "_timestamp_idx` ON `" + table + "` (`timestamp`)";
- queries.push_back(query_text);
-
- query_text = "CREATE TRIGGER `" + table + "_trigger` AFTER UPDATE ON `" + table + "` FOR EACH ROW BEGIN UPDATE `" + table + "` SET `timestamp` = CURRENT_TIMESTAMP WHERE `id` = `old.id`; end;";
- queries.push_back(query_text);
- }
- else
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- if (known_cols.count(it->first) > 0)
- continue;
-
- known_cols.insert(it->first);
-
- Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
- if (data.GetType(it->first) == Serialize::Data::DT_INT)
- query_text += "int(11)";
- else
- query_text += "text";
-
- queries.push_back(query_text);
- }
-
- return queries;
-}
-
-Query SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, Data &data)
-{
- /* Empty columns not present in the data set */
- const std::set<Anope::string> &known_cols = this->active_schema[table];
- for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it)
- if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0)
- data[*it] << "";
-
- Anope::string query_text = "REPLACE INTO `" + table + "` (";
- if (id > 0)
- query_text += "`id`,";
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- query_text += "`" + it->first + "`,";
- query_text.erase(query_text.length() - 1);
- query_text += ") VALUES (";
- if (id > 0)
- query_text += stringify(id) + ",";
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- query_text += "@" + it->first + "@,";
- query_text.erase(query_text.length() - 1);
- query_text += ")";
-
- Query query(query_text);
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- Anope::string buf;
- *it->second >> buf;
- query.SetValue(it->first, buf);
- }
-
- return query;
-}
-
-Query SQLiteService::GetTables(const Anope::string &prefix)
-{
- return Query("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';");
-}
-
-Anope::string SQLiteService::Escape(const Anope::string &query)
-{
- char *e = sqlite3_mprintf("%q", query.c_str());
- Anope::string buffer = e;
- sqlite3_free(e);
- return buffer;
-}
-
-Anope::string SQLiteService::BuildQuery(const Query &q)
-{
- Anope::string real_query = q.query;
-
- for (std::map<Anope::string, QueryData>::const_iterator it = q.parameters.begin(), it_end = q.parameters.end(); it != it_end; ++it)
- real_query = real_query.replace_all_cs("@" + it->first + "@", (it->second.escape ? ("'" + this->Escape(it->second.data) + "'") : it->second.data));
-
- return real_query;
-}
-
-Anope::string SQLiteService::FromUnixtime(time_t t)
-{
- return "datetime('" + stringify(t) + "', 'unixepoch')";
-}
-
-MODULE_INIT(ModuleSQLite)
-
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/mysql.cpp
index 06cce3143..b0aec1f6d 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/mysql.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
/* RequiredLibraries: mysqlclient */
@@ -66,31 +77,35 @@ class MySQLResult : public Result
public:
MySQLResult(unsigned int i, const Query &q, const Anope::string &fq, MYSQL_RES *r) : Result(i, q, fq), res(r)
{
- unsigned num_fields = res ? mysql_num_fields(res) : 0;
+ if (!res)
+ return;
+
+ unsigned num_fields = mysql_num_fields(res);
+ MYSQL_FIELD *fields = mysql_fetch_fields(res);
/* It is not thread safe to log anything here using Log(this->owner) now :( */
- if (!num_fields)
+ if (!num_fields || !fields)
return;
+ for (unsigned field_count = 0; field_count < num_fields; ++field_count)
+ columns.push_back(fields[field_count].name ? fields[field_count].name : "");
+
for (MYSQL_ROW row; (row = mysql_fetch_row(res));)
{
- MYSQL_FIELD *fields = mysql_fetch_fields(res);
+ std::vector<Value> values;
- if (fields)
+ for (unsigned field_count = 0; field_count < num_fields; ++field_count)
{
- std::map<Anope::string, Anope::string> items;
+ const char *data = row[field_count];
- for (unsigned field_count = 0; field_count < num_fields; ++field_count)
- {
- Anope::string column = (fields[field_count].name ? fields[field_count].name : "");
- Anope::string data = (row[field_count] ? row[field_count] : "");
-
- items[column] = data;
- }
-
- this->entries.push_back(items);
+ Value v;
+ v.null = !data;
+ v.value = data ? data : "";
+ values.push_back(v);
}
+
+ this->values.push_back(values);
}
}
@@ -109,7 +124,7 @@ class MySQLResult : public Result
*/
class MySQLService : public Provider
{
- std::map<Anope::string, std::set<Anope::string> > active_schema;
+ std::map<Anope::string, std::set<Anope::string> > active_schema, indexes;
Anope::string database;
Anope::string server;
@@ -135,23 +150,28 @@ class MySQLService : public Provider
~MySQLService();
- void Run(Interface *i, const Query &query) anope_override;
+ void Run(Interface *i, const Query &query) override;
- Result RunQuery(const Query &query) anope_override;
+ Result RunQuery(const Query &query) override;
- std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override;
+ std::vector<Query> InitSchema(const Anope::string &prefix) override;
+ std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) override;
+ std::vector<Query> CreateTable(const Anope::string &prefix, const Anope::string &table) override;
+ std::vector<Query> AlterTable(const Anope::string &, const Anope::string &table, const Anope::string &field, bool) override;
+ std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) override;
- Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) anope_override;
+ Query BeginTransaction() override;
+ Query Commit() override;
- Query GetTables(const Anope::string &prefix) anope_override;
+ Serialize::ID GetID(const Anope::string &) override;
+
+ Query GetTables(const Anope::string &prefix) override;
void Connect();
bool CheckConnection();
Anope::string BuildQuery(const Query &q);
-
- Anope::string FromUnixtime(time_t);
};
/** The SQL thread used to execute queries
@@ -161,12 +181,14 @@ class DispatcherThread : public Thread, public Condition
public:
DispatcherThread() : Thread() { }
- void Run() anope_override;
+ void Run() override;
};
class ModuleSQL;
static ModuleSQL *me;
-class ModuleSQL : public Module, public Pipe
+class ModuleSQL : public Module
+ , public Pipe
+ , public EventHook<Event::ModuleUnload>
{
/* SQL connections */
std::map<Anope::string, MySQLService *> MySQLServices;
@@ -179,6 +201,7 @@ class ModuleSQL : public Module, public Pipe
DispatcherThread *DThread;
ModuleSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::ModuleUnload>(this)
{
me = this;
@@ -199,7 +222,7 @@ class ModuleSQL : public Module, public Pipe
delete DThread;
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = conf->GetModule(this);
@@ -212,7 +235,7 @@ class ModuleSQL : public Module, public Pipe
++it;
for (i = 0; i < config->CountBlock("mysql"); ++i)
- if (config->GetBlock("mysql", i)->Get<const Anope::string>("name", "mysql/main") == cname)
+ if (config->GetBlock("mysql", i)->Get<Anope::string>("name", "mysql/main") == cname)
break;
if (i == config->CountBlock("mysql"))
@@ -227,14 +250,14 @@ class ModuleSQL : public Module, public Pipe
for (int i = 0; i < config->CountBlock("mysql"); ++i)
{
Configuration::Block *block = config->GetBlock("mysql", i);
- const Anope::string &connname = block->Get<const Anope::string>("name", "mysql/main");
+ const Anope::string &connname = block->Get<Anope::string>("name", "mysql/main");
if (this->MySQLServices.find(connname) == this->MySQLServices.end())
{
- const Anope::string &database = block->Get<const Anope::string>("database", "anope");
- const Anope::string &server = block->Get<const Anope::string>("server", "127.0.0.1");
- const Anope::string &user = block->Get<const Anope::string>("username", "anope");
- const Anope::string &password = block->Get<const Anope::string>("password");
+ const Anope::string &database = block->Get<Anope::string>("database", "anope");
+ const Anope::string &server = block->Get<Anope::string>("server", "127.0.0.1");
+ const Anope::string &user = block->Get<Anope::string>("username", "anope");
+ const Anope::string &password = block->Get<Anope::string>("password");
int port = block->Get<int>("port", "3306");
try
@@ -252,7 +275,7 @@ class ModuleSQL : public Module, public Pipe
}
}
- void OnModuleUnload(User *, Module *m) anope_override
+ void OnModuleUnload(User *, Module *m) override
{
this->DThread->Lock();
@@ -277,7 +300,7 @@ class ModuleSQL : public Module, public Pipe
this->OnNotify();
}
- void OnNotify() anope_override
+ void OnNotify() override
{
this->DThread->Lock();
std::deque<QueryResult> finishedRequests = this->FinishedRequests;
@@ -366,90 +389,146 @@ Result MySQLService::RunQuery(const Query &query)
}
}
-std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const Data &data)
+std::vector<Query> MySQLService::InitSchema(const Anope::string &prefix)
+{
+ std::vector<Query> queries;
+
+ Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + "id` ("
+ "`id` bigint(20) NOT NULL"
+ ") ENGINE=InnoDB";
+ queries.push_back(t);
+
+ t = "CREATE TABLE IF NOT EXISTS `" + prefix + "objects` (`id` bigint(20) NOT NULL PRIMARY KEY, `type` varchar(256)) ENGINE=InnoDB";
+ queries.push_back(t);
+
+ t = "CREATE TABLE IF NOT EXISTS `" + prefix + "edges` ("
+ "`id` bigint(20) NOT NULL,"
+ "`field` varchar(64) NOT NULL,"
+ "`other_id` bigint(20) NOT NULL,"
+ "PRIMARY KEY (`id`, `field`),"
+ "KEY `other` (`other_id`),"
+ "CONSTRAINT `edges_id_fk` FOREIGN KEY (`id`) REFERENCES `" + prefix + "objects` (`id`),"
+ "CONSTRAINT `edges_other_id_fk` FOREIGN KEY (`other_id`) REFERENCES `" + prefix + "objects` (`id`)"
+ ") ENGINE=InnoDB";
+ queries.push_back(t);
+
+ return queries;
+}
+
+std::vector<Query> MySQLService::Replace(const Anope::string &table, const Query &q, const std::set<Anope::string> &keys)
{
std::vector<Query> queries;
- std::set<Anope::string> &known_cols = this->active_schema[table];
- if (known_cols.empty())
+ Anope::string query_text = "INSERT INTO `" + table + "` (";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ query_text += "`" + p.first + "`,";
+ query_text.erase(query_text.length() - 1);
+ query_text += ") VALUES (";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ query_text += "@" + p.first + "@,";
+ query_text.erase(query_text.length() - 1);
+ query_text += ") ON DUPLICATE KEY UPDATE ";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ if (!keys.count(p.first))
+ query_text += "`" + p.first + "` = VALUES(`" + p.first + "`),";
+ query_text.erase(query_text.length() - 1);
+
+ Query query(query_text);
+ query.parameters = q.parameters;
+
+ queries.push_back(query);
+
+ return queries;
+}
+
+std::vector<Query> MySQLService::CreateTable(const Anope::string &prefix, const Anope::string &table)
+{
+ std::vector<Query> queries;
+
+ if (active_schema.find(prefix + table) == active_schema.end())
{
- Log(LOG_DEBUG) << "m_mysql: Fetching columns for " << table;
+ Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + table + "` (`id` bigint(20) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB";
+ queries.push_back(t);
- Result columns = this->RunQuery("SHOW COLUMNS FROM `" + table + "`");
- for (int i = 0; i < columns.Rows(); ++i)
- {
- const Anope::string &column = columns.Get(i, "Field");
+ t = "ALTER TABLE `" + prefix + table + "` "
+ "ADD CONSTRAINT `" + table + "_id_fk` FOREIGN KEY (`id`) REFERENCES `" + prefix + "objects` (`id`)";
+ queries.push_back(t);
- Log(LOG_DEBUG) << "m_mysql: Column #" << i << " for " << table << ": " << column;
- known_cols.insert(column);
- }
+ active_schema[prefix + table];
}
- if (known_cols.empty())
- {
- Anope::string query_text = "CREATE TABLE `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
- " `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- known_cols.insert(it->first);
+ return queries;
+}
- query_text += ", `" + it->first + "` ";
- if (data.GetType(it->first) == Serialize::Data::DT_INT)
- query_text += "int(11)";
- else
- query_text += "text";
- }
- query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))";
- queries.push_back(query_text);
+std::vector<Query> MySQLService::AlterTable(const Anope::string &prefix, const Anope::string &table, const Anope::string &field, bool object)
+{
+ std::vector<Query> queries;
+ std::set<Anope::string> &s = active_schema[prefix + table];
+
+ if (!s.count(field))
+ {
+ Query column;
+ if (!object)
+ column = "ALTER TABLE `" + prefix + table + "` ADD COLUMN `" + field + "` TINYTEXT";
+ else
+ column = "ALTER TABLE `" + prefix + table + "` "
+ "ADD COLUMN `" + field + "` bigint(20), "
+ "ADD CONSTRAINT `" + table + "_" + field + "_fk` FOREIGN KEY (`" + field + "`) REFERENCES `" + prefix + "objects` (`id`)";
+ queries.push_back(column);
+ s.insert(field);
}
- else
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- {
- if (known_cols.count(it->first) > 0)
- continue;
- known_cols.insert(it->first);
+ return queries;
+}
- Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
- if (data.GetType(it->first) == Serialize::Data::DT_INT)
- query_text += "int(11)";
- else
- query_text += "text";
+std::vector<Query> MySQLService::CreateIndex(const Anope::string &table, const Anope::string &field)
+{
+ std::vector<Query> queries;
- queries.push_back(query_text);
- }
+ if (indexes[table].count(field))
+ return queries;
+
+ Query t = "ALTER TABLE `" + table + "` ADD KEY `idx_" + field + "` (`" + field + "`(512))";
+ queries.push_back(t);
+
+ indexes[table].insert(field);
return queries;
}
-Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Data &data)
+Query MySQLService::BeginTransaction()
{
- /* Empty columns not present in the data set */
- const std::set<Anope::string> &known_cols = this->active_schema[table];
- for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it)
- if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0)
- data[*it] << "";
-
- Anope::string query_text = "INSERT INTO `" + table + "` (`id`";
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- query_text += ",`" + it->first + "`";
- query_text += ") VALUES (" + stringify(id);
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- query_text += ",@" + it->first + "@";
- query_text += ") ON DUPLICATE KEY UPDATE ";
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
- query_text += "`" + it->first + "`=VALUES(`" + it->first + "`),";
- query_text.erase(query_text.end() - 1);
+ return Query("START TRANSACTION WITH CONSISTENT SNAPSHOT");
+}
- Query query(query_text);
- for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it)
+Query MySQLService::Commit()
+{
+ return Query("COMMIT");
+}
+
+Serialize::ID MySQLService::GetID(const Anope::string &prefix)
+{
+ Query query("SELECT `id` FROM `" + prefix + "id` FOR UPDATE");
+ Serialize::ID id;
+
+ Result res = RunQuery(query);
+ if (res.Rows())
+ {
+ id = convertTo<Serialize::ID>(res.Get(0, "id"));
+
+ Query update_query("UPDATE `" + prefix + "id` SET `id` = `id` + 1");
+ RunQuery(update_query);
+ }
+ else
{
- Anope::string buf;
- *it->second >> buf;
- query.SetValue(it->first, buf);
+ id = 0;
+
+ Query insert_query("INSERT INTO `" + prefix + "id` (id) VALUES(@id@)");
+ insert_query.SetValue("id", 1);
+ RunQuery(insert_query);
}
-
- return query;
+
+ return id;
}
Query MySQLService::GetTables(const Anope::string &prefix)
@@ -467,9 +546,9 @@ void MySQLService::Connect()
bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, NULL, CLIENT_MULTI_RESULTS);
if (!connect)
- throw SQL::Exception("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql));
-
- Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port;
+ throw SQL::Exception("Unable to connect to MySQL service " + this->GetName() + ": " + mysql_error(this->sql));
+
+ Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->GetName() << " at " << this->server << ":" << this->port;
}
@@ -502,14 +581,21 @@ Anope::string MySQLService::BuildQuery(const Query &q)
Anope::string real_query = q.query;
for (std::map<Anope::string, QueryData>::const_iterator it = q.parameters.begin(), it_end = q.parameters.end(); it != it_end; ++it)
- real_query = real_query.replace_all_cs("@" + it->first + "@", (it->second.escape ? ("'" + this->Escape(it->second.data) + "'") : it->second.data));
+ {
+ const QueryData& qd = it->second;
+ Anope::string replacement;
- return real_query;
-}
+ if (qd.null)
+ replacement = "NULL";
+ else if (!qd.escape)
+ replacement = qd.data;
+ else
+ replacement = "'" + this->Escape(qd.data) + "'";
-Anope::string MySQLService::FromUnixtime(time_t t)
-{
- return "FROM_UNIXTIME(" + stringify(t) + ")";
+ real_query = real_query.replace_all_cs("@" + it->first + "@", replacement);
+ }
+
+ return real_query;
}
void DispatcherThread::Run()
diff --git a/modules/extra/sasl_dh-aes.cpp b/modules/extra/sasl_dh-aes.cpp
new file mode 100644
index 000000000..b4920aeb4
--- /dev/null
+++ b/modules/extra/sasl_dh-aes.cpp
@@ -0,0 +1,184 @@
+/* RequiredLibraries: ssl,crypto */
+/* RequiredWindowsLibraries: ssleay32,libeay32 */
+
+#include "module.h"
+#include "modules/sasl.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/aes.h>
+
+using namespace SASL;
+
+class DHAES : public Mechanism
+{
+ void Err(Session* sess, BIGNUM* key = NULL)
+ {
+ if (key)
+ BN_free(key);
+
+ sasl->Fail(sess);
+ delete sess;
+ }
+
+ public:
+ struct DHAESSession : SASL::Session
+ {
+ DH* dh;
+ DHAESSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
+ {
+ if (!(dh = DH_new()))
+ return;
+
+ dh->g = BN_dup(dh_params->g);
+ dh->p = BN_dup(dh_params->p);
+
+ if (!DH_generate_key(dh))
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+
+ ~DHAESSession()
+ {
+ if (dh)
+ DH_free(dh);
+ }
+ };
+
+ DH* dh_params;
+ const size_t keysize;
+ SASL::Session* CreateSession(const Anope::string &uid) override
+ {
+ return new DHAESSession(this, uid, dh_params);
+ }
+
+ DHAES(Module *o) : Mechanism(o, "DH-AES"), keysize(256 / 8)
+ {
+ if (!(dh_params = DH_new()))
+ throw ModuleException("DH_new() failed!");
+
+ if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL))
+ {
+ DH_free(dh_params);
+ throw ModuleException("Could not generate DH-params");
+ }
+ }
+
+ ~DHAES()
+ {
+ DH_free(dh_params);
+ }
+
+ void ProcessMessage(SASL::Session *session, const SASL::Message &m) override
+ {
+ DHAESSession *sess = anope_dynamic_static_cast<DHAESSession *>(session);
+
+ if (!sess->dh)
+ {
+ sasl->SendMessage(sess, "D", "A");
+ delete sess;
+ return;
+ }
+
+ if (m.type == "S")
+ {
+ // Format: [ss]<p>[ss]<g>[ss]<pub_key>
+ // Where ss is a unsigned short with the size of the key
+ const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key };
+
+ // Find the size of our buffer - initialized at 6 because of string size data
+ size_t size = 6;
+ for (size_t i = 0; i < 3; i++)
+ size += BN_num_bytes(dhval[i]);
+
+ // Fill in the DH data
+ std::vector<unsigned char> buffer(size);
+ for (size_t i = 0, pos = 0; i < 3; i++)
+ {
+ *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i]));
+ pos += 2;
+ BN_bn2bin(dhval[i], &buffer[pos]);
+ pos += BN_num_bytes(dhval[i]);
+ }
+
+ Anope::string encoded;
+ Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded);
+ sasl->SendMessage(sess, "C", encoded);
+ }
+ else if (m.type == "C")
+ {
+ // Make sure we have some data - actual size check is done later
+ if (m.data.length() < 10)
+ return Err(sess);
+
+ // Format: [ss]<key>[ss]<iv>[ss]<encrypted>
+ // <encrypted> = <username>\0<password>\0
+
+ Anope::string decoded;
+ Anope::B64Decode(m.data, decoded);
+
+ // Make sure we have an IV and at least one encrypted block
+ if ((decoded.length() < keysize + 2 + (AES_BLOCK_SIZE * 2)) || ((decoded.length() - keysize - 2) % AES_BLOCK_SIZE))
+ return Err(sess);
+
+ const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data());
+
+ // Control the size of the key
+ if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize)
+ return Err(sess);
+
+ // Convert pubkey from binary
+ size_t pos = 2;
+ BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL);
+ if (!pubkey)
+ return Err(sess);
+
+ // Find shared key
+ std::vector<unsigned char> secretkey(keysize);
+ if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize))
+ return Err(sess, pubkey);
+
+ // Set decryption key
+ AES_KEY AESKey;
+ AES_set_decrypt_key(&secretkey[0], keysize * 8, &AESKey);
+
+ // Fetch IV
+ pos += keysize;
+ std::vector<unsigned char> IV(data + pos, data + pos + AES_BLOCK_SIZE);
+
+ // Find encrypted blocks, and decrypt
+ pos += AES_BLOCK_SIZE;
+ size_t size = decoded.length() - pos;
+ std::vector<char> decrypted(size + 2, 0);
+ AES_cbc_encrypt(&data[pos], reinterpret_cast<unsigned char*>(&decrypted[0]), size, &AESKey, &IV[0], AES_DECRYPT);
+
+ std::string username = &decrypted[0];
+ std::string password = &decrypted[username.length() + 1];
+
+ if (username.empty() || password.empty() || !IRCD->IsNickValid(username) || password.find_first_of("\r\n") != Anope::string::npos)
+ return Err(sess, pubkey);
+
+ SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req);
+ req->Dispatch();
+
+ BN_free(pubkey);
+ }
+ }
+};
+
+
+class ModuleSASLDHAES : public Module
+{
+ DHAES dhaes;
+
+ public:
+ ModuleSASLDHAES(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA)
+ , dhaes(this)
+ {
+ }
+};
+
+MODULE_INIT(ModuleSASLDHAES)
diff --git a/modules/extra/sasl_dh-blowfish.cpp b/modules/extra/sasl_dh-blowfish.cpp
new file mode 100644
index 000000000..e3e0eb4f9
--- /dev/null
+++ b/modules/extra/sasl_dh-blowfish.cpp
@@ -0,0 +1,194 @@
+/* RequiredLibraries: ssl,crypto */
+/* RequiredWindowsLibraries: ssleay32,libeay32 */
+
+#include "module.h"
+#include "modules/sasl.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/blowfish.h>
+
+using namespace SASL;
+
+class DHBS : public Mechanism
+{
+ void Err(Session* sess, BIGNUM* key = NULL)
+ {
+ if (key)
+ BN_free(key);
+
+ sasl->Fail(sess);
+ delete sess;
+ }
+
+ public:
+ struct DHBSSession : SASL::Session
+ {
+ DH* dh;
+ DHBSSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
+ {
+ if (!(dh = DH_new()))
+ return;
+
+ dh->g = BN_dup(dh_params->g);
+ dh->p = BN_dup(dh_params->p);
+
+ if (!DH_generate_key(dh))
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+
+ ~DHBSSession()
+ {
+ if (dh)
+ DH_free(dh);
+ }
+ };
+
+ DH* dh_params;
+ const size_t keysize;
+ SASL::Session* CreateSession(const Anope::string &uid) override
+ {
+ return new DHBSSession(this, uid, dh_params);
+ }
+
+ DHBS(Module *o) : Mechanism(o, "DH-BLOWFISH"), keysize(256 / 8)
+ {
+ if (!(dh_params = DH_new()))
+ throw ModuleException("DH_new() failed!");
+
+ if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL))
+ {
+ DH_free(dh_params);
+ throw ModuleException("Could not generate DH-params");
+ }
+ }
+
+ ~DHBS()
+ {
+ DH_free(dh_params);
+ }
+
+ void ProcessMessage(SASL::Session *session, const SASL::Message &m) override
+ {
+ DHBSSession *sess = anope_dynamic_static_cast<DHBSSession *>(session);
+
+ if (!sess->dh)
+ {
+ sasl->SendMessage(sess, "D", "A");
+ delete sess;
+ return;
+ }
+
+ if (m.type == "S")
+ {
+ // Format: [ss]<p>[ss]<g>[ss]<pub_key>
+ // Where ss is a unsigned short with the size of the key
+ const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key };
+
+ // Find the size of our buffer - initialized at 6 because of string size data
+ size_t size = 6;
+ for (size_t i = 0; i < 3; i++)
+ size += BN_num_bytes(dhval[i]);
+
+ // Fill in the DH data
+ std::vector<unsigned char> buffer(size);
+ for (size_t i = 0, pos = 0; i < 3; i++)
+ {
+ *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i]));
+ pos += 2;
+ BN_bn2bin(dhval[i], &buffer[pos]);
+ pos += BN_num_bytes(dhval[i]);
+ }
+
+ Anope::string encoded;
+ Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded);
+ sasl->SendMessage(sess, "C", encoded);
+ }
+ else if (m.type == "C")
+ {
+ // Make sure we have some data - actual size check is done later
+ if (m.data.length() < 10)
+ return Err(sess);
+
+ // Format: [ss]<key><username><\0><encrypted>
+
+ Anope::string decoded;
+ Anope::B64Decode(m.data, decoded);
+
+ // As we rely on the client giving us a null terminator at the right place,
+ // let's add one extra in case the client tries to crash us
+ const size_t decodedlen = decoded.length();
+ decoded.push_back('\0');
+
+ // Make sure we have enough data for at least the key, a one letter username, and a block of data
+ if (decodedlen < keysize + 2 + 2 + 8)
+ return Err(sess);
+
+ const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data());
+
+ // Control the size of the key
+ if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize)
+ return Err(sess);
+
+ // Convert pubkey from binary
+ size_t pos = 2;
+ BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL);
+ if (!pubkey)
+ return Err(sess);
+
+ // Find shared key
+ std::vector<unsigned char> secretkey(DH_size(sess->dh) + 1, 0);
+ if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize))
+ return Err(sess, pubkey);
+
+ // Set decryption key
+ BF_KEY BFKey;
+ BF_set_key(&BFKey, keysize, &secretkey[0]);
+
+ pos += keysize;
+ const Anope::string username = reinterpret_cast<const char*>(&data[pos]);
+ // Check that the username is valid, and that we have at least one block of data
+ // 2 + 1 + 8 = uint16_t size for keylen, \0 for username, 8 for one block of data
+ if (username.empty() || username.length() + keysize + 2 + 1 + 8 > decodedlen || !IRCD->IsNickValid(username))
+ return Err(sess, pubkey);
+
+ pos += username.length() + 1;
+ size_t size = decodedlen - pos;
+
+ // Blowfish data blocks are 64 bits wide - valid format?
+ if (size % 8)
+ return Err(sess, pubkey);
+
+ std::vector<char> decrypted(size + 1, 0);
+ for (size_t i = 0; i < size; i += 8)
+ BF_ecb_encrypt(&data[pos + i], reinterpret_cast<unsigned char*>(&decrypted[i]), &BFKey, BF_DECRYPT);
+
+ std::string password = &decrypted[0];
+ if (password.empty() || password.find_first_of("\r\n") != Anope::string::npos)
+ return Err(sess, pubkey);
+
+ SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req);
+ req->Dispatch();
+
+ BN_free(pubkey);
+ }
+ }
+};
+
+
+class ModuleSASLDHBS : public Module
+{
+ DHBS dhbs;
+
+ public:
+ ModuleSASLDHBS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA)
+ , dhbs(this)
+ {
+ }
+};
+
+MODULE_INIT(ModuleSASLDHBS)
diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/sql_authentication.cpp
index a742af096..98128d325 100644
--- a/modules/extra/m_sql_authentication.cpp
+++ b/modules/extra/sql_authentication.cpp
@@ -1,13 +1,25 @@
/*
+ * Anope IRC Services
*
- * (C) 2012-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
#include "modules/sql.h"
+#include "modules/nickserv.h"
static Module *me;
@@ -27,7 +39,7 @@ class SQLAuthenticationResult : public SQL::Interface
req->Release(me);
}
- void OnResult(const SQL::Result &r) anope_override
+ void OnResult(const SQL::Result &r) override
{
if (r.Rows() == 0)
{
@@ -45,19 +57,19 @@ class SQLAuthenticationResult : public SQL::Interface
}
catch (const SQL::Exception &) { }
- NickAlias *na = NickAlias::Find(req->GetAccount());
- BotInfo *NickServ = Config->GetClient("NickServ");
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
+ ServiceBot *NickServ = Config->GetClient("NickServ");
if (na == NULL)
{
- na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount()));
- FOREACH_MOD(OnNickRegister, (user, na, ""));
+ na = new NickServ::Nick(req->GetAccount(), new NickServ::Account(req->GetAccount()));
+ NickServ::EventManager::Get()->Dispatch(&NickServ::Event::NickRegister::OnNickRegister, user, na, "");
if (user && NickServ)
- user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
+ user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->GetNick().c_str());
}
- if (!email.empty() && email != na->nc->email)
+ if (!email.empty() && email != na->GetAccount()->GetEmail())
{
- na->nc->email = email;
+ na->GetAccount()->GetEmail() = email;
if (user && NickServ)
user->SendMessage(NickServ, _("Your email has been updated to \002%s\002."), email.c_str());
}
@@ -66,7 +78,7 @@ class SQLAuthenticationResult : public SQL::Interface
delete this;
}
- void OnError(const SQL::Result &r) anope_override
+ void OnError(const SQL::Result &r) override
{
Log(this->owner) << "m_sql_authentication: Error executing query " << r.GetQuery().query << ": " << r.GetError();
delete this;
@@ -74,6 +86,8 @@ class SQLAuthenticationResult : public SQL::Interface
};
class ModuleSQLAuthentication : public Module
+ , public EventHook<Event::PreCommand>
+ , public EventHook<Event::CheckAuthentication>
{
Anope::string engine;
Anope::string query;
@@ -88,18 +102,18 @@ class ModuleSQLAuthentication : public Module
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = conf->GetModule(this);
- this->engine = config->Get<const Anope::string>("engine");
- this->query = config->Get<const Anope::string>("query");
- this->disable_reason = config->Get<const Anope::string>("disable_reason");
+ this->engine = config->Get<Anope::string>("engine");
+ this->query = config->Get<Anope::string>("query");
+ this->disable_reason = config->Get<Anope::string>("disable_reason");
this->disable_email_reason = config->Get<Anope::string>("disable_email_reason");
this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine);
}
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
{
if (!this->disable_reason.empty() && (command->name == "nickserv/register" || command->name == "nickserv/group"))
{
@@ -116,7 +130,7 @@ class ModuleSQLAuthentication : public Module
return EVENT_CONTINUE;
}
- void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override
+ void OnCheckAuthentication(User *u, IdentifyRequest *req) override
{
if (!this->SQL)
{
diff --git a/modules/extra/m_sql_log.cpp b/modules/extra/sql_log.cpp
index 3dd6c936f..320350ced 100644
--- a/modules/extra/m_sql_log.cpp
+++ b/modules/extra/sql_log.cpp
@@ -1,15 +1,27 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
#include "modules/sql.h"
class SQLLog : public Module
+ , public EventHook<Event::LogMessage>
{
std::set<Anope::string> inited;
Anope::string table;
@@ -19,13 +31,13 @@ class SQLLog : public Module
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = conf->GetModule(this);
- this->table = config->Get<const Anope::string>("table", "logs");
+ this->table = config->Get<Anope::string>("table", "logs");
}
- void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) anope_override
+ void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) override
{
Anope::string ref_name;
ServiceReference<SQL::Provider> SQL;
@@ -96,9 +108,9 @@ class SQLLog : public Module
}
insert.SetValue("user", l->u ? l->u->nick : "");
- insert.SetValue("acc", l->nc ? l->nc->display : "");
+ insert.SetValue("acc", l->nc ? l->nc->GetDisplay() : "");
insert.SetValue("command", l->c ? l->c->name : "");
- insert.SetValue("channel", l->ci ? l->ci->name : "");
+ insert.SetValue("channel", l->ci ? l->ci->GetName() : "");
insert.SetValue("msg", msg);
SQL->Run(NULL, insert);
diff --git a/modules/extra/sql_oper.cpp b/modules/extra/sql_oper.cpp
new file mode 100644
index 000000000..17c825828
--- /dev/null
+++ b/modules/extra/sql_oper.cpp
@@ -0,0 +1,194 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/sql.h"
+
+class SQLOperResult : public SQL::Interface
+{
+ Reference<User> user;
+
+ struct SQLOperResultDeleter
+ {
+ SQLOperResult *res;
+ SQLOperResultDeleter(SQLOperResult *r) : res(r) { }
+ ~SQLOperResultDeleter() { delete res; }
+ };
+
+ void Deoper()
+ {
+ if (user->Account()->o && user->Account()->o->owner == this->owner)
+ {
+ user->Account()->o->Delete();
+ user->Account()->o = nullptr;
+
+ Log(this->owner) << "Removed services operator from " << user->nick << " (" << user->Account()->GetDisplay() << ")";
+ user->RemoveMode(Config->GetClient("OperServ"), "OPER"); // Probably not set, just incase
+ }
+ }
+
+ public:
+ SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { }
+
+ void OnResult(const SQL::Result &r) override
+ {
+ SQLOperResultDeleter d(this);
+
+ if (!user || !user->Account())
+ return;
+
+ if (r.Rows() == 0)
+ {
+ Log(LOG_DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick;
+ Deoper();
+ return;
+ }
+
+ Anope::string opertype;
+ try
+ {
+ opertype = r.Get(0, "opertype");
+ }
+ catch (const SQL::Exception &)
+ {
+ Log(this->owner) << "Expected column named \"opertype\" but one was not found";
+ return;
+ }
+
+ Log(LOG_DEBUG) << "m_sql_oper: Got result for " << user->nick << ", opertype " << opertype;
+
+ Anope::string modes;
+ try
+ {
+ modes = r.Get(0, "modes");
+ }
+ catch (const SQL::Exception &) { }
+
+ ServiceBot *OperServ = Config->GetClient("OperServ");
+ if (opertype.empty())
+ {
+ Deoper();
+ return;
+ }
+
+ OperType *ot = OperType::Find(opertype);
+ if (ot == NULL)
+ {
+ Log(this->owner) << "m_sql_oper: Oper " << user->nick << " has type " << opertype << ", but this opertype does not exist?";
+ return;
+ }
+
+ if (user->Account()->o && user->Account()->o->owner != this->owner)
+ {
+ Log(this->owner) << "Oper " << user->Account()->GetDisplay() << " has type " << ot->GetName() << ", but is already configured as an oper of type " << user->Account()->o->GetType()->GetName();
+ return;
+ }
+
+ if (!user->Account()->o || user->Account()->o->GetType() != ot)
+ {
+ Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype;
+
+ if (user->Account()->o)
+ user->Account()->o->Delete();
+
+ Oper *o = Serialize::New<Oper *>();
+ o->owner = this->owner;
+ o->SetName(user->Account()->GetDisplay());
+ o->SetType(ot);
+
+ user->Account()->o = o;
+ }
+
+ if (!user->HasMode("OPER"))
+ {
+ IRCD->SendOper(user);
+
+ if (!modes.empty())
+ user->SetModes(OperServ, "%s", modes.c_str());
+ }
+ }
+
+ void OnError(const SQL::Result &r) override
+ {
+ SQLOperResultDeleter d(this);
+ Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError();
+ }
+};
+
+class ModuleSQLOper : public Module
+ , public EventHook<Event::NickIdentify>
+{
+ Anope::string engine;
+ Anope::string query;
+
+ ServiceReference<SQL::Provider> SQL;
+
+ public:
+ ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
+ EventHook<Event::NickIdentify>(this)
+ {
+ }
+
+ ~ModuleSQLOper()
+ {
+ if (NickServ::service == nullptr)
+ return;
+
+ NickServ::nickcore_map& map = NickServ::service->GetAccountMap();
+ for (NickServ::nickcore_map::const_iterator it = map.begin(); it != map.end(); ++it)
+ {
+ NickServ::Account *nc = it->second;
+
+ if (nc->o && nc->o->owner == this)
+ {
+ nc->o->Delete();
+ nc->o = nullptr;
+ }
+ }
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *config = conf->GetModule(this);
+
+ this->engine = config->Get<Anope::string>("engine");
+ this->query = config->Get<Anope::string>("query");
+
+ this->SQL = ServiceReference<SQL::Provider>(engine);
+ }
+
+ void OnNickIdentify(User *u) override
+ {
+ if (!this->SQL)
+ {
+ Log() << "Unable to find SQL engine: " << engine;
+ return;
+ }
+
+ SQL::Query q(this->query);
+ q.SetValue("a", u->Account()->GetDisplay());
+ q.SetValue("i", u->ip.addr());
+
+ this->SQL->Run(new SQLOperResult(this, u), q);
+
+ Log(LOG_DEBUG) << "m_sql_oper: Checking authentication for " << u->Account()->GetDisplay();
+ }
+};
+
+MODULE_INIT(ModuleSQLOper)
diff --git a/modules/extra/sqlite.cpp b/modules/extra/sqlite.cpp
new file mode 100644
index 000000000..59acbf43f
--- /dev/null
+++ b/modules/extra/sqlite.cpp
@@ -0,0 +1,399 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+/* RequiredLibraries: sqlite3 */
+/* RequiredWindowsLibraries: sqlite3 */
+
+#include "module.h"
+#include "modules/sql.h"
+#include <sqlite3.h>
+
+using namespace SQL;
+
+/* SQLite3 API, based from InspiRCd */
+
+/** A SQLite result
+ */
+class SQLiteResult : public Result
+{
+ public:
+ SQLiteResult(sqlite3 *sql, unsigned int id, const Query &q, const Anope::string &fq, sqlite3_stmt *stmt) : Result(id, q, fq)
+ {
+ int cols = sqlite3_column_count(stmt);
+ for (int i = 0; i < cols; ++i)
+ this->columns.push_back(sqlite3_column_name(stmt, i));
+
+ int err;
+ while ((err = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ std::vector<SQL::Result::Value> values;
+
+ for (int i = 0; i < cols; ++i)
+ {
+ const char *data = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
+
+ Value v;
+ v.null = !data;
+ v.value = data ? data : "";
+ values.push_back(v);
+ }
+
+ this->values.push_back(values);
+ }
+
+ if (err != SQLITE_DONE)
+ {
+ error = sqlite3_errmsg(sql);
+ }
+ }
+
+ SQLiteResult(const Query &q, const Anope::string &fq, const Anope::string &err) : Result(0, q, fq, err)
+ {
+ }
+};
+
+/** A SQLite database, there can be multiple
+ */
+class SQLiteService : public Provider
+{
+ std::map<Anope::string, std::set<Anope::string> > active_schema, indexes;
+
+ Anope::string database;
+
+ sqlite3 *sql;
+
+ Anope::string Escape(const Anope::string &query);
+
+ public:
+ SQLiteService(Module *o, const Anope::string &n, const Anope::string &d);
+
+ ~SQLiteService();
+
+ void Run(Interface *i, const Query &query) override;
+
+ Result RunQuery(const Query &query);
+
+ std::vector<Query> InitSchema(const Anope::string &prefix) override;
+ std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) override;
+ std::vector<Query> CreateTable(const Anope::string &, const Anope::string &table) override;
+ std::vector<Query> AlterTable(const Anope::string &, const Anope::string &table, const Anope::string &field, bool) override;
+ std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) override;
+
+ Query BeginTransaction() override;
+ Query Commit() override;
+
+ Serialize::ID GetID(const Anope::string &) override;
+
+ Query GetTables(const Anope::string &prefix);
+
+ Anope::string BuildQuery(const Query &q);
+};
+
+class ModuleSQLite : public Module
+{
+ /* SQL connections */
+ std::map<Anope::string, SQLiteService *> SQLiteServices;
+
+ public:
+ ModuleSQLite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ {
+ }
+
+ ~ModuleSQLite()
+ {
+ for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end(); ++it)
+ delete it->second;
+ SQLiteServices.clear();
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *config = conf->GetModule(this);
+
+ for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();)
+ {
+ const Anope::string &cname = it->first;
+ SQLiteService *s = it->second;
+ int i, num;
+ ++it;
+
+ for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i)
+ if (config->GetBlock("sqlite", i)->Get<Anope::string>("name", "sqlite/main") == cname)
+ break;
+
+ if (i == num)
+ {
+ Log(LOG_NORMAL, "sqlite") << "SQLite: Removing server connection " << cname;
+
+ delete s;
+ this->SQLiteServices.erase(cname);
+ }
+ }
+
+ for (int i = 0; i < config->CountBlock("sqlite"); ++i)
+ {
+ Configuration::Block *block = config->GetBlock("sqlite", i);
+ Anope::string connname = block->Get<Anope::string>("name", "sqlite/main");
+
+ if (this->SQLiteServices.find(connname) == this->SQLiteServices.end())
+ {
+ Anope::string database = Anope::DataDir + "/" + block->Get<Anope::string>("database", "anope");
+
+ try
+ {
+ SQLiteService *ss = new SQLiteService(this, connname, database);
+ this->SQLiteServices[connname] = ss;
+
+ Log(LOG_NORMAL, "sqlite") << "SQLite: Successfully added database " << database;
+ }
+ catch (const SQL::Exception &ex)
+ {
+ Log(LOG_NORMAL, "sqlite") << "SQLite: " << ex.GetReason();
+ }
+ }
+ }
+ }
+};
+
+SQLiteService::SQLiteService(Module *o, const Anope::string &n, const Anope::string &d)
+: Provider(o, n), database(d), sql(NULL)
+{
+ int db = sqlite3_open_v2(database.c_str(), &this->sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
+ if (db != SQLITE_OK)
+ throw SQL::Exception("Unable to open SQLite database " + database + ": " + sqlite3_errmsg(this->sql));
+}
+
+SQLiteService::~SQLiteService()
+{
+ sqlite3_interrupt(this->sql);
+ sqlite3_close(this->sql);
+}
+
+void SQLiteService::Run(Interface *i, const Query &query)
+{
+ Result res = this->RunQuery(query);
+ if (!res.GetError().empty())
+ i->OnError(res);
+ else
+ i->OnResult(res);
+}
+
+Result SQLiteService::RunQuery(const Query &query)
+{
+ Anope::string real_query = this->BuildQuery(query);
+ sqlite3_stmt *stmt;
+ int err = sqlite3_prepare_v2(this->sql, real_query.c_str(), real_query.length(), &stmt, NULL);
+ if (err != SQLITE_OK)
+ {
+ return SQLiteResult(query, real_query, sqlite3_errmsg(this->sql));
+ }
+
+ int id = sqlite3_last_insert_rowid(this->sql);
+ SQLiteResult result(this->sql, id, query, real_query, stmt);
+
+ sqlite3_finalize(stmt);
+
+ return result;
+}
+
+std::vector<Query> SQLiteService::InitSchema(const Anope::string &prefix)
+{
+ std::vector<Query> queries;
+
+ Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + "id` ("
+ "`id`"
+ ")";
+ queries.push_back(t);
+
+ t = "CREATE TABLE IF NOT EXISTS `" + prefix + "objects` (`id` PRIMARY KEY, `type`)";
+ queries.push_back(t);
+
+ t = "CREATE TABLE IF NOT EXISTS `" + prefix + "edges` ("
+ "`id`,"
+ "`field`,"
+ "`other_id`,"
+ "PRIMARY KEY (`id`, `field`)"
+ ")";
+ queries.push_back(t);
+
+ t = "CREATE INDEX IF NOT EXISTS idx_edge ON `" + prefix + "edges` (other_id)";
+ queries.push_back(t);
+
+ return queries;
+}
+
+std::vector<Query> SQLiteService::Replace(const Anope::string &table, const Query &q, const std::set<Anope::string> &keys)
+{
+ std::vector<Query> queries;
+
+ Anope::string query_text = "INSERT OR IGNORE INTO `" + table + "` (";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ query_text += "`" + p.first + "`,";
+ query_text.erase(query_text.length() - 1);
+ query_text += ") VALUES (";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ query_text += "@" + p.first + "@,";
+ query_text.erase(query_text.length() - 1);
+ query_text += ")";
+
+ Query query(query_text);
+ query.parameters = q.parameters;
+ queries.push_back(query);
+
+ query_text = "UPDATE `" + table + "` SET ";
+ for (const std::pair<Anope::string, QueryData> &p : q.parameters)
+ if (!keys.count(p.first))
+ query_text += "`" + p.first + "` = @" + p.first + "@,";
+ query_text.erase(query_text.length() - 1);
+ unsigned int i = 0;
+ for (const Anope::string &key : keys)
+ {
+ if (!i++)
+ query_text += " WHERE ";
+ else
+ query_text += " AND ";
+ query_text += "`" + key + "` = @" + key + "@";
+ }
+
+ query = query_text;
+ query.parameters = q.parameters;
+ queries.push_back(query);
+
+ return queries;
+}
+
+std::vector<Query> SQLiteService::CreateTable(const Anope::string &prefix, const Anope::string &table)
+{
+ std::vector<Query> queries;
+
+ if (active_schema.find(prefix + table) == active_schema.end())
+ {
+ Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + table + "` (`id` bigint(20) NOT NULL, PRIMARY KEY (`id`))";
+ queries.push_back(t);
+
+ active_schema[prefix + table];
+ }
+
+ return queries;
+}
+
+std::vector<Query> SQLiteService::AlterTable(const Anope::string &prefix, const Anope::string &table, const Anope::string &field, bool)
+{
+ std::vector<Query> queries;
+ std::set<Anope::string> &s = active_schema[prefix + table];
+
+ if (!s.count(field))
+ {
+ Query t = "ALTER TABLE `" + prefix + table + "` ADD `" + field + "` COLLATE NOCASE";
+ queries.push_back(t);
+ s.insert(field);
+ }
+
+ return queries;
+}
+
+std::vector<Query> SQLiteService::CreateIndex(const Anope::string &table, const Anope::string &field)
+{
+ std::vector<Query> queries;
+
+ if (indexes[table].count(field))
+ return queries;
+
+ Query t = "CREATE INDEX IF NOT EXISTS idx_" + field + " ON `" + table + "` (" + field + ")";
+ queries.push_back(t);
+
+ indexes[table].insert(field);
+
+ return queries;
+}
+
+Query SQLiteService::BeginTransaction()
+{
+ return Query("BEGIN TRANSACTION");
+}
+
+Query SQLiteService::Commit()
+{
+ return Query("COMMIT");
+}
+
+Serialize::ID SQLiteService::GetID(const Anope::string &prefix)
+{
+ /* must be in a deferred or reserved transaction here for atomic row update */
+
+ Query query("SELECT `id` FROM `" + prefix + "id`");
+ Serialize::ID id;
+
+ Result res = RunQuery(query);
+ if (res.Rows())
+ {
+ id = convertTo<Serialize::ID>(res.Get(0, "id"));
+
+ Query update_query("UPDATE `" + prefix + "id` SET `id` = `id` + 1");
+ RunQuery(update_query);
+ }
+ else
+ {
+ id = 0;
+
+ Query insert_query("INSERT INTO `" + prefix + "id` (id) VALUES(@id@)");
+ insert_query.SetValue("id", 1);
+ RunQuery(insert_query);
+ }
+
+ return id;
+}
+
+Query SQLiteService::GetTables(const Anope::string &prefix)
+{
+ return Query("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';");
+}
+
+Anope::string SQLiteService::Escape(const Anope::string &query)
+{
+ char *e = sqlite3_mprintf("%q", query.c_str());
+ Anope::string buffer = e;
+ sqlite3_free(e);
+ return buffer;
+}
+
+Anope::string SQLiteService::BuildQuery(const Query &q)
+{
+ Anope::string real_query = q.query;
+
+ for (std::map<Anope::string, QueryData>::const_iterator it = q.parameters.begin(), it_end = q.parameters.end(); it != it_end; ++it)
+ {
+ const QueryData& qd = it->second;
+ Anope::string replacement;
+
+ if (qd.null)
+ replacement = "NULL";
+ else if (!qd.escape)
+ replacement = qd.data;
+ else
+ replacement = "'" + this->Escape(qd.data) + "'";
+
+ real_query = real_query.replace_all_cs("@" + it->first + "@", replacement);
+ }
+
+ return real_query;
+}
+
+MODULE_INIT(ModuleSQLite)
+
diff --git a/modules/extra/m_ssl_gnutls.cpp b/modules/extra/ssl_gnutls.cpp
index 318efe650..223b72519 100644
--- a/modules/extra/m_ssl_gnutls.cpp
+++ b/modules/extra/ssl_gnutls.cpp
@@ -1,10 +1,21 @@
/*
+ * Anope IRC Services
*
- * (C) 2014 Attila Molnar <attilamolnar@hush.com>
- * (C) 2014-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
/* RequiredLibraries: gnutls */
@@ -30,7 +41,7 @@ class MySSLService : public SSLService
/** Initialize a socket to use SSL
* @param s The socket
*/
- void Init(Socket *s) anope_override;
+ void Init(Socket *s) override;
};
class SSLSocketIO : public SocketIO
@@ -49,43 +60,43 @@ class SSLSocketIO : public SocketIO
* @param sz How much to read
* @return Number of bytes received
*/
- int Recv(Socket *s, char *buf, size_t sz) anope_override;
+ int Recv(Socket *s, char *buf, size_t sz) override;
/** Write something to the socket
* @param s The socket
* @param buf The data to write
* @param size The length of the data
*/
- int Send(Socket *s, const char *buf, size_t sz) anope_override;
+ int Send(Socket *s, const char *buf, size_t sz) override;
/** Accept a connection from a socket
* @param s The socket
* @return The new socket
*/
- ClientSocket *Accept(ListenSocket *s) anope_override;
+ ClientSocket *Accept(ListenSocket *s) override;
/** Finished accepting a connection from a socket
* @param s The socket
* @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error
*/
- SocketFlag FinishAccept(ClientSocket *cs) anope_override;
+ SocketFlag FinishAccept(ClientSocket *cs) override;
/** Connect the socket
* @param s THe socket
* @param target IP to connect to
* @param port to connect to
*/
- void Connect(ConnectionSocket *s, const Anope::string &target, int port) anope_override;
+ void Connect(ConnectionSocket *s, const Anope::string &target, int port) override;
/** Called to potentially finish a pending connection
* @param s The socket
* @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error.
*/
- SocketFlag FinishConnect(ConnectionSocket *s) anope_override;
+ SocketFlag FinishConnect(ConnectionSocket *s) override;
/** Called when the socket is destructing
*/
- void Destroy() anope_override;
+ void Destroy() override;
};
namespace GnuTLS
@@ -295,6 +306,7 @@ namespace GnuTLS
}
class GnuTLSModule : public Module
+ , public EventHook<Event::PreServerConnect>
{
GnuTLS::Init libinit;
@@ -302,7 +314,9 @@ class GnuTLSModule : public Module
GnuTLS::X509CertCredentials *cred;
MySSLService service;
- GnuTLSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), cred(NULL), service(this, "ssl")
+ GnuTLSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , cred(NULL)
+ , service(this, "ssl")
{
me = this;
this->SetPermanent(true);
@@ -332,13 +346,13 @@ class GnuTLSModule : public Module
}
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = conf->GetModule(this);
- const Anope::string certfile = config->Get<const Anope::string>("cert", "data/anope.crt");
- const Anope::string keyfile = config->Get<const Anope::string>("key", "data/anope.key");
- const Anope::string dhfile = config->Get<const Anope::string>("dh", "data/dhparams.pem");
+ const Anope::string certfile = config->Get<Anope::string>("cert", "data/anope.crt");
+ const Anope::string keyfile = config->Get<Anope::string>("key", "data/anope.key");
+ const Anope::string dhfile = config->Get<Anope::string>("dh", "data/dhparams.pem");
CheckFile(certfile);
CheckFile(keyfile);
@@ -368,7 +382,7 @@ class GnuTLSModule : public Module
Log(LOG_DEBUG) << "m_ssl_gnutls: Successfully loaded certificate " << certfile << " and private key " << keyfile;
}
- void OnPreServerConnect() anope_override
+ void OnPreServerConnect() override
{
Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink);
diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/ssl_openssl.cpp
index 00df168de..8958592e3 100644
--- a/modules/extra/m_ssl_openssl.cpp
+++ b/modules/extra/ssl_openssl.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
/* RequiredLibraries: ssl,crypto */
@@ -29,7 +40,7 @@ class MySSLService : public SSLService
/** Initialize a socket to use SSL
* @param s The socket
*/
- void Init(Socket *s) anope_override;
+ void Init(Socket *s) override;
};
class SSLSocketIO : public SocketIO
@@ -48,55 +59,57 @@ class SSLSocketIO : public SocketIO
* @param sz How much to read
* @return Number of bytes received
*/
- int Recv(Socket *s, char *buf, size_t sz) anope_override;
+ int Recv(Socket *s, char *buf, size_t sz) override;
/** Write something to the socket
* @param s The socket
* @param buf The data to write
* @param size The length of the data
*/
- int Send(Socket *s, const char *buf, size_t sz) anope_override;
+ int Send(Socket *s, const char *buf, size_t sz) override;
/** Accept a connection from a socket
* @param s The socket
* @return The new socket
*/
- ClientSocket *Accept(ListenSocket *s) anope_override;
+ ClientSocket *Accept(ListenSocket *s) override;
/** Finished accepting a connection from a socket
* @param s The socket
* @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error
*/
- SocketFlag FinishAccept(ClientSocket *cs) anope_override;
+ SocketFlag FinishAccept(ClientSocket *cs) override;
/** Connect the socket
* @param s THe socket
* @param target IP to connect to
* @param port to connect to
*/
- void Connect(ConnectionSocket *s, const Anope::string &target, int port) anope_override;
+ void Connect(ConnectionSocket *s, const Anope::string &target, int port) override;
/** Called to potentially finish a pending connection
* @param s The socket
* @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error.
*/
- SocketFlag FinishConnect(ConnectionSocket *s) anope_override;
+ SocketFlag FinishConnect(ConnectionSocket *s) override;
/** Called when the socket is destructing
*/
- void Destroy() anope_override;
+ void Destroy() override;
};
class SSLModule;
static SSLModule *me;
class SSLModule : public Module
+ , public EventHook<Event::PreServerConnect>
{
Anope::string certfile, keyfile;
public:
MySSLService service;
- SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), service(this, "ssl")
+ SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , service(this, "ssl")
{
me = this;
@@ -138,12 +151,12 @@ class SSLModule : public Module
SSL_CTX_free(server_ctx);
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *config = conf->GetModule(this);
- this->certfile = config->Get<const Anope::string>("cert", "data/anope.crt");
- this->keyfile = config->Get<const Anope::string>("key", "data/anope.key");
+ this->certfile = config->Get<Anope::string>("cert", "data/anope.crt");
+ this->keyfile = config->Get<Anope::string>("key", "data/anope.key");
if (Anope::IsFile(this->certfile.c_str()))
{
@@ -186,7 +199,7 @@ class SSLModule : public Module
}
}
- void OnPreServerConnect() anope_override
+ void OnPreServerConnect() override
{
Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink);
@@ -205,7 +218,7 @@ void MySSLService::Init(Socket *s)
{
if (s->io != &NormalSocketIO)
throw CoreException("Socket initializing SSL twice");
-
+
s->io = new SSLSocketIO();
}
@@ -283,7 +296,7 @@ ClientSocket *SSLSocketIO::Accept(ListenSocket *s)
newsocket->flags[SF_ACCEPTING] = true;
this->FinishAccept(newsocket);
-
+
return newsocket;
}
@@ -297,7 +310,7 @@ SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs)
throw SocketException("SSLSocketIO::FinishAccept called for a socket not accepted nor accepting?");
SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(cs->io);
-
+
int ret = SSL_accept(io->sslsock);
if (ret <= 0)
{
@@ -378,7 +391,7 @@ SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s)
if (!SSL_set_fd(io->sslsock, s->GetFD()))
throw SocketException("Unable to set SSL fd");
}
-
+
int ret = SSL_connect(io->sslsock);
if (ret <= 0)
{
diff --git a/modules/extra/stats/m_chanstats.cpp b/modules/extra/stats/chanstats.cpp
index e21b3641d..65a198449 100644
--- a/modules/extra/stats/m_chanstats.cpp
+++ b/modules/extra/stats/chanstats.cpp
@@ -10,9 +10,9 @@ class CommandCSSetChanstats : public Command
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
if (!ci)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
@@ -20,7 +20,7 @@ class CommandCSSetChanstats : public Command
}
EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, params[1]);
if (MOD_RESULT == EVENT_STOP)
return;
@@ -46,7 +46,7 @@ class CommandCSSetChanstats : public Command
this->OnSyntaxError(source, "");
}
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
@@ -65,7 +65,7 @@ class CommandNSSetChanstats : public Command
}
void Run(CommandSource &source, const Anope::string &user, const Anope::string &param, bool saset = false)
{
- NickAlias *na = NickAlias::Find(user);
+ NickServ::Nick *na = NickServ::FindNick(user);
if (!na)
{
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
@@ -73,25 +73,25 @@ class CommandNSSetChanstats : public Command
}
EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, na->nc, param));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, na->GetAccount(), param);
if (MOD_RESULT == EVENT_STOP)
return;
if (param.equals_ci("ON"))
{
- Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable chanstats for " << na->nc->display;
- na->nc->Extend<bool>("NS_STATS");
+ Log(na->GetAccount() == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable chanstats for " << na->GetAccount()->GetDisplay();
+ na->GetAccount()->Extend<bool>("NS_STATS");
if (saset)
- source.Reply(_("Chanstats statistics are now enabled for %s"), na->nc->display.c_str());
+ source.Reply(_("Chanstats statistics are now enabled for %s"), na->GetAccount()->GetDisplay().c_str());
else
source.Reply(_("Chanstats statistics are now enabled for your nick."));
}
else if (param.equals_ci("OFF"))
{
- Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable chanstats for " << na->nc->display;
- na->nc->Shrink<bool>("NS_STATS");
+ Log(na->GetAccount() == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable chanstats for " << na->GetAccount()->GetDisplay();
+ na->GetAccount()->Shrink<bool>("NS_STATS");
if (saset)
- source.Reply(_("Chanstats statistics are now disabled for %s"), na->nc->display.c_str());
+ source.Reply(_("Chanstats statistics are now disabled for %s"), na->GetAccount()->GetDisplay().c_str());
else
source.Reply(_("Chanstats statistics are now disabled for your nick."));
}
@@ -99,12 +99,12 @@ class CommandNSSetChanstats : public Command
this->OnSyntaxError(source, "CHANSTATS");
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
- this->Run(source, source.nc->display, params[0]);
+ this->Run(source, source.nc->GetDisplay(), params[0]);
}
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
@@ -122,12 +122,12 @@ class CommandNSSASetChanstats : public CommandNSSetChanstats
this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
this->Run(source, params[0], params[1], true);
}
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
@@ -141,11 +141,11 @@ class MySQLInterface : public SQL::Interface
public:
MySQLInterface(Module *o) : SQL::Interface(o) { }
- void OnResult(const SQL::Result &r) anope_override
+ void OnResult(const SQL::Result &r) override
{
}
- void OnError(const SQL::Result &r) anope_override
+ void OnError(const SQL::Result &r) override
{
if (!r.GetQuery().query.empty())
Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
@@ -156,7 +156,7 @@ class MySQLInterface : public SQL::Interface
class MChanstats : public Module
{
- SerializableExtensibleItem<bool> cs_stats, ns_stats;
+ Serialize::Field<bool> cs_stats, ns_stats;
CommandCSSetChanstats commandcssetchanstats;
@@ -200,7 +200,7 @@ class MChanstats : public Module
const Anope::string GetDisplay(User *u)
{
if (u && u->Account() && ns_stats.HasExt(u->Account()))
- return u->Account()->display;
+ return u->Account()->GetDisplay();
else
return "";
}
@@ -484,16 +484,16 @@ class MChanstats : public Module
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
- prefix = block->Get<const Anope::string>("prefix", "anope_");
- SmileysHappy = block->Get<const Anope::string>("SmileysHappy");
- SmileysSad = block->Get<const Anope::string>("SmileysSad");
- SmileysOther = block->Get<const Anope::string>("SmileysOther");
+ prefix = block->Get<Anope::string>("prefix", "anope_");
+ SmileysHappy = block->Get<Anope::string>("SmileysHappy");
+ SmileysSad = block->Get<Anope::string>("SmileysSad");
+ SmileysOther = block->Get<Anope::string>("SmileysOther");
NSDefChanstats = block->Get<bool>("ns_def_chanstats");
CSDefChanstats = block->Get<bool>("cs_def_chanstats");
- Anope::string engine = block->Get<const Anope::string>("engine");
+ Anope::string engine = block->Get<Anope::string>("engine");
this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
if (sql)
this->CheckTables();
@@ -501,7 +501,7 @@ class MChanstats : public Module
Log(this) << "no database connection to " << engine;
}
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override
{
if (!show_all)
return;
@@ -509,15 +509,15 @@ class MChanstats : public Module
info.AddOption(_("Chanstats"));
}
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
{
if (!show_hidden)
return;
- if (ns_stats.HasExt(na->nc))
+ if (ns_stats.HasExt(na->GetAccount()))
info.AddOption(_("Chanstats"));
}
- void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override
{
if (!source || !source->Account() || !c->ci || !cs_stats.HasExt(c->ci))
return;
@@ -527,13 +527,13 @@ class MChanstats : public Module
this->RunQuery(query);
}
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override
{
this->OnModeChange(c, setter.GetUser());
return EVENT_CONTINUE;
}
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *, const Anope::string &param) anope_override
+ EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *, const Anope::string &param) override
{
this->OnModeChange(c, setter.GetUser());
return EVENT_CONTINUE;
@@ -552,7 +552,7 @@ class MChanstats : public Module
}
public:
- void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override
+ void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) override
{
if (!cu->chan->ci || !cs_stats.HasExt(cu->chan->ci))
return;
@@ -568,7 +568,7 @@ class MChanstats : public Module
this->RunQuery(query);
}
- void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
+ void OnPrivmsg(User *u, Channel *c, Anope::string &msg) override
{
if (!c->ci || !cs_stats.HasExt(c->ci))
return;
@@ -609,29 +609,29 @@ class MChanstats : public Module
this->RunQuery(query);
}
- void OnDelCore(NickCore *nc) anope_override
+ void OnDelCore(NickServ::Account *nc) override
{
query = "DELETE FROM `" + prefix + "chanstats` WHERE `nick` = @nick@;";
- query.SetValue("nick", nc->display);
+ query.SetValue("nick", nc->GetDisplay());
this->RunQuery(query);
}
- void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override
+ void OnChangeCoreDisplay(NickServ::Account *nc, const Anope::string &newdisplay) override
{
query = "CALL " + prefix + "chanstats_proc_chgdisplay(@old_display@, @new_display@);";
- query.SetValue("old_display", nc->display);
+ query.SetValue("old_display", nc->GetDisplay());
query.SetValue("new_display", newdisplay);
this->RunQuery(query);
}
- void OnDelChan(ChannelInfo *ci) anope_override
+ void OnDelChan(ChanServ::Channel *ci) override
{
query = "DELETE FROM `" + prefix + "chanstats` WHERE `chan` = @channel@;";
- query.SetValue("channel", ci->name);
+ query.SetValue("channel", ci->GetName());
this->RunQuery(query);
}
- void OnChanRegistered(ChannelInfo *ci)
+ void OnChanRegistered(ChanServ::Channel *ci)
{
if (CSDefChanstats)
ci->Extend<bool>("CS_STATS");
@@ -640,7 +640,7 @@ class MChanstats : public Module
void OnNickRegister(User *user, NickAlias *na, const Anope::string &)
{
if (NSDefChanstats)
- na->nc->Extend<bool>("NS_STATS");
+ na->GetAccount()->Extend<bool>("NS_STATS");
}
};
diff --git a/modules/extra/stats/cs_fantasy_stats.cpp b/modules/extra/stats/cs_fantasy_stats.cpp
index 37830abb1..118a7e496 100644
--- a/modules/extra/stats/cs_fantasy_stats.cpp
+++ b/modules/extra/stats/cs_fantasy_stats.cpp
@@ -1,6 +1,6 @@
/* Chanstats core functions
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -17,11 +17,11 @@ class MySQLInterface : public SQL::Interface
public:
MySQLInterface(Module *o) : SQL::Interface(o) { }
- void OnResult(const SQL::Result &r) anope_override
+ void OnResult(const SQL::Result &r) override
{
}
- void OnError(const SQL::Result &r) anope_override
+ void OnError(const SQL::Result &r) override
{
if (!r.GetQuery().query.empty())
Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
@@ -73,10 +73,10 @@ class CSStats : public Module
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
- prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_");
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine"));
+ prefix = conf->GetModule("m_chanstats")->Get<Anope::string>("prefix", "anope_");
+ this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<Anope::string>("engine"));
}
SQL::Result RunQuery(const SQL::Query &query)
@@ -113,8 +113,8 @@ class CSStats : public Module
channel = params[0];
else
{
- if (NickAlias *na = NickAlias::Find(params[0]))
- display = na->nc->display;
+ if (NickServ::Nick *na = NickServ::FindNick(params[0]))
+ display = na->GetAccount()->GetDisplay();
else
{
source.Reply(_("%s not found."), params[0].c_str());
@@ -125,7 +125,7 @@ class CSStats : public Module
}
if (display.empty())
- display = source.nc->display;
+ display = source.nc->GetDisplay();
try
{
diff --git a/modules/extra/stats/cs_fantasy_top.cpp b/modules/extra/stats/cs_fantasy_top.cpp
index 0de75d855..82480ffc3 100644
--- a/modules/extra/stats/cs_fantasy_top.cpp
+++ b/modules/extra/stats/cs_fantasy_top.cpp
@@ -1,6 +1,6 @@
/* Chanstats core functions
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -17,11 +17,11 @@ class MySQLInterface : public SQL::Interface
public:
MySQLInterface(Module *o) : SQL::Interface(o) { }
- void OnResult(const SQL::Result &r) anope_override
+ void OnResult(const SQL::Result &r) override
{
}
- void OnError(const SQL::Result &r) anope_override
+ void OnError(const SQL::Result &r) override
{
if (!r.GetQuery().query.empty())
Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
@@ -98,10 +98,10 @@ class CSTop : public Module
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
- prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_");
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine"));
+ prefix = conf->GetModule("m_chanstats")->Get<Anope::string>("prefix", "anope_");
+ this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<Anope::string>("engine"));
}
SQL::Result RunQuery(const SQL::Query &query)
@@ -122,7 +122,7 @@ class CSTop : public Module
if (!params.empty())
channel = params[0];
else if (source.c && source.c->ci)
- channel = source.c->ci->name;
+ channel = source.c->ci->GetName();
if (!is_global && channel.empty())
is_global = true;
@@ -151,7 +151,7 @@ class CSTop : public Module
{
source.Reply(_("%2lu \002%-16s\002 letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"),
i+1, res.Get(i, "nick").c_str(), res.Get(i, "letters").c_str(),
- res.Get(i, "words").c_str(), res.Get(i, "line").c_str(),
+ res.Get(i, "words").c_str(), res.Get(i, "line").c_str(),
res.Get(i, "smileys").c_str(), res.Get(i, "actions").c_str());
}
}
diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp
index a00181304..e0c03edbd 100644
--- a/modules/extra/stats/irc2sql/irc2sql.cpp
+++ b/modules/extra/stats/irc2sql/irc2sql.cpp
@@ -11,21 +11,21 @@ void IRC2SQL::OnShutdown()
void IRC2SQL::OnReload(Configuration::Conf *conf)
{
Configuration::Block *block = Config->GetModule(this);
- prefix = block->Get<const Anope::string>("prefix", "anope_");
- GeoIPDB = block->Get<const Anope::string>("geoip_database");
+ prefix = block->Get<Anope::string>("prefix", "anope_");
+ GeoIPDB = block->Get<Anope::string>("geoip_database");
ctcpuser = block->Get<bool>("ctcpuser", "no");
ctcpeob = block->Get<bool>("ctcpeob", "yes");
- Anope::string engine = block->Get<const Anope::string>("engine");
+ Anope::string engine = block->Get<Anope::string>("engine");
this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
if (sql)
this->CheckTables();
else
Log() << "IRC2SQL: no database connection to " << engine;
- const Anope::string &snick = block->Get<const Anope::string>("client");
+ const Anope::string &snick = block->Get<Anope::string>("client");
if (snick.empty())
throw ConfigException(Module::name + ": <client> must be defined");
- StatServ = BotInfo::Find(snick, true);
+ StatServ = ServiceBot::Find(snick, true);
if (!StatServ)
throw ConfigException(Module::name + ": no bot named " + snick);
@@ -99,7 +99,7 @@ void IRC2SQL::OnUserConnect(User *u, bool &exempt)
query.SetValue("ident", u->GetIdent());
query.SetValue("vident", u->GetVIdent());
query.SetValue("secure", u->HasMode("SSL") || u->HasExt("ssl") ? "Y" : "N");
- query.SetValue("account", u->Account() ? u->Account()->display : "");
+ query.SetValue("account", u->Account() ? u->Account()->GetDisplay() : "");
query.SetValue("fingerprint", u->fingerprint);
query.SetValue("signon", u->signon);
query.SetValue("server", u->server->GetName());
@@ -167,7 +167,7 @@ void IRC2SQL::OnUserLogin(User *u)
{
query = "UPDATE `" + prefix + "user` SET account=@account@ WHERE nick=@nick@";
query.SetValue("nick", u->nick);
- query.SetValue("account", u->Account() ? u->Account()->display : "");
+ query.SetValue("account", u->Account() ? u->Account()->GetDisplay() : "");
this->RunQuery(query);
}
@@ -221,7 +221,7 @@ void IRC2SQL::OnJoinChannel(User *u, Channel *c)
this->RunQuery(query);
}
-EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param)
+EventReturn IRC2SQL::OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param)
{
query = "UPDATE `" + prefix + "chan` SET modes=@modes@ WHERE channel=@channel@";
query.SetValue("channel", c->name);
@@ -230,7 +230,7 @@ EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, Channel
return EVENT_CONTINUE;
}
-EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param)
+EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param)
{
this->OnChannelModeSet(c, setter, mode, param);
return EVENT_CONTINUE;
@@ -264,7 +264,7 @@ void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user
this->RunQuery(query);
}
-void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message)
+void IRC2SQL::OnBotNotice(User *u, ServiceBot *bi, Anope::string &message)
{
Anope::string versionstr;
if (bi != StatServ)
diff --git a/modules/extra/stats/irc2sql/irc2sql.h b/modules/extra/stats/irc2sql/irc2sql.h
index a7396fcf0..b73e95cf1 100644
--- a/modules/extra/stats/irc2sql/irc2sql.h
+++ b/modules/extra/stats/irc2sql/irc2sql.h
@@ -6,11 +6,11 @@ class MySQLInterface : public SQL::Interface
public:
MySQLInterface(Module *o) : SQL::Interface(o) { }
- void OnResult(const SQL::Result &r) anope_override
+ void OnResult(const SQL::Result &r) override
{
}
- void OnError(const SQL::Result &r) anope_override
+ void OnError(const SQL::Result &r) override
{
if (!r.GetQuery().query.empty())
Log(LOG_DEBUG) << "m_irc2sql: Error executing query " << r.finished_query << ": " << r.GetError();
@@ -27,7 +27,7 @@ class IRC2SQL : public Module
std::vector<Anope::string> TableList, ProcedureList, EventList;
Anope::string prefix, GeoIPDB;
bool quitting, introduced_myself, ctcpuser, ctcpeob, firstrun;
- BotInfo *StatServ;
+ ServiceBot *StatServ;
PrimitiveExtensibleItem<bool> versionreply;
void RunQuery(const SQL::Query &q);
@@ -48,31 +48,31 @@ class IRC2SQL : public Module
introduced_myself = false;
}
- void OnShutdown() anope_override;
- void OnReload(Configuration::Conf *config) anope_override;
- void OnNewServer(Server *server) anope_override;
- void OnServerQuit(Server *server) anope_override;
- void OnUserConnect(User *u, bool &exempt) anope_override;
- void OnUserQuit(User *u, const Anope::string &msg) anope_override;
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override;
- void OnUserAway(User *u, const Anope::string &message) anope_override;
- void OnFingerprint(User *u) anope_override;
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override;
- void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override;
- void OnUserLogin(User *u) anope_override;
- void OnNickLogout(User *u) anope_override;
- void OnSetDisplayedHost(User *u) anope_override;
+ void OnShutdown() override;
+ void OnReload(Configuration::Conf *config) override;
+ void OnNewServer(Server *server) override;
+ void OnServerQuit(Server *server) override;
+ void OnUserConnect(User *u, bool &exempt) override;
+ void OnUserQuit(User *u, const Anope::string &msg) override;
+ void OnUserNickChange(User *u, const Anope::string &oldnick) override;
+ void OnUserAway(User *u, const Anope::string &message) override;
+ void OnFingerprint(User *u) override;
+ void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override;
+ void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override;
+ void OnUserLogin(User *u) override;
+ void OnNickLogout(User *u) override;
+ void OnSetDisplayedHost(User *u) override;
- void OnChannelCreate(Channel *c) anope_override;
- void OnChannelDelete(Channel *c) anope_override;
- void OnLeaveChannel(User *u, Channel *c) anope_override;
- void OnJoinChannel(User *u, Channel *c) anope_override;
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override;
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override;
+ void OnChannelCreate(Channel *c) override;
+ void OnChannelDelete(Channel *c) override;
+ void OnLeaveChannel(User *u, Channel *c) override;
+ void OnJoinChannel(User *u, Channel *c) override;
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
+ EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
- void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override;
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override;
- void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) anope_override;
+ void OnBotNotice(User *u, ServiceBot *bi, Anope::string &message) override;
};
diff --git a/modules/fantasy.cpp b/modules/fantasy.cpp
index 023ef286f..20585f527 100644
--- a/modules/fantasy.cpp
+++ b/modules/fantasy.cpp
@@ -1,15 +1,25 @@
-/* Fantasy functionality
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
+#include "modules/fantasy.h"
+#include "modules/botserv/info.h"
class CommandBSSetFantasy : public Command
{
@@ -20,20 +30,20 @@ class CommandBSSetFantasy : public Command
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
+ ChanServ::Channel *ci = ChanServ::Find(params[0]);
const Anope::string &value = params[1];
if (ci == NULL)
{
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
+ source.Reply(_("Channel \002{0}\002 isn't registered."), params[0]);
return;
}
if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. You do not have the \002{0}\002 privilege on \002{1}\002."), "SET", ci->GetName());
return;
}
@@ -46,24 +56,24 @@ class CommandBSSetFantasy : public Command
if (value.equals_ci("ON"))
{
bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy";
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy";
- ci->Extend<bool>("BS_FANTASY");
- source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
+ ci->SetS<bool>("BS_FANTASY", true);
+ source.Reply(_("Fantasy mode is now \002on\002 on channel \002{0}\002."), ci->GetName());
}
else if (value.equals_ci("OFF"))
{
bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy";
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy";
- ci->Shrink<bool>("BS_FANTASY");
- source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
+ ci->UnsetS<bool>("BS_FANTASY");
+ source.Reply(_("Fantasy mode is now \002off\002 on channel \002{0}\002."), ci->GetName());
}
else
this->OnSyntaxError(source, source.command);
}
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(_(" \n"
@@ -75,26 +85,31 @@ class CommandBSSetFantasy : public Command
"Note that users wanting to use fantaisist\n"
"commands MUST have enough access for both\n"
"the FANTASIA and the command they are executing."),
- Config->GetModule(this->owner)->Get<const Anope::string>("fantasycharacter", "!").c_str());
+ Config->GetModule(this->GetOwner())->Get<Anope::string>("fantasycharacter", "!").c_str());
return true;
}
};
class Fantasy : public Module
+ , public EventHook<Event::Privmsg>
+ , public EventHook<Event::ServiceBotEvent>
{
- SerializableExtensibleItem<bool> fantasy;
+ Serialize::Field<ChanServ::Channel, bool> fantasy;
CommandBSSetFantasy commandbssetfantasy;
public:
- Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- fantasy(this, "BS_FANTASY"), commandbssetfantasy(this)
+ Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::Privmsg>(this)
+ , EventHook<Event::ServiceBotEvent>(this)
+ , fantasy(this, "BS_FANTASY")
+ , commandbssetfantasy(this)
{
}
- void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
+ void OnPrivmsg(User *u, Channel *c, Anope::string &msg) override
{
- if (!u || !c || !c->ci || !c->ci->bi || msg.empty() || msg[0] == '\1')
+ if (!u || !c || !c->ci || !c->ci->GetBot() || msg.empty() || msg[0] == '\1')
return;
if (Config->GetClient("BotServ") && !fantasy.HasExt(c->ci))
@@ -109,7 +124,7 @@ class Fantasy : public Module
Anope::string normalized_param0 = Anope::NormalizeBuffer(params[0]);
Anope::string fantasy_chars = Config->GetModule(this)->Get<Anope::string>("fantasycharacter", "!");
- if (!normalized_param0.find(c->ci->bi->nick))
+ if (!normalized_param0.find(c->ci->GetBot()->nick))
{
params.erase(params.begin());
}
@@ -146,7 +161,7 @@ class Fantasy : public Module
return;
const CommandInfo &info = it->second;
- ServiceReference<Command> cmd("Command", info.name);
+ ServiceReference<Command> cmd(info.name);
if (!cmd)
{
Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for non-existent service " << info.name << "!";
@@ -173,22 +188,22 @@ class Fantasy : public Module
if (params.size() < cmd->min_params)
return;
- CommandSource source(u->nick, u, u->Account(), u, c->ci->bi);
+ CommandSource source(u->nick, u, u->Account(), u, c->ci->GetBot());
source.c = c;
source.command = it->first;
source.permission = info.permission;
- AccessGroup ag = c->ci->AccessFor(u);
+ ChanServ::AccessGroup ag = c->ci->AccessFor(u);
bool has_fantasia = ag.HasPriv("FANTASIA") || source.HasPriv("botserv/fantasy");
EventReturn MOD_RESULT;
if (has_fantasia)
{
- FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotFantasy::OnBotFantasy, source, cmd, c->ci, params);
}
else
{
- FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotNoFantasyAccess::OnBotNoFantasyAccess, source, cmd, c->ci, params);
}
if (MOD_RESULT == EVENT_STOP || !has_fantasia)
@@ -197,18 +212,18 @@ class Fantasy : public Module
if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
return;
- FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, cmd, params));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreCommand::OnPreCommand, source, cmd, params);
if (MOD_RESULT == EVENT_STOP)
return;
- Reference<NickCore> nc_reference(u->Account());
+ Reference<NickServ::Account> nc_reference(u->Account());
cmd->Execute(source, params);
if (!nc_reference)
source.nc = NULL;
- FOREACH_MOD(OnPostCommand, (source, cmd, params));
+ EventManager::Get()->Dispatch(&Event::PostCommand::OnPostCommand, source, cmd, params);
}
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info)
+ void OnServiceBot(CommandSource &source, ServiceBot *bi, ChanServ::Channel *ci, InfoFormatter &info) override
{
if (fantasy.HasExt(ci))
info.AddOption(_("Fantasy"));
diff --git a/modules/global/CMakeLists.txt b/modules/global/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/global/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/global/global.cpp b/modules/global/global.cpp
new file mode 100644
index 000000000..af4add942
--- /dev/null
+++ b/modules/global/global.cpp
@@ -0,0 +1,68 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/global.h"
+
+class CommandGLGlobal : public Command
+{
+ ServiceReference<Global::GlobalService> service;
+
+ public:
+ CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1)
+ {
+ this->SetDesc(_("Send a message to all users"));
+ this->SetSyntax(_("\037message\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &msg = params[0];
+
+ if (!service)
+ {
+ source.Reply("No global reference, is global loaded?");
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this);
+ service->SendGlobal(NULL, source.GetNick(), msg);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows Services Operators to send a message to all users on the network."
+ " The message will be sent from \002{0}\002."), source.service->nick);
+ return true;
+ }
+};
+
+class GLGlobal : public Module
+{
+ CommandGLGlobal commandglglobal;
+
+ public:
+ GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandglglobal(this)
+ {
+
+ }
+};
+
+MODULE_INIT(GLGlobal)
diff --git a/modules/global/main/CMakeLists.txt b/modules/global/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/global/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/global/main/global.cpp b/modules/global/main/global.cpp
new file mode 100644
index 000000000..cbc0e0757
--- /dev/null
+++ b/modules/global/main/global.cpp
@@ -0,0 +1,119 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/help.h"
+#include "modules/global.h"
+
+class GlobalCore : public Module
+ , public Global::GlobalService
+ , public EventHook<Event::Restart>
+ , public EventHook<Event::Shutdown>
+ , public EventHook<Event::NewServer>
+ , public EventHook<Event::Help>
+{
+ Reference<ServiceBot> Global;
+
+ void ServerGlobal(ServiceBot *sender, Server *s, const Anope::string &message)
+ {
+ if (s != Me && !s->IsJuped())
+ s->Notice(sender, message);
+ for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
+ this->ServerGlobal(sender, s->GetLinks()[i], message);
+ }
+
+ public:
+ GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , EventHook<Event::Restart>(this)
+ , EventHook<Event::Shutdown>(this)
+ , EventHook<Event::NewServer>(this)
+ , EventHook<Event::Help>(this)
+ , GlobalService(this)
+ {
+ }
+
+ void SendGlobal(ServiceBot *sender, const Anope::string &source, const Anope::string &message) override
+ {
+ if (Me->GetLinks().empty())
+ return;
+ if (!sender)
+ sender = Global;
+ if (!sender)
+ return;
+
+ Anope::string rmessage;
+
+ if (!source.empty() && !Config->GetModule("global")->Get<bool>("anonymousglobal"))
+ rmessage = "[" + source + "] " + message;
+ else
+ rmessage = message;
+
+ this->ServerGlobal(sender, Servers::GetUplink(), rmessage);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &glnick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (glnick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(glnick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + glnick);
+
+ Global = bi;
+ }
+
+ void OnRestart() override
+ {
+ const Anope::string &gl = Config->GetModule(this)->Get<Anope::string>("globaloncycledown");
+ if (!gl.empty())
+ this->SendGlobal(Global, "", gl);
+ }
+
+ void OnShutdown() override
+ {
+ const Anope::string &gl = Config->GetModule(this)->Get<Anope::string>("globaloncycledown");
+ if (!gl.empty())
+ this->SendGlobal(Global, "", gl);
+ }
+
+ void OnNewServer(Server *s) override
+ {
+ const Anope::string &gl = Config->GetModule(this)->Get<Anope::string>("globaloncycleup");
+ if (!gl.empty() && !Me->IsSynced())
+ s->Notice(Global, gl);
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *Global)
+ return EVENT_CONTINUE;
+ source.Reply(_("%s commands:"), Global->nick.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ }
+};
+
+MODULE_INIT(GlobalCore)
+
diff --git a/modules/greet.cpp b/modules/greet.cpp
new file mode 100644
index 000000000..d43becd16
--- /dev/null
+++ b/modules/greet.cpp
@@ -0,0 +1,223 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/botserv/info.h"
+#include "modules/nickserv/set.h"
+
+class CommandBSSetGreet : public Command
+{
+ public:
+ CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2)
+ {
+ this->SetDesc(_("Enable greet messages"));
+ this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &value = params[1];
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ ChanServ::Channel *ci = ChanServ::Find(chan);
+ if (ci == NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
+ return;
+ }
+
+ if (value.equals_ci("ON"))
+ {
+ bool override = !source.AccessFor(ci).HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets";
+
+ ci->SetS<bool>("BS_GREET", true);
+ source.Reply(_("Greet mode for \002{0}\002 is now \002on\002."), ci->GetName());
+ }
+ else if (value.equals_ci("OFF"))
+ {
+ bool override = !source.AccessFor(ci).HasPriv("SET");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets";
+
+ ci->UnsetS<bool>("BS_GREET");
+ source.Reply(_("Greet mode for \002{0}\002 is now \002off\002."), ci->GetName());
+ }
+ else
+ this->OnSyntaxError(source, source.command);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables \002greet\002 mode on \037channel\037."
+ " When \002greet\002 mode is enabled, the assigned service bot will display the greet messages of users joining the channel, if they have the \002{0}\002 privilege."),
+ "GREET");
+ return true;
+ }
+};
+
+class CommandNSSetGreet : public Command
+{
+ public:
+ CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Associate a greet message with your nickname"));
+ this->SetSyntax(_("\037message\037"));
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (!param.empty())
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->GetDisplay();
+ nc->SetS<Anope::string>("greet", param);
+ source.Reply(_("Greet message for \002{0}\002 changed to \002{1}\002."), nc->GetDisplay(), param);
+ }
+ else
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->GetDisplay();
+ nc->UnsetS<Anope::string>("greet");
+ source.Reply(_("Greet message for \002{0}\002 unset."), nc->GetDisplay());
+ }
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params.size() > 0 ? params[0] : "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets your greet to \037message\037. Your greet is displayed when you enter channels that have the greet option enabled if you have the \002{0}\002 privilege on the channel."),
+ "GREET");
+ return true;
+ }
+};
+
+class CommandNSSASetGreet : public CommandNSSetGreet
+{
+ public:
+ CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037user\037 \037message\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params.size() > 1 ? params[1] : "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets the greet for \037user\037 to \037message\037. Greet messages are displayed when users enter channels that have the greet option enabiled if they have the \002{0}\002 privilege on the channel."),
+ "GREET");
+ return true;
+ }
+};
+
+class Greet : public Module
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::NickInfo>
+ , public EventHook<Event::ServiceBotEvent>
+{
+ /* channel setting for whether or not greet should be shown */
+ Serialize::Field<ChanServ::Channel, bool> bs_greet;
+ /* user greets */
+ Serialize::Field<NickServ::Account, Anope::string> ns_greet;
+
+ CommandBSSetGreet commandbssetgreet;
+ CommandNSSetGreet commandnssetgreet;
+ CommandNSSASetGreet commandnssasetgreet;
+
+ public:
+ Greet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::JoinChannel>(this)
+ , EventHook<Event::NickInfo>(this)
+ , EventHook<Event::ServiceBotEvent>(this)
+ , bs_greet(this, "BS_GREET")
+ , ns_greet(this, "greet")
+ , commandbssetgreet(this)
+ , commandnssetgreet(this)
+ , commandnssasetgreet(this)
+ {
+ }
+
+ void OnJoinChannel(User *user, Channel *c) override
+ {
+ /* 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->ci || !c->ci->GetBot() || !user->server->IsSynced() || !user->Account())
+ return;
+
+ Anope::string greet = ns_greet.Get(user->Account());
+ if (bs_greet.HasExt(c->ci) && !greet.empty() && c->FindUser(c->ci->GetBot()) && c->ci->AccessFor(user).HasPriv("GREET"))
+ {
+ IRCD->SendPrivmsg(c->ci->GetBot(), c->name, "[%s] %s", user->Account()->GetDisplay().c_str(), greet.c_str());
+ c->ci->GetBot()->lastmsg = Anope::CurTime;
+ }
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
+ {
+ Anope::string greet = ns_greet.Get(na->GetAccount());
+ if (!greet.empty())
+ info[_("Greet")] = greet;
+ }
+
+ void OnServiceBot(CommandSource &source, ServiceBot *bi, ChanServ::Channel *ci, InfoFormatter &info) override
+ {
+ if (bs_greet.HasExt(ci))
+ info.AddOption(_("Greet"));
+ }
+};
+
+MODULE_INIT(Greet)
diff --git a/modules/commands/help.cpp b/modules/help.cpp
index f6e459bde..b032d11a1 100644
--- a/modules/commands/help.cpp
+++ b/modules/help.cpp
@@ -1,20 +1,27 @@
-/* Core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
+#include "modules/help.h"
class CommandHelp : public Command
{
- static const unsigned help_wrap_len = 40;
-
static CommandGroup *FindGroup(const Anope::string &name)
{
for (unsigned i = 0; i < Config->CommandGroups.size(); ++i)
@@ -34,15 +41,14 @@ class CommandHelp : public Command
this->AllowUnregistered(true);
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnPreHelp, MOD_RESULT, (source, params));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::Help::OnPreHelp, source, params);
if (MOD_RESULT == EVENT_STOP)
return;
-
+
Anope::string source_command = source.command;
- const BotInfo *bi = source.service;
+ const ServiceBot *bi = source.service;
const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands;
bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
@@ -54,7 +60,7 @@ class CommandHelp : public Command
GroupInfo groups;
if (all)
- source.Reply(_("All available commands for \002%s\002:"), source.service->nick.c_str());
+ source.Reply(_("All available commands for \002{0}\002:"), source.service->nick);
for (CommandInfo::map::const_iterator it = map.begin(), it_end = map.end(); it != it_end; ++it)
{
@@ -70,7 +76,7 @@ class CommandHelp : public Command
if (cmd != it->first && map.count(cmd))
continue;
- ServiceReference<Command> c("Command", info.name);
+ ServiceReference<Command> c(info.name);
if (!c)
continue;
@@ -100,31 +106,21 @@ class CommandHelp : public Command
CommandGroup *gr = it->first;
source.Reply(" ");
- source.Reply("%s", gr->description.c_str());
+ source.Reply("{0}", gr->description);
Anope::string buf;
for (std::list<Anope::string>::iterator it2 = it->second.begin(), it2_end = it->second.end(); it2 != it2_end; ++it2)
{
const Anope::string &c_name = *it2;
-
buf += ", " + c_name;
-
- if (buf.length() > help_wrap_len)
- {
- source.Reply(" %s", buf.substr(2).c_str());
- buf.clear();
- }
}
if (buf.length() > 2)
- {
- source.Reply(" %s", buf.substr(2).c_str());
- buf.clear();
- }
+ source.Reply(" {0}", buf.substr(2));
}
if (!groups.empty())
{
source.Reply(" ");
- source.Reply(_("Use the \002%s ALL\002 command to list all commands and their descriptions."), source_command.c_str());
+ source.Reply(_("Use the \002{0} ALL\002 command to list all commands and their descriptions."), source_command);
}
}
else
@@ -143,17 +139,19 @@ class CommandHelp : public Command
const CommandInfo &info = it->second;
- ServiceReference<Command> c("Command", info.name);
+ ServiceReference<Command> c(info.name);
if (!c)
continue;
if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
continue;
-
+
// Allow unregistered users to see help for commands that they explicitly request help for
const Anope::string &subcommand = params.size() > max ? params[max] : "";
- source.command = full_command;
+ source.command = it->first;
+
+ c->SendSyntax(source);
if (!c->OnHelp(source, subcommand))
continue;
@@ -163,7 +161,7 @@ class CommandHelp : public Command
if (!info.permission.empty())
{
source.Reply(" ");
- source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), info.permission.c_str());
+ source.Reply(_("Access to this command requires the permission \002{0}\002 to be present in your opertype."), info.permission);
}
if (!c->AllowUnregistered() && !source.nc)
{
@@ -181,12 +179,10 @@ class CommandHelp : public Command
}
if (helped == false)
- source.Reply(_("No help available for \002%s\002."), params[0].c_str());
+ source.Reply(_("No help available for \002{0}\002."), params[0]);
}
-
- FOREACH_MOD(OnPostHelp, (source, params));
- return;
+ EventManager::Get()->Dispatch(&Event::Help::OnPostHelp, source, params);
}
};
@@ -195,8 +191,8 @@ class Help : public Module
CommandHelp commandhelp;
public:
- Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhelp(this)
+ Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhelp(this)
{
}
diff --git a/modules/helpchan.cpp b/modules/helpchan.cpp
new file mode 100644
index 000000000..294677a3f
--- /dev/null
+++ b/modules/helpchan.cpp
@@ -0,0 +1,45 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class HelpChannel : public Module
+ , public EventHook<Event::ChannelModeSet>
+{
+ public:
+ HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChannelModeSet>(this)
+ {
+ }
+
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &, ChannelMode *mode, const Anope::string &param) override
+ {
+ if (mode->name == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<Anope::string>("helpchannel")))
+ {
+ User *u = User::Find(param);
+
+ if (u && c->ci->AccessFor(u).HasPriv("OPME"))
+ u->SetMode(Config->GetClient("OperServ"), "HELPOP");
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(HelpChannel)
diff --git a/modules/hostserv/CMakeLists.txt b/modules/hostserv/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/hostserv/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/hostserv/del.cpp b/modules/hostserv/del.cpp
new file mode 100644
index 000000000..bc9b08533
--- /dev/null
+++ b/modules/hostserv/del.cpp
@@ -0,0 +1,111 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/hostserv/del.h"
+
+class CommandHSDel : public Command
+{
+ public:
+ CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 1)
+ {
+ this->SetDesc(_("Delete the vhost of another user"));
+ this->SetSyntax(_("\037user\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ const Anope::string &nick = params[0];
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "for user " << na->GetNick();
+ EventManager::Get()->Dispatch(&Event::DeleteVhost::OnDeleteVhost, na);
+ na->RemoveVhost();
+ source.Reply(_("Vhost for \002{0}\002 has been removed."), na->GetNick());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Removes the vhost of \037user\037."));
+ return true;
+ }
+};
+
+class CommandHSDelAll : public Command
+{
+ public:
+ CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1)
+ {
+ this->SetDesc(_("Delete the vhost for all nicks in a group"));
+ this->SetSyntax(_("\037group\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ const Anope::string &nick = params[0];
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ EventManager::Get()->Dispatch(&Event::DeleteVhost::OnDeleteVhost, na);
+
+ NickServ::Account *nc = na->GetAccount();
+ for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>())
+ na2->RemoveVhost();
+ Log(LOG_ADMIN, source, this) << "for all nicks in group " << nc->GetDisplay();
+ source.Reply(_("Vhosts for group \002{0}\002 have been removed."), nc->GetDisplay());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Removes the vhost of all nicks in the group \037group\037."));
+ return true;
+ }
+};
+
+class HSDel : public Module
+{
+ CommandHSDel commandhsdel;
+ CommandHSDelAll commandhsdelall;
+
+ public:
+ HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhsdel(this)
+ , commandhsdelall(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSDel)
diff --git a/modules/hostserv/group.cpp b/modules/hostserv/group.cpp
new file mode 100644
index 000000000..8113435fa
--- /dev/null
+++ b/modules/hostserv/group.cpp
@@ -0,0 +1,127 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/group.h"
+
+class CommandHSGroup : public Command
+{
+ bool setting;
+
+ public:
+ void Sync(NickServ::Nick *na)
+ {
+ if (setting)
+ return;
+
+ if (!na || !na->HasVhost())
+ return;
+
+ setting = true;
+ for (NickServ::Nick *nick : na->GetAccount()->GetRefs<NickServ::Nick *>())
+ {
+ nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
+ EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, nick);
+ }
+ setting = false;
+ }
+
+ CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0), setting(false)
+ {
+ this->SetDesc(_("Syncs the vhost for all nicks in a group"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(source.GetNick());
+ if (!na || na->GetAccount() != source.GetAccount())
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ if (!na->HasVhost())
+ {
+ source.Reply(_("There is no vhost assigned to this nickname."));
+ return;
+ }
+
+ this->Sync(na);
+ if (!na->GetVhostIdent().empty())
+ source.Reply(_("All vhosts in the group \002{0}\002 have been set to \002{1}\002@\002{2}\002."), source.nc->GetDisplay(), na->GetVhostIdent(), na->GetVhostHost());
+ else
+ source.Reply(_("All vhosts in the group \002{0}\002 have been set to \002{1}\002."), source.nc->GetDisplay(), na->GetVhostHost());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the vhost of all nicks in your group to the vhost of your current nick."));
+ return true;
+ }
+};
+
+class HSGroup : public Module
+ , public EventHook<Event::SetVhost>
+ , public EventHook<Event::NickGroup>
+{
+ CommandHSGroup commandhsgroup;
+ bool syncongroup;
+ bool synconset;
+
+ public:
+ HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::SetVhost>(this)
+ , EventHook<Event::NickGroup>(this)
+ , commandhsgroup(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+
+ void OnSetVhost(NickServ::Nick *na) override
+ {
+ if (!synconset)
+ return;
+
+ commandhsgroup.Sync(na);
+ }
+
+ void OnNickGroup(User *u, NickServ::Nick *na) override
+ {
+ if (!syncongroup)
+ return;
+
+ commandhsgroup.Sync(na);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ syncongroup = block->Get<bool>("syncongroup");
+ synconset = block->Get<bool>("synconset");
+ }
+};
+
+MODULE_INIT(HSGroup)
diff --git a/modules/commands/hs_list.cpp b/modules/hostserv/list.cpp
index a5258b04c..cdaf72a37 100644
--- a/modules/commands/hs_list.cpp
+++ b/modules/hostserv/list.cpp
@@ -1,12 +1,20 @@
-/* HostServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandHSList : public Command
this->SetSyntax(_("[\037key\037|\037#X-Y\037]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &key = !params.empty() ? params[0] : "";
int from = 0, to = 0, counter = 1;
@@ -34,14 +42,14 @@ class CommandHSList : public Command
size_t tmp = key.find('-');
if (tmp == Anope::string::npos || tmp == key.length() || tmp == 1)
{
- source.Reply(LIST_INCORRECT_RANGE);
+ source.Reply(_("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002."));
return;
}
for (unsigned i = 1, end = key.length(); i < end; ++i)
{
if (!isdigit(key[i]) && i != tmp)
{
- source.Reply(LIST_INCORRECT_RANGE);
+ source.Reply(_("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002."));
return;
}
try
@@ -53,26 +61,24 @@ class CommandHSList : public Command
}
}
- unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
+ unsigned display_counter = 0, listmax = Config->GetModule(this->GetOwner())->Get<unsigned>("listmax", "50");
ListFormatter list(source.GetAccount());
list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Creator")).AddColumn(_("Created"));
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
+ for (NickServ::Nick *na : NickServ::service->GetNickList())
{
- const NickAlias *na = it->second;
-
if (!na->HasVhost())
continue;
if (!key.empty() && key[0] != '#')
{
- if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax)
+ if ((Anope::Match(na->GetNick(), key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax)
{
++display_counter;
ListFormatter::ListEntry entry;
entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->nick;
+ entry["Nick"] = na->GetNick();
if (!na->GetVhostIdent().empty())
entry["Vhost"] = na->GetVhostIdent() + "@" + na->GetVhostHost();
else
@@ -93,7 +99,7 @@ class CommandHSList : public Command
++display_counter;
ListFormatter::ListEntry entry;
entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->nick;
+ entry["Nick"] = na->GetNick();
if (!na->GetVhostIdent().empty())
entry["Vhost"] = na->GetVhostIdent() + "@" + na->GetVhostHost();
else
@@ -113,13 +119,13 @@ class CommandHSList : public Command
}
if (!key.empty())
- source.Reply(_("Displayed records matching key \002%s\002 (count: \002%d\002)."), key.c_str(), display_counter);
+ source.Reply(_("Displayed records matching key \002{0}\002 (count: \002{1}\002)."), key, display_counter);
else
{
if (from)
- source.Reply(_("Displayed records from \002%d\002 to \002%d\002."), from, to);
+ source.Reply(_("Displayed records from \002{0}\002 to \002{1}\002."), from, to);
else
- source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter);
+ source.Reply(_("Displayed all records (count: \002{0}\002)."), display_counter);
}
std::vector<Anope::string> replies;
@@ -129,17 +135,18 @@ class CommandHSList : public Command
source.Reply(replies[i]);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command lists registered vhosts to the operator.\n"
- "If a \037key\037 is specified, only entries whose nick or vhost match\n"
- "the pattern given in \037key\037 are displayed e.g. Rob* for all\n"
- "entries beginning with \"Rob\"\n"
- "If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n"
- "and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n"
- "nick/vhost entries."));
+ source.Reply(_("Lists all vhosts. If \037key\037 is specified, only entries whose nick or vhost match the pattern given in \037key\037 are displayed."
+ "If a \037#X-Y\037 style is used, only entries between the range of \002X\002 and \002Y\002 will be displayed.\n"
+ "\n"
+ "Examples:\n"
+ " {0} Rob*\n"
+ " Lists all entries with the nick or vhost beginning with \"Rob\"\n"
+ "\n"
+ " {0} #1-3\n"
+ " Lists the first three entries."),
+ source.command);
return true;
}
};
@@ -149,8 +156,8 @@ class HSList : public Module
CommandHSList commandhslist;
public:
- HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhslist(this)
+ HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhslist(this)
{
if (!IRCD || !IRCD->CanSetVHost)
throw ModuleException("Your IRCd does not support vhosts");
diff --git a/modules/hostserv/main/CMakeLists.txt b/modules/hostserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/hostserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/hostserv/main/hostserv.cpp b/modules/hostserv/main/hostserv.cpp
new file mode 100644
index 000000000..c1c9408e4
--- /dev/null
+++ b/modules/hostserv/main/hostserv.cpp
@@ -0,0 +1,148 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/update.h"
+#include "modules/hostserv/del.h"
+#include "modules/help.h"
+
+class HostServCore : public Module
+ , public EventHook<Event::UserLogin>
+ , public EventHook<Event::NickUpdate>
+ , public EventHook<Event::Help>
+ , public EventHook<Event::SetVhost>
+ , public EventHook<Event::DeleteVhost>
+{
+ Reference<ServiceBot> HostServ;
+
+ public:
+ HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , EventHook<Event::UserLogin>(this)
+ , EventHook<Event::NickUpdate>(this)
+ , EventHook<Event::Help>(this)
+ , EventHook<Event::SetVhost>(this)
+ , EventHook<Event::DeleteVhost>(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &hsnick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (hsnick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(hsnick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + hsnick);
+
+ HostServ = bi;
+ }
+
+ void OnUserLogin(User *u) override
+ {
+ if (!IRCD->CanSetVHost)
+ return;
+
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (!na || na->GetAccount() != u->Account() || !na->HasVhost())
+ na = NickServ::FindNick(u->Account()->GetDisplay());
+ if (!na || !na->HasVhost())
+ return;
+
+ if (u->vhost.empty() || !u->vhost.equals_cs(na->GetVhostHost()) || (!na->GetVhostIdent().empty() && !u->GetVIdent().equals_cs(na->GetVhostIdent())))
+ {
+ IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
+
+ u->vhost = na->GetVhostHost();
+ u->UpdateHost();
+
+ if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
+ u->SetVIdent(na->GetVhostIdent());
+
+ if (HostServ)
+ {
+ if (!na->GetVhostIdent().empty())
+ u->SendMessage(*HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
+ else
+ u->SendMessage(*HostServ, _("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
+ }
+ }
+ }
+
+ void OnNickUpdate(User *u) override
+ {
+ this->OnUserLogin(u);
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *HostServ)
+ return EVENT_CONTINUE;
+ source.Reply(_("%s commands:"), HostServ->nick.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ }
+
+ void OnSetVhost(NickServ::Nick *na) override
+ {
+ if (Config->GetModule(this)->Get<bool>("activate_on_set"))
+ {
+ User *u = User::Find(na->GetNick());
+
+ if (u && u->Account() == na->GetAccount())
+ {
+ IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
+
+ u->vhost = na->GetVhostHost();
+ u->UpdateHost();
+
+ if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
+ u->SetVIdent(na->GetVhostIdent());
+
+ if (HostServ)
+ {
+ if (!na->GetVhostIdent().empty())
+ u->SendMessage(*HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
+ else
+ u->SendMessage(*HostServ, _("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
+ }
+ }
+ }
+ }
+
+ void OnDeleteVhost(NickServ::Nick *na) override
+ {
+ if (Config->GetModule(this)->Get<bool>("activate_on_set"))
+ {
+ User *u = User::Find(na->GetNick());
+
+ if (u && u->Account() == na->GetAccount())
+ IRCD->SendVhostDel(u);
+ }
+ }
+};
+
+MODULE_INIT(HostServCore)
+
diff --git a/modules/hostserv/off.cpp b/modules/hostserv/off.cpp
new file mode 100644
index 000000000..e8c191164
--- /dev/null
+++ b/modules/hostserv/off.cpp
@@ -0,0 +1,71 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandHSOff : public Command
+{
+ public:
+ CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0)
+ {
+ this->SetDesc(_("Deactivates your assigned vhost"));
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+
+ if (!na || na->GetAccount() != u->Account() || !na->HasVhost())
+ na = NickServ::FindNick(u->Account()->GetDisplay());
+
+ if (!na || !na->HasVhost() || na->GetAccount() != source.GetAccount())
+ {
+ source.Reply(_("There is no vhost assigned to this nickname."));
+ return;
+ }
+
+ u->vhost.clear();
+ IRCD->SendVhostDel(u);
+ Log(LOG_COMMAND, source, this) << "to disable their vhost";
+ source.Reply(_("Your vhost was removed and the normal cloaking restored."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Deactivates your vhost."));
+ return true;
+ }
+};
+
+class HSOff : public Module
+{
+ CommandHSOff commandhsoff;
+
+ public:
+ HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhsoff(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSOff)
diff --git a/modules/hostserv/on.cpp b/modules/hostserv/on.cpp
new file mode 100644
index 000000000..1332c7e7a
--- /dev/null
+++ b/modules/hostserv/on.cpp
@@ -0,0 +1,81 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandHSOn : public Command
+{
+ public:
+ CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0)
+ {
+ this->SetDesc(_("Activates your assigned vhost"));
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!IRCD->CanSetVHost)
+ return; // HostServ wouldn't even be loaded at this point
+
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+
+ if (!na || na->GetAccount() != u->Account() || !na->HasVhost())
+ na = NickServ::FindNick(u->Account()->GetDisplay());
+
+ if (!na || !na->HasVhost() || na->GetAccount() != u->Account())
+ {
+ source.Reply(_("There is no vhost assigned to this nickname."));
+ return;
+ }
+
+ if (!na->GetVhostIdent().empty())
+ source.Reply(_("Your vhost of \002{0}\002@\002{1}\002 is now activated."), na->GetVhostIdent(), na->GetVhostHost());
+ else
+ source.Reply(_("Your vhost of \002{0}\002 is now activated."), na->GetVhostHost());
+
+ Log(LOG_COMMAND, source, this) << "to enable their vhost of " << (!na->GetVhostIdent().empty() ? na->GetVhostIdent() + "@" : "") << na->GetVhostHost();
+ IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
+ u->vhost = na->GetVhostHost();
+ if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
+ u->SetVIdent(na->GetVhostIdent());
+ u->UpdateHost();
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Activates your vhost."));
+ return true;
+ }
+};
+
+class HSOn : public Module
+{
+ CommandHSOn commandhson;
+
+ public:
+ HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhson(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSOn)
diff --git a/modules/hostserv/request.cpp b/modules/hostserv/request.cpp
new file mode 100644
index 000000000..2024ef3b3
--- /dev/null
+++ b/modules/hostserv/request.cpp
@@ -0,0 +1,432 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class HostRequest : public Serialize::Object
+{
+ friend class HostRequestType;
+
+ NickServ::Nick *na = nullptr;
+ Anope::string ident, host;
+ time_t time = 0;
+
+ public:
+ static constexpr const char *const NAME = "hostrequest";
+
+ HostRequest(Serialize::TypeBase *type) : Serialize::Object(type) { }
+ HostRequest(Serialize::TypeBase *type, Serialize::ID id) : Serialize::Object(type, id) { }
+
+ NickServ::Nick *GetNick();
+ void SetNick(NickServ::Nick *na);
+
+ Anope::string GetIdent();
+ void SetIdent(const Anope::string &i);
+
+ Anope::string GetHost();
+ void SetHost(const Anope::string &h);
+
+ time_t GetTime();
+ void SetTime(const time_t &t);
+};
+
+class HostRequestType : public Serialize::Type<HostRequest>
+{
+ public:
+ Serialize::ObjectField<HostRequest, NickServ::Nick *> na;
+ Serialize::Field<HostRequest, Anope::string> ident, host;
+ Serialize::Field<HostRequest, time_t> time;
+
+ HostRequestType(Module *me) : Serialize::Type<HostRequest>(me)
+ , na(this, "na", &HostRequest::na, true)
+ , ident(this, "ident", &HostRequest::ident)
+ , host(this, "host", &HostRequest::host)
+ , time(this, "time", &HostRequest::time)
+ {
+ }
+};
+
+NickServ::Nick *HostRequest::GetNick()
+{
+ return Get(&HostRequestType::na);
+}
+
+void HostRequest::SetNick(NickServ::Nick *na)
+{
+ Set(&HostRequestType::na, na);
+}
+
+Anope::string HostRequest::GetIdent()
+{
+ return Get(&HostRequestType::ident);
+}
+
+void HostRequest::SetIdent(const Anope::string &i)
+{
+ Set(&HostRequestType::ident, i);
+}
+
+Anope::string HostRequest::GetHost()
+{
+ return Get(&HostRequestType::host);
+}
+
+void HostRequest::SetHost(const Anope::string &h)
+{
+ Set(&HostRequestType::host, h);
+}
+
+time_t HostRequest::GetTime()
+{
+ return Get(&HostRequestType::time);
+}
+
+void HostRequest::SetTime(const time_t &t)
+{
+ Set(&HostRequestType::time, t);
+}
+
+class CommandHSRequest : public Command
+{
+ ServiceReference<MemoServ::MemoServService> memoserv;
+
+ void SendMemos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
+ {
+ Anope::string host;
+
+ if (!vIdent.empty())
+ host = vIdent + "@" + vHost;
+ else
+ host = vHost;
+
+ if (Config->GetModule(GetOwner())->Get<bool>("memooper") && memoserv)
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ {
+ NickServ::Nick *na = NickServ::FindNick(o->GetName());
+ if (!na)
+ continue;
+
+ Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str());
+
+ memoserv->Send(source.service->nick, na->GetNick(), message, true);
+ }
+ }
+
+ public:
+ CommandHSRequest(Module *creator) : Command(creator, "hostserv/request", 1, 1)
+ {
+ this->SetDesc(_("Request a vHost for your nick"));
+ this->SetSyntax(_("vhost"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(source.GetNick());
+ if (!na || na->GetAccount() != source.GetAccount())
+ {
+ source.Reply(_("Access denied.")); //XXX with nonickownership this should be allowed.
+ return;
+ }
+
+ if (source.GetAccount()->HasFieldS("UNCONFIRMED"))
+ {
+ source.Reply(_("You must confirm your account before you may request a vhost."));
+ return;
+ }
+
+ Anope::string rawhostmask = params[0];
+
+ 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->GetBlock("networkinfo")->Get<unsigned>("userlen"))
+ {
+ source.Reply(_("The username \002{0}\002 is too long, please use a username shorter than %d characters."), Config->GetBlock("networkinfo")->Get<unsigned>("userlen"));
+ return;
+ }
+
+ if (!IRCD->CanSetVIdent)
+ {
+ source.Reply(_("Vhosts may not contain a username."));
+ return;
+ }
+
+ if (!IRCD->IsIdentValid(user))
+ {
+ source.Reply(_("The requested username is not valid."));
+ return;
+ }
+ }
+
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
+ {
+ source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
+ return;
+ }
+
+ if (!IRCD->IsHostValid(host))
+ {
+ source.Reply(_("The requested hostname is not valid."));
+ return;
+ }
+
+ time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
+ if (Config->GetModule(this->GetOwner())->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
+ {
+ source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay);
+ u->lastmemosend = Anope::CurTime;
+ return;
+ }
+
+ HostRequest *req = Serialize::New<HostRequest *>();
+ req->SetNick(na);
+ req->SetIdent(user);
+ req->SetHost(host);
+ req->SetTime(Anope::CurTime);
+
+ source.Reply(_("Your vhost has been requested."));
+ this->SendMemos(source, user, host);
+ Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Request the given \036vhost\037 to be actived for your nick by the network administrators. Please be patient while your request is being considered."));
+ return true;
+ }
+};
+
+class CommandHSActivate : public Command
+{
+ ServiceReference<MemoServ::MemoServService> memoserv;
+
+ public:
+ CommandHSActivate(Module *creator) : Command(creator, "hostserv/activate", 1, 1)
+ {
+ this->SetDesc(_("Approve the requested vHost of a user"));
+ this->SetSyntax(_("\037user\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+ NickServ::Nick *na = NickServ::FindNick(nick);
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ HostRequest *req = na->GetExt<HostRequest>("hostrequest");
+ if (!req)
+ {
+ source.Reply(_("\002{0}\002 does not have a pending vhost request."), na->GetNick());
+ return;
+ }
+
+ na->SetVhost(req->GetIdent(), req->GetHost(), source.GetNick(), req->GetTime());
+ EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, na);
+
+ if (Config->GetModule(this->GetOwner())->Get<bool>("memouser") && memoserv)
+ memoserv->Send(source.service->nick, na->GetNick(), _("[auto memo] Your requested vHost has been approved."), true);
+
+ source.Reply(_("Vhost for \002{0}\002 has been activated."), na->GetNick());
+ Log(LOG_COMMAND, source, this) << "for " << na->GetNick() << " for vhost " << (!req->GetIdent().empty() ? req->GetIdent() + "@" : "") << req->GetHost();
+ req->Delete();
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Activate the requested vhost for the given user."));
+ if (Config->GetModule(this->GetOwner())->Get<bool>("memouser"))
+ source.Reply(_("A memo informing the user will also be sent."));
+
+ return true;
+ }
+};
+
+class CommandHSReject : public Command
+{
+ ServiceReference<MemoServ::MemoServService> memoserv;
+
+ public:
+ CommandHSReject(Module *creator) : Command(creator, "hostserv/reject", 1, 2)
+ {
+ this->SetDesc(_("Reject the requested vHost of a user"));
+ this->SetSyntax(_("\037user\037 [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+ const Anope::string &reason = params.size() > 1 ? params[1] : "";
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ HostRequest *req = na->GetExt<HostRequest>("hostrequest");
+ if (!req)
+ {
+ source.Reply(_("\002{0}\002 does not have a pending vhost request."), na->GetNick());
+ return;
+ }
+
+ req->Delete();
+
+ if (Config->GetModule(this->GetOwner())->Get<bool>("memouser") && memoserv)
+ {
+ Anope::string message;
+ if (!reason.empty())
+ message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
+ else
+ message = _("[auto memo] Your requested vHost has been rejected.");
+
+ memoserv->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true);
+ }
+
+ source.Reply(_("Vhost for \002{0}\002 has been rejected."), na->GetNick());
+ Log(LOG_COMMAND, source, this) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "no reason") << ")";
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Reject the requested vhost for the given user."));
+ if (Config->GetModule(this->GetOwner())->Get<bool>("memouser"))
+ source.Reply(_("A memo informing the user will also be sent, which includes the reason for the rejection if supplied."));
+
+ return true;
+ }
+};
+
+class CommandHSWaiting : public Command
+{
+ public:
+ CommandHSWaiting(Module *creator) : Command(creator, "hostserv/waiting", 0, 0)
+ {
+ this->SetDesc(_("Retrieves the vhost requests"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ unsigned counter = 0;
+ unsigned display_counter = 0, listmax = Config->GetModule(this->GetOwner())->Get<unsigned>("listmax");
+ ListFormatter list(source.GetAccount());
+
+ list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Created"));
+
+ for (HostRequest *hr : Serialize::GetObjects<HostRequest *>())
+ {
+ if (!listmax || display_counter < listmax)
+ {
+ ++display_counter;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(display_counter);
+ entry["Nick"] = hr->GetNick()->GetNick();
+ if (!hr->GetIdent().empty())
+ entry["Vhost"] = hr->GetIdent() + "@" + hr->GetHost();
+ else
+ entry["Vhost"] = hr->GetHost();
+ entry["Created"] = Anope::strftime(hr->GetTime(), NULL, true);
+ list.AddEntry(entry);
+ }
+ ++counter;
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("Displayed \002{0}\002 records (\002{1}\002 total)."), display_counter, counter);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Lists the vhost requests."));
+
+ return true;
+ }
+};
+
+class HSRequest : public Module
+{
+ CommandHSRequest commandhsrequest;
+ CommandHSActivate commandhsactive;
+ CommandHSReject commandhsreject;
+ CommandHSWaiting commandhswaiting;
+
+ HostRequestType hrtype;
+
+ public:
+ HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhsrequest(this)
+ , commandhsactive(this)
+ , commandhsreject(this)
+ , commandhswaiting(this)
+ , hrtype(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSRequest)
diff --git a/modules/hostserv/set.cpp b/modules/hostserv/set.cpp
new file mode 100644
index 000000000..357c0466a
--- /dev/null
+++ b/modules/hostserv/set.cpp
@@ -0,0 +1,224 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandHSSet : public Command
+{
+ public:
+ CommandHSSet(Module *creator) : Command(creator, "hostserv/set", 2, 2)
+ {
+ this->SetDesc(_("Set the vhost of another user"));
+ this->SetSyntax(_("\037user\037 \037hostmask\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ 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 (!IRCD->CanSetVIdent)
+ {
+ source.Reply(_("Vhosts may not contain a username."));
+ return;
+ }
+
+ if (!IRCD->IsIdentValid(user))
+ {
+ source.Reply(_("The requested username is not valid."));
+ return;
+ }
+ }
+
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
+ {
+ source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
+ return;
+ }
+
+ if (!IRCD->IsHostValid(host))
+ {
+ source.Reply(_("The requested hostname is not valid."));
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->GetNick() << " to " << (!user.empty() ? user + "@" : "") << host;
+
+ na->SetVhost(user, host, source.GetNick());
+ EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, na);
+ if (!user.empty())
+ source.Reply(_("Vhost for \002{0}\002 set to \002{0}\002@\002{1}\002."), nick, user, host);
+ else
+ source.Reply(_("Vhost for \002{0}\002 set to \002{0}\002."), nick, host);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the vhost of the given \037user\037 to the given \037hostmask\037."));
+ return true;
+ }
+};
+
+class CommandHSSetAll : public Command
+{
+ void Sync(NickServ::Nick *na)
+ {
+ if (!na || !na->HasVhost())
+ return;
+
+ for (NickServ::Nick *nick : na->GetAccount()->GetRefs<NickServ::Nick *>())
+ nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
+ }
+
+ public:
+ CommandHSSetAll(Module *creator) : Command(creator, "hostserv/setall", 2, 2)
+ {
+ this->SetDesc(_("Set the vhost for all nicks in a group"));
+ this->SetSyntax(_("\037user\037 \037hostmask\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ 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 (!IRCD->CanSetVIdent)
+ {
+ source.Reply(_("Vhosts may not contain a username."));
+ return;
+ }
+
+ if (!IRCD->IsIdentValid(user))
+ {
+ source.Reply(_("The requested username is not valid."));
+ return;
+ }
+ }
+
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
+ {
+ source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
+ return;
+ }
+
+ if (!IRCD->IsHostValid(host))
+ {
+ source.Reply(_("The requested hostname is not valid."));
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->GetNick() << " to " << (!user.empty() ? user + "@" : "") << host;
+
+ na->SetVhost(user, host, source.GetNick());
+ this->Sync(na);
+ EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, na);
+ if (!user.empty())
+ source.Reply(_("Vhost for group \002{0}\002 set to \002{1}\002@\002{2}\002."), nick.c_str(), user.c_str(), host.c_str());
+ else
+ source.Reply(_("host for group \002{0}\002 set to \002{1}\002."), nick.c_str(), host.c_str());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets the vhost for all nicknames in the group of \037user\037."));
+ return true;
+ }
+};
+
+class HSSet : public Module
+{
+ CommandHSSet commandhsset;
+ CommandHSSetAll commandhssetall;
+
+ public:
+ HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhsset(this)
+ , commandhssetall(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSSet)
diff --git a/modules/m_httpd.cpp b/modules/httpd.cpp
index 20c98dd56..11f8318e7 100644
--- a/modules/m_httpd.cpp
+++ b/modules/httpd.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -105,17 +116,17 @@ class MyHTTPClient : public HTTPClient
}
/* Close connection once all data is written */
- bool ProcessWrite() anope_override
+ bool ProcessWrite() override
{
return !BinarySocket::ProcessWrite() || this->write_buffer.empty() ? false : true;
}
- const Anope::string GetIP() anope_override
+ const Anope::string GetIP() override
{
return this->ip;
}
- bool Read(const char *buffer, size_t l) anope_override
+ bool Read(const char *buffer, size_t l) override
{
message.content.append(buffer, l);
@@ -149,7 +160,7 @@ class MyHTTPClient : public HTTPClient
this->Serve();
}
-
+
return true;
}
@@ -233,7 +244,7 @@ class MyHTTPClient : public HTTPClient
return true;
}
- void SendError(HTTPError err, const Anope::string &msg) anope_override
+ void SendError(HTTPError err, const Anope::string &msg) override
{
HTTPReply h;
@@ -244,7 +255,7 @@ class MyHTTPClient : public HTTPClient
this->SendReply(&h);
}
- void SendReply(HTTPReply *msg) anope_override
+ void SendReply(HTTPReply *msg) override
{
this->WriteClient("HTTP/1.1 " + GetStatusFromCode(msg->error));
this->WriteClient("Date: " + BuildDate());
@@ -296,7 +307,7 @@ class MyHTTPProvider : public HTTPProvider, public Timer
public:
MyHTTPProvider(Module *c, const Anope::string &n, const Anope::string &i, const unsigned short p, const int t, bool s) : Socket(-1, i.find(':') != Anope::string::npos), HTTPProvider(c, n, i, p, s), Timer(c, 10, Anope::CurTime, true), timeout(t) { }
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
while (!this->clients.empty())
{
@@ -309,24 +320,24 @@ class MyHTTPProvider : public HTTPProvider, public Timer
}
}
- ClientSocket* OnAccept(int fd, const sockaddrs &addr) anope_override
+ ClientSocket* OnAccept(int fd, const sockaddrs &addr) override
{
MyHTTPClient *c = new MyHTTPClient(this, fd, addr);
this->clients.push_back(c);
return c;
}
- bool RegisterPage(HTTPPage *page) anope_override
+ bool RegisterPage(HTTPPage *page) override
{
return this->pages.insert(std::make_pair(page->GetURL(), page)).second;
}
- void UnregisterPage(HTTPPage *page) anope_override
+ void UnregisterPage(HTTPPage *page) override
{
this->pages.erase(page->GetURL());
}
- HTTPPage* FindPage(const Anope::string &pname)
+ HTTPPage* FindPage(const Anope::string &pname) override
{
if (this->pages.count(pname) == 0)
return NULL;
@@ -335,11 +346,13 @@ class MyHTTPProvider : public HTTPProvider, public Timer
};
class HTTPD : public Module
+ , public EventHook<Event::ModuleLoad>
{
ServiceReference<SSLService> sslref;
std::map<Anope::string, MyHTTPProvider *> providers;
public:
- HTTPD(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), sslref("SSLService", "ssl")
+ HTTPD(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::ModuleLoad>(this)
{
}
@@ -358,7 +371,7 @@ class HTTPD : public Module
this->providers.clear();
}
- void OnReload(Configuration::Conf *config) anope_override
+ void OnReload(Configuration::Conf *config) override
{
Configuration::Block *conf = config->GetModule(this);
std::set<Anope::string> existing;
@@ -368,15 +381,15 @@ class HTTPD : public Module
Configuration::Block *block = conf->GetBlock("httpd", i);
- const Anope::string &hname = block->Get<const Anope::string>("name", "httpd/main");
+ const Anope::string &hname = block->Get<Anope::string>("name", "httpd/main");
existing.insert(hname);
- Anope::string ip = block->Get<const Anope::string>("ip");
+ Anope::string ip = block->Get<Anope::string>("ip");
int port = block->Get<int>("port", "8080");
int timeout = block->Get<int>("timeout", "30");
bool ssl = block->Get<bool>("ssl", "no");
- Anope::string ext_ip = block->Get<const Anope::string>("extforward_ip");
- Anope::string ext_header = block->Get<const Anope::string>("extforward_header");
+ Anope::string ext_ip = block->Get<Anope::string>("extforward_ip");
+ Anope::string ext_header = block->Get<Anope::string>("extforward_header");
if (ip.empty())
{
@@ -444,16 +457,16 @@ class HTTPD : public Module
HTTPProvider *p = it->second;
++it;
- if (existing.count(p->name) == 0)
+ if (existing.count(p->GetName()) == 0)
{
- Log(this) << "Removing HTTP server " << p->name;
- this->providers.erase(p->name);
+ Log(this) << "Removing HTTP server " << p->GetName();
+ this->providers.erase(p->GetName());
delete p;
}
}
}
- void OnModuleLoad(User *u, Module *m) anope_override
+ void OnModuleLoad(User *u, Module *m) override
{
for (std::map<Anope::string, MyHTTPProvider *>::iterator it = this->providers.begin(), it_end = this->providers.end(); it != it_end; ++it)
{
diff --git a/modules/m_helpchan.cpp b/modules/m_helpchan.cpp
deleted file mode 100644
index f8cd2b231..000000000
--- a/modules/m_helpchan.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-
-class HelpChannel : public Module
-{
- public:
- HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
- {
- }
-
- EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (mode->name == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string>("helpchannel")))
- {
- User *u = User::Find(param);
-
- if (u && c->ci->AccessFor(u).HasPriv("OPME"))
- u->SetMode(Config->GetClient("OperServ"), "HELPOP");
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(HelpChannel)
diff --git a/modules/m_proxyscan.cpp b/modules/m_proxyscan.cpp
deleted file mode 100644
index ac38895e4..000000000
--- a/modules/m_proxyscan.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-
-struct ProxyCheck
-{
- std::set<Anope::string, ci::less> types;
- std::vector<unsigned short> ports;
- time_t duration;
- Anope::string reason;
-};
-
-static Anope::string ProxyCheckString;
-static Anope::string target_ip;
-static unsigned short target_port;
-static bool add_to_akill;
-
-class ProxyCallbackListener : public ListenSocket
-{
- class ProxyCallbackClient : public ClientSocket, public BufferedSocket
- {
- public:
- ProxyCallbackClient(ListenSocket *l, int f, const sockaddrs &a) : Socket(f, l->IsIPv6()), ClientSocket(l, a), BufferedSocket()
- {
- }
-
- void OnAccept() anope_override
- {
- this->Write(ProxyCheckString);
- }
-
- bool ProcessWrite() anope_override
- {
- return !BufferedSocket::ProcessWrite() || this->write_buffer.empty() ? false : true;
- }
- };
-
- public:
- ProxyCallbackListener(const Anope::string &b, int p) : Socket(-1, b.find(':') != Anope::string::npos), ListenSocket(b, p, false)
- {
- }
-
- ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_override
- {
- return new ProxyCallbackClient(this, fd, addr);
- }
-};
-
-class ProxyConnect : public ConnectionSocket
-{
- static ServiceReference<XLineManager> akills;
-
- public:
- static std::set<ProxyConnect *> proxies;
-
- ProxyCheck proxy;
- unsigned short port;
- time_t created;
-
- ProxyConnect(ProxyCheck &p, unsigned short po) : Socket(-1), ConnectionSocket(), proxy(p),
- port(po), created(Anope::CurTime)
- {
- proxies.insert(this);
- }
-
- ~ProxyConnect()
- {
- proxies.erase(this);
- }
-
- virtual void OnConnect() anope_override = 0;
- virtual const Anope::string GetType() const = 0;
-
- protected:
- void Ban()
- {
- Anope::string reason = this->proxy.reason;
-
- reason = reason.replace_all_cs("%t", this->GetType());
- reason = reason.replace_all_cs("%i", this->conaddr.addr());
- reason = reason.replace_all_cs("%p", stringify(this->conaddr.port()));
-
- BotInfo *OperServ = Config->GetClient("OperServ");
- Log(OperServ) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")";
- XLine *x = new XLine("*@" + this->conaddr.addr(), OperServ ? OperServ->nick : "", Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID());
- if (add_to_akill && akills)
- {
- akills->AddXLine(x);
- akills->Send(NULL, x);
- }
- else
- {
- if (IRCD->CanSZLine)
- IRCD->SendSZLine(NULL, x);
- else
- IRCD->SendAkill(NULL, x);
- delete x;
- }
- }
-};
-ServiceReference<XLineManager> ProxyConnect::akills("XLineManager", "xlinemanager/sgline");
-std::set<ProxyConnect *> ProxyConnect::proxies;
-
-class HTTPProxyConnect : public ProxyConnect, public BufferedSocket
-{
- public:
- HTTPProxyConnect(ProxyCheck &p, unsigned short po) : Socket(-1), ProxyConnect(p, po), BufferedSocket()
- {
- }
-
- void OnConnect() anope_override
- {
- this->Write("CONNECT %s:%d HTTP/1.0", target_ip.c_str(), target_port);
- this->Write("Content-length: 0");
- this->Write("Connection: close");
- this->Write("");
- }
-
- const Anope::string GetType() const anope_override
- {
- return "HTTP";
- }
-
- bool ProcessRead() anope_override
- {
- bool b = BufferedSocket::ProcessRead();
- if (this->GetLine() == ProxyCheckString)
- {
- this->Ban();
- return false;
- }
- return b;
- }
-};
-
-class SOCKS5ProxyConnect : public ProxyConnect, public BinarySocket
-{
- public:
- SOCKS5ProxyConnect(ProxyCheck &p, unsigned short po) : Socket(-1), ProxyConnect(p, po), BinarySocket()
- {
- }
-
- void OnConnect() anope_override
- {
- sockaddrs target_addr;
- char buf[4 + sizeof(target_addr.sa4.sin_addr.s_addr) + sizeof(target_addr.sa4.sin_port)];
- int ptr = 0;
- target_addr.pton(AF_INET, target_ip, target_port);
- if (!target_addr.valid())
- return;
-
- buf[ptr++] = 5; // Version
- buf[ptr++] = 1; // # of methods
- buf[ptr++] = 0; // No authentication
-
- this->Write(buf, ptr);
-
- ptr = 1;
- buf[ptr++] = 1; // Connect
- buf[ptr++] = 0; // Reserved
- buf[ptr++] = 1; // IPv4
- memcpy(buf + ptr, &target_addr.sa4.sin_addr.s_addr, sizeof(target_addr.sa4.sin_addr.s_addr));
- ptr += sizeof(target_addr.sa4.sin_addr.s_addr);
- memcpy(buf + ptr, &target_addr.sa4.sin_port, sizeof(target_addr.sa4.sin_port));
- ptr += sizeof(target_addr.sa4.sin_port);
-
- this->Write(buf, ptr);
- }
-
- const Anope::string GetType() const anope_override
- {
- return "SOCKS5";
- }
-
- bool Read(const char *buffer, size_t l) anope_override
- {
- if (l >= ProxyCheckString.length() && !strncmp(buffer, ProxyCheckString.c_str(), ProxyCheckString.length()))
- {
- this->Ban();
- return false;
- }
- return true;
- }
-};
-
-class ModuleProxyScan : public Module
-{
- Anope::string listen_ip;
- unsigned short listen_port;
- Anope::string con_notice, con_source;
- std::vector<ProxyCheck> proxyscans;
-
- ProxyCallbackListener *listener;
-
- class ConnectionTimeout : public Timer
- {
- public:
- ConnectionTimeout(Module *c, long timeout) : Timer(c, timeout, Anope::CurTime, true)
- {
- }
-
- void Tick(time_t) anope_override
- {
- for (std::set<ProxyConnect *>::iterator it = ProxyConnect::proxies.begin(), it_end = ProxyConnect::proxies.end(); it != it_end;)
- {
- ProxyConnect *p = *it;
- ++it;
-
- if (p->created + this->GetSecs() < Anope::CurTime)
- delete p;
- }
- }
- } connectionTimeout;
-
- public:
- ModuleProxyScan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- connectionTimeout(this, 5)
- {
-
-
- this->listener = NULL;
- }
-
- ~ModuleProxyScan()
- {
- for (std::set<ProxyConnect *>::iterator it = ProxyConnect::proxies.begin(), it_end = ProxyConnect::proxies.end(); it != it_end;)
- {
- ProxyConnect *p = *it;
- ++it;
- delete p;
- }
-
- for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
- {
- Socket *s = it->second;
- ++it;
-
- ClientSocket *cs = dynamic_cast<ClientSocket *>(s);
- if (cs != NULL && cs->ls == this->listener)
- delete s;
- }
-
- delete this->listener;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *config = Config->GetModule(this);
-
- Anope::string s_target_ip = config->Get<const Anope::string>("target_ip");
- if (s_target_ip.empty())
- throw ConfigException(this->name + " target_ip may not be empty");
-
- int s_target_port = config->Get<int>("target_port", "-1");
- if (s_target_port <= 0)
- throw ConfigException(this->name + " target_port may not be empty and must be a positive number");
-
- Anope::string s_listen_ip = config->Get<const Anope::string>("listen_ip");
- if (s_listen_ip.empty())
- throw ConfigException(this->name + " listen_ip may not be empty");
-
- int s_listen_port = config->Get<int>("listen_port", "-1");
- if (s_listen_port <= 0)
- throw ConfigException(this->name + " listen_port may not be empty and must be a positive number");
-
- target_ip = s_target_ip;
- target_port = s_target_port;
- this->listen_ip = s_listen_ip;
- this->listen_port = s_listen_port;
- this->con_notice = config->Get<const Anope::string>("connect_notice");
- this->con_source = config->Get<const Anope::string>("connect_source");
- add_to_akill = config->Get<bool>("add_to_akill", "true");
- this->connectionTimeout.SetSecs(config->Get<time_t>("timeout", "5s"));
-
- ProxyCheckString = Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname") + " proxy check";
- delete this->listener;
- this->listener = NULL;
- try
- {
- this->listener = new ProxyCallbackListener(this->listen_ip, this->listen_port);
- }
- catch (const SocketException &ex)
- {
- throw ConfigException("m_proxyscan: " + ex.GetReason());
- }
-
- this->proxyscans.clear();
- for (int i = 0; i < config->CountBlock("proxyscan"); ++i)
- {
- Configuration::Block *block = config->GetBlock("proxyscan", i);
- ProxyCheck p;
- Anope::string token;
-
- commasepstream sep(block->Get<const Anope::string>("type"));
- while (sep.GetToken(token))
- {
- if (!token.equals_ci("HTTP") && !token.equals_ci("SOCKS5"))
- continue;
- p.types.insert(token);
- }
- if (p.types.empty())
- continue;
-
- commasepstream sep2(block->Get<const Anope::string>("port"));
- while (sep2.GetToken(token))
- {
- try
- {
- unsigned short port = convertTo<unsigned short>(token);
- p.ports.push_back(port);
- }
- catch (const ConvertException &) { }
- }
- if (p.ports.empty())
- continue;
-
- p.duration = block->Get<time_t>("time", "4h");
- p.reason = block->Get<const Anope::string>("reason");
- if (p.reason.empty())
- continue;
-
- this->proxyscans.push_back(p);
- }
- }
-
- void OnUserConnect(User *user, bool &exempt) anope_override
- {
- if (exempt || user->Quitting() || !Me->IsSynced() || !user->server->IsSynced())
- return;
-
- /* At this time we only support IPv4 */
- if (!user->ip.valid() || user->ip.sa.sa_family != AF_INET)
- /* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */
- return;
-
- if (!this->con_notice.empty() && !this->con_source.empty())
- {
- BotInfo *bi = BotInfo::Find(this->con_source, true);
- if (bi)
- user->SendMessage(bi, this->con_notice);
- }
-
- for (unsigned i = this->proxyscans.size(); i > 0; --i)
- {
- ProxyCheck &p = this->proxyscans[i - 1];
-
- for (std::set<Anope::string, ci::less>::iterator it = p.types.begin(), it_end = p.types.end(); it != it_end; ++it)
- {
- for (unsigned k = 0; k < p.ports.size(); ++k)
- {
- try
- {
- ProxyConnect *con = NULL;
- if (it->equals_ci("HTTP"))
- con = new HTTPProxyConnect(p, p.ports[k]);
- else if (it->equals_ci("SOCKS5"))
- con = new SOCKS5ProxyConnect(p, p.ports[k]);
- else
- continue;
- con->Connect(user->ip.addr(), p.ports[k]);
- }
- catch (const SocketException &ex)
- {
- Log(LOG_DEBUG) << "m_proxyscan: " << ex.GetReason();
- }
- }
- }
- }
- }
-};
-
-MODULE_INIT(ModuleProxyScan)
-
diff --git a/modules/m_sasl.cpp b/modules/m_sasl.cpp
deleted file mode 100644
index e1f55bcc9..000000000
--- a/modules/m_sasl.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- *
- * (C) 2014-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/sasl.h"
-#include "modules/ns_cert.h"
-
-using namespace SASL;
-
-class Plain : public Mechanism
-{
- public:
- Plain(Module *o) : Mechanism(o, "PLAIN") { }
-
- void ProcessMessage(Session *sess, const SASL::Message &m) anope_override
- {
- if (m.type == "S")
- {
- sasl->SendMessage(sess, "C", "+");
- }
- else if (m.type == "C")
- {
- Anope::string decoded;
- Anope::B64Decode(m.data, decoded);
-
- size_t p = decoded.find('\0');
- if (p == Anope::string::npos)
- {
- sasl->Fail(sess);
- delete sess;
- return;
- }
- decoded = decoded.substr(p + 1);
-
- p = decoded.find('\0');
- if (p == Anope::string::npos)
- {
- sasl->Fail(sess);
- delete sess;
- return;
- }
-
- Anope::string acc = decoded.substr(0, p),
- pass = decoded.substr(p + 1);
-
- if (acc.empty() || pass.empty() || !IRCD->IsNickValid(acc) || pass.find_first_of("\r\n") != Anope::string::npos)
- {
- sasl->Fail(sess);
- delete sess;
- return;
- }
-
- SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, acc, pass);
- FOREACH_MOD(OnCheckAuthentication, (NULL, req));
- req->Dispatch();
- }
- }
-};
-
-class External : public Mechanism
-{
- ServiceReference<CertService> certs;
-
- struct Session : SASL::Session
- {
- Anope::string cert;
-
- Session(Mechanism *m, const Anope::string &u) : SASL::Session(m, u) { }
- };
-
- public:
- External(Module *o) : Mechanism(o, "EXTERNAL"), certs("CertService", "certs")
- {
- if (!IRCD || !IRCD->CanCertFP)
- throw ModuleException("No CertFP");
- }
-
- Session* CreateSession(const Anope::string &uid) anope_override
- {
- return new Session(this, uid);
- }
-
- void ProcessMessage(SASL::Session *sess, const SASL::Message &m) anope_override
- {
- Session *mysess = anope_dynamic_static_cast<Session *>(sess);
-
- if (m.type == "S")
- {
- mysess->cert = m.ext;
-
- sasl->SendMessage(sess, "C", "+");
- }
- else if (m.type == "C")
- {
- if (!certs || mysess->cert.empty())
- {
- sasl->Fail(sess);
- delete sess;
- return;
- }
-
- NickCore *nc = certs->FindAccountFromCert(mysess->cert);
- if (!nc || nc->HasExt("NS_SUSPENDED"))
- {
- Log(Config->GetClient("NickServ"), "sasl") << "A user failed to identify using certificate " << mysess->cert << " using SASL EXTERNAL";
- sasl->Fail(sess);
- delete sess;
- return;
- }
-
- Log(Config->GetClient("NickServ"), "sasl") << "A user identified to account " << nc->display << " using SASL EXTERNAL";
- sasl->Succeed(sess, nc);
- delete sess;
- }
- }
-};
-
-class SASLService : public SASL::Service, public Timer
-{
- std::map<Anope::string, SASL::Session *> sessions;
-
- public:
- SASLService(Module *o) : SASL::Service(o), Timer(o, 60, Anope::CurTime, true) { }
-
- ~SASLService()
- {
- for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end(); it++)
- delete it->second;
- }
-
- void ProcessMessage(const SASL::Message &m) anope_override
- {
- if (m.target != "*")
- {
- Server *s = Server::Find(m.target);
- if (s != Me)
- {
- User *u = User::Find(m.target);
- if (!u || u->server != Me)
- return;
- }
- }
-
- Session* &session = sessions[m.source];
-
- if (m.type == "S")
- {
- ServiceReference<Mechanism> mech("SASL::Mechanism", m.data);
- if (!mech)
- {
- Session tmp(NULL, m.source);
-
- sasl->SendMechs(&tmp);
- sasl->Fail(&tmp);
- return;
- }
-
- if (!session)
- session = mech->CreateSession(m.source);
- }
- else if (m.type == "D")
- {
- delete session;
- sessions.erase(m.source);
- return;
- }
-
- if (session && session->mech)
- session->mech->ProcessMessage(session, m);
- }
-
- Anope::string GetAgent() anope_override
- {
- Anope::string agent = Config->GetModule(Service::owner)->Get<Anope::string>("agent", "NickServ");
- BotInfo *bi = Config->GetClient(agent);
- if (bi)
- agent = bi->GetUID();
- return agent;
- }
-
- Session* GetSession(const Anope::string &uid) anope_override
- {
- std::map<Anope::string, Session *>::iterator it = sessions.find(uid);
- if (it != sessions.end())
- return it->second;
- return NULL;
- }
-
- void RemoveSession(Session *sess) anope_override
- {
- sessions.erase(sess->uid);
- }
-
- void DeleteSessions(Mechanism *mech, bool da) anope_override
- {
- for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
- {
- std::map<Anope::string, Session *>::iterator del = it++;
- if (*del->second->mech == mech)
- {
- if (da)
- this->SendMessage(del->second, "D", "A");
- delete del->second;
- }
- }
- }
-
- void SendMessage(Session *session, const Anope::string &mtype, const Anope::string &data) anope_override
- {
- SASL::Message msg;
- msg.source = this->GetAgent();
- msg.target = session->uid;
- msg.type = mtype;
- msg.data = data;
-
- IRCD->SendSASLMessage(msg);
- }
-
- void Succeed(Session *session, NickCore *nc) anope_override
- {
- // If the user is already introduced then we log them in now.
- // Otherwise, we send an SVSLOGIN to log them in later.
- User *user = User::Find(session->uid);
- NickAlias *na = NickAlias::Find(nc->display);
- if (user)
- {
- user->Identify(na);
- }
- else
- {
- IRCD->SendSVSLogin(session->uid, nc->display, na->GetVhostIdent(), na->GetVhostHost());
- }
- this->SendMessage(session, "D", "S");
- }
-
- void Fail(Session *session) anope_override
- {
- this->SendMessage(session, "D", "F");
- }
-
- void SendMechs(Session *session) anope_override
- {
- std::vector<Anope::string> mechs = Service::GetServiceKeys("SASL::Mechanism");
- Anope::string buf;
- for (unsigned j = 0; j < mechs.size(); ++j)
- buf += "," + mechs[j];
-
- this->SendMessage(session, "M", buf.empty() ? "" : buf.substr(1));
- }
-
- void Tick(time_t) anope_override
- {
- for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
- {
- Anope::string key = it->first;
- Session *s = it->second;
- ++it;
-
- if (!s || !s->mech || s->created + 60 < Anope::CurTime)
- {
- delete s;
- sessions.erase(key);
- }
- }
- }
-};
-
-class ModuleSASL : public Module
-{
- SASLService sasl;
-
- Plain plain;
- External *external;
-
- std::vector<Anope::string> mechs;
-
- void CheckMechs()
- {
- std::vector<Anope::string> newmechs = ::Service::GetServiceKeys("SASL::Mechanism");
- if (newmechs == mechs)
- return;
-
- mechs = newmechs;
-
- // If we are connected to the network then broadcast the mechlist.
- if (Me && Me->IsSynced())
- IRCD->SendSASLMechanisms(mechs);
- }
-
- public:
- ModuleSASL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- sasl(this), plain(this), external(NULL)
- {
- try
- {
- external = new External(this);
- CheckMechs();
- }
- catch (ModuleException &) { }
- }
-
- ~ModuleSASL()
- {
- delete external;
- }
-
- void OnModuleLoad(User *, Module *) anope_override
- {
- CheckMechs();
- }
-
- void OnModuleUnload(User *, Module *) anope_override
- {
- CheckMechs();
- }
-
- void OnPreUplinkSync(Server *) anope_override
- {
- // We have not yet sent a mechanism list so always do it here.
- IRCD->SendSASLMechanisms(mechs);
- }
-};
-
-MODULE_INIT(ModuleSASL)
diff --git a/modules/memoserv/CMakeLists.txt b/modules/memoserv/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/memoserv/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/memoserv/cancel.cpp b/modules/memoserv/cancel.cpp
new file mode 100644
index 000000000..3ba25ffaf
--- /dev/null
+++ b/modules/memoserv/cancel.cpp
@@ -0,0 +1,98 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSCancel : public Command
+{
+ public:
+ CommandMSCancel(Module *creator) : Command(creator, "memoserv/cancel", 1, 1)
+ {
+ this->SetDesc(_("Cancel the last memo you sent"));
+ this->SetSyntax(_("{\037user\037 | \037channel\037}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nname = params[0];
+
+ bool ischan, isregistered;
+ MemoServ::MemoInfo *mi = MemoServ::service->GetMemoInfo(nname, ischan, isregistered, false);
+
+ if (!isregistered)
+ {
+ if (ischan)
+ source.Reply(_("Channel \002{0}\002 isn't registered."), nname);
+ else
+ source.Reply(_("\002{0}\002 isn't registered."), nname);
+ }
+ else
+ {
+ ChanServ::Channel *ci = NULL;
+ NickServ::Nick *na = NULL;
+ if (ischan)
+ ci = ChanServ::Find(nname);
+ else
+ na = NickServ::FindNick(nname);
+ if (mi)
+ {
+ auto memos = mi->GetMemos();
+ for (int i = memos.size() - 1; i >= 0; --i)
+ {
+ MemoServ::Memo *m = memos[i];
+ if (m->GetUnread() && source.nc->GetDisplay().equals_ci(m->GetSender()))
+ {
+ EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ischan ? ci->GetName() : na->GetAccount()->GetDisplay(), mi, m);
+ mi->Del(i);
+ source.Reply(_("Your last memo to \002{0}\002 has been cancelled."), nname);
+ return;
+ }
+ }
+ }
+
+ source.Reply(_("No memo to \002{0}\002 was cancelable."), nname);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Cancels the last memo you sent to \037user\037, provided it has not yet been read."));
+ return true;
+ }
+};
+
+class MSCancel : public Module
+{
+ CommandMSCancel commandmscancel;
+
+ public:
+ MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmscancel(this)
+ {
+ }
+};
+
+MODULE_INIT(MSCancel)
diff --git a/modules/memoserv/check.cpp b/modules/memoserv/check.cpp
new file mode 100644
index 000000000..8174f3eb4
--- /dev/null
+++ b/modules/memoserv/check.cpp
@@ -0,0 +1,88 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandMSCheck : public Command
+{
+ public:
+ CommandMSCheck(Module *creator) : Command(creator, "memoserv/check", 1, 1)
+ {
+ this->SetDesc(_("Checks if last memo to a user was read"));
+ this->SetSyntax(_("\037user\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &recipient = params[0];
+
+ bool found = false;
+
+ NickServ::Nick *na = NickServ::FindNick(recipient);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), recipient);
+ return;
+ }
+
+ MemoServ::MemoInfo *mi = na->GetAccount()->GetMemos();
+
+ if (mi)
+ /* find the last memo */
+ for (unsigned i = mi->GetMemos().size(); i > 0; --i)
+ {
+ MemoServ::Memo *m = mi->GetMemo(i - 1);
+ NickServ::Nick *na2 = NickServ::FindNick(m->GetSender());
+
+ if (na2 != NULL && na2->GetAccount() == source.GetAccount())
+ {
+ found = true; /* Yes, we've found the memo */
+
+ if (m->GetUnread())
+ source.Reply(_("The last memo you sent to \002{0}\002 (sent on \002{1}\002) has not yet been read."), na->GetNick(), Anope::strftime(m->GetTime(), source.GetAccount()));
+ else
+ source.Reply(_("The last memo you sent to \002{0}\002 (sent on \002{1}\002) has been read."), na->GetNick(), Anope::strftime(m->GetTime(), source.GetAccount()));
+ break;
+ }
+ }
+
+ if (!found)
+ source.Reply(_("\002{0}\002 doesn't have a memo from you."), na->GetNick());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Checks whether the last memo you sent to \037user\037 has been read or not."));
+ return true;
+ }
+};
+
+class MSCheck : public Module
+{
+ CommandMSCheck commandmscheck;
+
+ public:
+ MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmscheck(this)
+ {
+
+ }
+};
+
+MODULE_INIT(MSCheck)
diff --git a/modules/memoserv/del.cpp b/modules/memoserv/del.cpp
new file mode 100644
index 000000000..17ef2a39f
--- /dev/null
+++ b/modules/memoserv/del.cpp
@@ -0,0 +1,153 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSDel : public Command
+{
+ public:
+ 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}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ MemoServ::MemoInfo *mi;
+ ChanServ::Channel *ci = NULL;
+ Anope::string numstr = !params.empty() ? params[0] : "", chan;
+
+ if (!numstr.empty() && numstr[0] == '#')
+ {
+ chan = numstr;
+ numstr = params.size() > 1 ? params[1] : "";
+
+ ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+
+ mi = ci->GetMemos();
+ }
+ else
+ mi = source.nc->GetMemos();
+
+ if (numstr.empty() || (!isdigit(numstr[0]) && !numstr.equals_ci("ALL") && !numstr.equals_ci("LAST")))
+ {
+ this->OnSyntaxError(source, numstr);
+ return;
+ }
+
+ if (!mi || mi->GetMemos().empty())
+ {
+ if (!chan.empty())
+ source.Reply(_("\002{0}\002 has no memos."), chan);
+ else
+ source.Reply(_("You have no memos."));
+ return;
+ }
+
+ auto memos = mi->GetMemos();
+
+ if (isdigit(numstr[0]))
+ {
+ NumberList(numstr, true,
+ [&](unsigned int number)
+ {
+ if (!number || number > memos.size())
+ return;
+
+ EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, mi->GetMemo(number - 1));
+
+ mi->Del(number - 1);
+ source.Reply(_("Memo \002{0}\002 has been deleted."), number);
+ },
+ [](){});
+ }
+ else if (numstr.equals_ci("LAST"))
+ {
+ /* Delete last memo. */
+ EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, mi->GetMemo(memos.size() - 1));
+ mi->Del(memos.size() - 1);
+ source.Reply(_("Memo \002{0}\002 has been deleted."), memos.size() + 1);
+ }
+ else
+ {
+ /* Delete all memos. */
+ std::for_each(memos.begin(), memos.end(),
+ [&](MemoServ::Memo *m)
+ {
+ EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, m);
+ delete m;
+ });
+ if (!chan.empty())
+ source.Reply(_("All memos for channel \002{0}\002 have been deleted."), chan);
+ else
+ source.Reply(_("All of your memos have been deleted."));
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Deletes the specified memo or memos."
+ " You can supply multiple memo numbers or ranges of numbers instead of a single number, as in the second example below."
+ " If \002LAST\002 is given, the last memo will be deleted."
+ " If \002ALL\002 is given, deletes all of your memos.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ " {0} 1\n"
+ " Deletes your first memo.\n"
+ "\n"
+ " {0} 2-5,7-9\n"
+ " Deletes memos numbered 2 through 5 and 7 through 9."),
+ source.command);
+ return true;
+ }
+};
+
+class MSDel : public Module
+{
+ CommandMSDel commandmsdel;
+
+ public:
+ MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsdel(this)
+ {
+
+ }
+};
+
+MODULE_INIT(MSDel)
diff --git a/modules/memoserv/ignore.cpp b/modules/memoserv/ignore.cpp
new file mode 100644
index 000000000..42e94a609
--- /dev/null
+++ b/modules/memoserv/ignore.cpp
@@ -0,0 +1,155 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandMSIgnore : public Command
+{
+ public:
+ CommandMSIgnore(Module *creator) : Command(creator, "memoserv/ignore", 1, 3)
+ {
+ this->SetDesc(_("Manage the memo ignore list"));
+ this->SetSyntax(_("[\037channel\037] ADD \037entry\037"));
+ this->SetSyntax(_("[\037channel\037] DEL \037entry\037"));
+ this->SetSyntax(_("[\037channel\037] LIST"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if (!MemoServ::service)
+ return;
+
+ Anope::string channel = params[0];
+ Anope::string command = (params.size() > 1 ? params[1] : "");
+ Anope::string param = (params.size() > 2 ? params[2] : "");
+
+ if (channel[0] != '#')
+ {
+ param = command;
+ command = channel;
+ channel = source.GetNick();
+ }
+
+ bool ischan, isregistered;
+ MemoServ::MemoInfo *mi = MemoServ::service->GetMemoInfo(channel, ischan, isregistered, true);
+ ChanServ::Channel *ci = ChanServ::Find(channel);
+ if (!isregistered)
+ {
+ if (ischan)
+ source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
+ else
+ source.Reply(_("\002{0}\002 isn't registered."), channel);
+ return;
+ }
+
+ if (ischan && !source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+
+ auto ignores = mi->GetIgnores();
+
+ if (command.equals_ci("ADD") && !param.empty())
+ {
+ if (ignores.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("max", "32"))
+ {
+ source.Reply(_("Sorry, the memo ignore list for \002{0}\002 is full."), channel);
+ return;
+ }
+
+ for (MemoServ::Ignore *ign : ignores)
+ if (ign->GetMask().equals_ci(param))
+ {
+ source.Reply(_("\002{0}\002 is already on your memo ignore list."), param);
+ return;
+ }
+
+ MemoServ::Ignore *ign = Serialize::New<MemoServ::Ignore *>();
+ ign->SetMemoInfo(mi);
+ ign->SetMask(param);
+
+ source.Reply(_("\002{0}\002 has been added to your memo ignore list."), param);
+ }
+ else if (command.equals_ci("DEL") && !param.empty())
+ {
+ for (MemoServ::Ignore *ign : ignores)
+ if (ign->GetMask().equals_ci(param))
+ {
+ delete ign;
+ source.Reply(_("\002{0}\002 has been removed from your memo ignore list."), param);
+ return;
+ }
+
+ source.Reply(_("\002{0}\002 is not on your memo ignore list."), param);
+ }
+ else if (command.equals_ci("LIST"))
+ {
+ if (ignores.empty())
+ {
+ source.Reply(_("Your memo ignore list is empty."));
+ return;
+ }
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Mask"));
+ for (MemoServ::Ignore *ign : ignores)
+ {
+ ListFormatter::ListEntry entry;
+ entry["Mask"] = ign->GetMask();
+ list.AddEntry(entry);
+ }
+
+ source.Reply(_("Memo ignore list:"));
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows you to ignore users from memoing you or a channel."
+ " If someone on the memo ignore list tries to memo you or a channel, they will not be told that you have them ignored."));
+ return true;
+ }
+};
+
+class MSIgnore : public Module
+{
+ CommandMSIgnore commandmsignore;
+
+ public:
+ MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsignore(this)
+ {
+ }
+};
+
+MODULE_INIT(MSIgnore)
diff --git a/modules/memoserv/info.cpp b/modules/memoserv/info.cpp
new file mode 100644
index 000000000..aff622b21
--- /dev/null
+++ b/modules/memoserv/info.cpp
@@ -0,0 +1,227 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandMSInfo : public Command
+{
+ public:
+ CommandMSInfo(Module *creator) : Command(creator, "memoserv/info", 0, 1)
+ {
+ this->SetDesc(_("Displays information about your memos"));
+ this->SetSyntax(_("[\037user\037 | \037channel\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ NickServ::Account *nc = source.nc;
+ MemoServ::MemoInfo *mi;
+ NickServ::Nick *na = NULL;
+ ChanServ::Channel *ci = NULL;
+ const Anope::string &nname = !params.empty() ? params[0] : "";
+ bool hardmax;
+
+ if (!nname.empty() && nname[0] != '#' && source.HasPriv("memoserv/info"))
+ {
+ na = NickServ::FindNick(nname);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nname);
+ return;
+ }
+ mi = na->GetAccount()->GetMemos();
+ hardmax = na->GetAccount()->HasFieldS("MEMO_HARDMAX");
+ }
+ else if (!nname.empty() && nname[0] == '#')
+ {
+ ci = ChanServ::Find(nname);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), nname);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+
+ mi = ci->GetMemos();
+ hardmax = ci->HasFieldS("MEMO_HARDMAX");
+ }
+ else if (!nname.empty()) /* It's not a chan and we aren't an oper */
+ {
+ source.Reply(_("Access denied. You do not have the correct operator privilege to see the memo info of \002{0}\002."), nname);
+ return;
+ }
+ else
+ {
+ mi = nc->GetMemos();
+ hardmax = nc->HasFieldS("MEMO_HARDMAX");
+ }
+ if (!mi)
+ return;
+
+ auto memos = mi->GetMemos();
+
+ if (!nname.empty() && (ci || na->GetAccount() != nc))
+ {
+ if (memos.empty())
+ source.Reply(_("%s currently has no memos."), nname.c_str());
+ else if (memos.size() == 1)
+ {
+ if (mi->GetMemo(0)->GetUnread())
+ source.Reply(_("\002{0}\002 currently has \0021\002 memo, and it has not yet been read."), nname);
+ else
+ source.Reply(_("\002{0}\002 currently has \0021\002 memo."), nname);
+ }
+ else
+ {
+ unsigned count = 0, i, end;
+ for (i = 0, end = memos.size(); i < end; ++i)
+ if (mi->GetMemo(i)->GetUnread())
+ ++count;
+ if (count == memos.size())
+ source.Reply(_("\002{0}\002 currently has \002{1]\002 memos; all of them are unread."), nname, count);
+ else if (!count)
+ source.Reply(_("\002{0}\002 currently has \002{1}\002 memos."), nname, memos.size());
+ else if (count == 1)
+ source.Reply(_("\002{0}\002 currently has \002{1}\002 memos, of which \0021\002 is unread."), nname, memos.size());
+ else
+ source.Reply(_("\002{0}\002 currently has \002{1]\002 memos, of which \002{2}\002 are unread."), nname, memos.size(), count);
+ }
+ if (mi->GetMemoMax() >= 0)
+ {
+ if (hardmax)
+ source.Reply(_("The memo limit of \002{0}\002 is \002{1}\002, and may not be changed."), nname, mi->GetMemoMax());
+ else
+ source.Reply(_("The memo limit of \002{0}\002 is \002{1}\002."), nname, mi->GetMemoMax());
+ }
+ else
+ source.Reply(_("\002{0}\002 has no memo limit."), nname);
+
+ if (na)
+ {
+ if (na->GetAccount()->HasFieldS("MEMO_RECEIVE") && na->GetAccount()->HasFieldS("MEMO_SIGNON"))
+ source.Reply(_("\002{0}\002 is notified of new memos at logon and when they arrive."), nname);
+ else if (na->GetAccount()->HasFieldS("MEMO_RECEIVE"))
+ source.Reply(_("\002{0}\002 is notified when new memos arrive."), nname);
+ else if (na->GetAccount()->HasFieldS("MEMO_SIGNON"))
+ source.Reply(_("\002{0}\002 is notified of news memos at logon."), nname);
+ else
+ source.Reply(_("\002{0}\002 is not notified of new memos."), nname);
+ }
+ }
+ else
+ {
+ if (memos.empty())
+ source.Reply(_("You currently have no memos."));
+ else if (memos.size() == 1)
+ {
+ if (mi->GetMemo(0)->GetUnread())
+ source.Reply(_("You currently have \0021\002 memo, and it has not yet been read."));
+ else
+ source.Reply(_("You currently have \0021\002 memo."));
+ }
+ else
+ {
+ unsigned count = 0, i, end;
+ for (i = 0, end = memos.size(); i < end; ++i)
+ if (mi->GetMemo(i)->GetUnread())
+ ++count;
+ if (count == memos.size())
+ source.Reply(_("You currently have \002{0}\002 memos; all of them are unread."), count);
+ else if (!count)
+ source.Reply(_("You currently have \002{0}\002 memos."), memos.size());
+ else if (count == 1)
+ source.Reply(_("You currently have \002{0}\002 memos, of which \0021\002 is unread."), memos.size());
+ else
+ source.Reply(_("You currently have \002{0}\002 memos, of which \002{1}\002 are unread."), memos.size(), count);
+ }
+
+ if (!mi->GetMemoMax())
+ {
+ if (!source.IsServicesOper() && hardmax)
+ source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit."));
+ else
+ source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos."));
+ }
+ else if (mi->GetMemoMax() > 0)
+ {
+ if (!source.IsServicesOper() && hardmax)
+ source.Reply(_("Your memo limit is \002{0}\002, and may not be changed."), mi->GetMemoMax());
+ else
+ source.Reply(_("Your memo limit is \002{0}\002."), mi->GetMemoMax());
+ }
+ else
+ source.Reply(_("You have no limit on the number of memos you may keep."));
+
+ bool memo_mail = nc->HasFieldS("MEMO_MAIL");
+ if (nc->HasFieldS("MEMO_RECEIVE") && nc->HasFieldS("MEMO_SIGNON"))
+ {
+ if (memo_mail)
+ source.Reply(_("You will be notified of new memos at logon and when they arrive, and by mail when they arrive."));
+ else
+ source.Reply(_("You will be notified of new memos at logon and when they arrive."));
+ }
+ else if (nc->HasFieldS("MEMO_RECEIVE"))
+ {
+ if (memo_mail)
+ source.Reply(_("You will be notified by message and by mail when new memos arrive."));
+ else
+ source.Reply(_("You will be notified when new memos arrive."));
+ }
+ else if (nc->HasFieldS("MEMO_SIGNON"))
+ {
+ if (memo_mail)
+ source.Reply(_("You will be notified of new memos at logon, and by mail when they arrive."));
+ else
+ source.Reply(_("You will be notified of new memos at logon."));
+ }
+ else
+ source.Reply(_("You will not be notified of new memos."));
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Without a parameter, displays information on the number of memos you have, how many of them are unread, and how many total memos you can receive."
+ " With a parameter, displays the same information for the given \037user\037 or \037channel\037, if you have the appropriate privilege.\n"
+ "\n"
+ "Use of this command on a channel requires the \002{0}\002 privilege on \037channel\037."),
+ source.command);
+
+ return true;
+ }
+};
+
+class MSInfo : public Module
+{
+ CommandMSInfo commandmsinfo;
+
+ public:
+ MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsinfo(this)
+ {
+
+ }
+};
+
+MODULE_INIT(MSInfo)
diff --git a/modules/memoserv/list.cpp b/modules/memoserv/list.cpp
new file mode 100644
index 000000000..0fd169cc2
--- /dev/null
+++ b/modules/memoserv/list.cpp
@@ -0,0 +1,171 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandMSList : public Command
+{
+ public:
+ CommandMSList(Module *creator) : Command(creator, "memoserv/list", 0, 2)
+ {
+ this->SetDesc(_("List your memos"));
+ this->SetSyntax(_("[\037channel\037] [\037list\037 | NEW]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ Anope::string param = !params.empty() ? params[0] : "", chan;
+ ChanServ::Channel *ci = NULL;
+ MemoServ::MemoInfo *mi;
+
+ if (!param.empty() && param[0] == '#')
+ {
+ chan = param;
+ param = params.size() > 1 ? params[1] : "";
+
+ ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+
+ mi = ci->GetMemos();
+ }
+ else
+ mi = source.nc->GetMemos();
+
+ if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW"))
+ {
+ this->OnSyntaxError(source, param);
+ return;
+ }
+
+ if (!mi)
+ return;
+
+ auto memos = mi->GetMemos();
+
+ if (!memos.size())
+ {
+ if (!chan.empty())
+ source.Reply(_("\002{0}\002 has no memos."), chan);
+ else
+ source.Reply(_("You have no memos."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+
+ list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time"));
+
+ if (!param.empty() && isdigit(param[0]))
+ {
+ NumberList(param, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > memos.size())
+ return;
+
+ MemoServ::Memo *m = mi->GetMemo(number - 1);
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = (m->GetUnread() ? "* " : " ") + stringify(number);
+ entry["Sender"] = m->GetSender();
+ entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount());
+ list.AddEntry(entry);
+ },
+ []{});
+ }
+ else
+ {
+ if (!param.empty())
+ {
+ unsigned i, end;
+ for (i = 0, end = memos.size(); i < end; ++i)
+ if (mi->GetMemo(i)->GetUnread())
+ break;
+ if (i == end)
+ {
+ if (!chan.empty())
+ source.Reply(_("\002{0}\002 has no new memos."), chan);
+ else
+ source.Reply(_("You have no new memos."));
+ return;
+ }
+ }
+
+ for (unsigned i = 0, end = memos.size(); i < end; ++i)
+ {
+ if (!param.empty() && !mi->GetMemo(i)->GetUnread())
+ continue;
+
+ MemoServ::Memo *m = mi->GetMemo(i);
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = (m->GetUnread() ? "* " : " ") + stringify(i + 1);
+ entry["Sender"] = m->GetSender();
+ entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount());
+ list.AddEntry(entry);
+ }
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ source.Reply(_("Memos for \002{0}\002:"), ci ? ci->GetName().c_str() : source.GetNick().c_str());
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Lists the memos you currently have."
+ " With \002NEW\002, lists only new (unread) memos."
+ " Unread memos are marked with a \"*\" to the left of the memo number."
+ " You can also specify a list of numbers, as in the example below:\n"
+ "\n"
+ "Example:\n"
+ "\n"
+ " {0} 2-5,7-9\n"
+ " Lists memos numbered 2 through 5 and 7 through 9."));
+ return true;
+ }
+};
+
+class MSList : public Module
+{
+ CommandMSList commandmslist;
+
+ public:
+ MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmslist(this)
+ {
+
+ }
+};
+
+MODULE_INIT(MSList)
diff --git a/modules/memoserv/main/CMakeLists.txt b/modules/memoserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/memoserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/memoserv/main/ignore.cpp b/modules/memoserv/main/ignore.cpp
new file mode 100644
index 000000000..8ac15484f
--- /dev/null
+++ b/modules/memoserv/main/ignore.cpp
@@ -0,0 +1,46 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "memo.h"
+#include "ignoretype.h"
+
+IgnoreImpl::~IgnoreImpl()
+{
+}
+
+MemoServ::MemoInfo *IgnoreImpl::GetMemoInfo()
+{
+ return Get(&IgnoreType::mi);
+}
+
+void IgnoreImpl::SetMemoInfo(MemoServ::MemoInfo *m)
+{
+ Set(&IgnoreType::mi, m);
+}
+
+Anope::string IgnoreImpl::GetMask()
+{
+ return Get(&IgnoreType::mask);
+}
+
+void IgnoreImpl::SetMask(const Anope::string &mask)
+{
+ Set(&IgnoreType::mask, mask);
+}
+
diff --git a/modules/memoserv/main/ignore.h b/modules/memoserv/main/ignore.h
new file mode 100644
index 000000000..3c632a74e
--- /dev/null
+++ b/modules/memoserv/main/ignore.h
@@ -0,0 +1,39 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/memoserv.h"
+
+class IgnoreImpl : public MemoServ::Ignore
+{
+ friend class IgnoreType;
+
+ MemoServ::MemoInfo *memoinfo = nullptr;
+ Anope::string mask;
+
+ public:
+ IgnoreImpl(Serialize::TypeBase *type) : MemoServ::Ignore(type) { }
+ IgnoreImpl(Serialize::TypeBase *type, Serialize::ID id) : MemoServ::Ignore(type, id) { }
+ ~IgnoreImpl();
+
+ MemoServ::MemoInfo *GetMemoInfo() override;
+ void SetMemoInfo(MemoServ::MemoInfo *) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &mask) override;
+};
diff --git a/modules/memoserv/main/ignoretype.cpp b/modules/memoserv/main/ignoretype.cpp
new file mode 100644
index 000000000..940214803
--- /dev/null
+++ b/modules/memoserv/main/ignoretype.cpp
@@ -0,0 +1,29 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "ignoretype.h"
+
+IgnoreType::IgnoreType(Module *me) : Serialize::Type<IgnoreImpl>(me)
+ , mi(this, "mi", &IgnoreImpl::memoinfo, true)
+ , mask(this, "mask", &IgnoreImpl::mask)
+{
+
+}
+
diff --git a/modules/memoserv/main/ignoretype.h b/modules/memoserv/main/ignoretype.h
new file mode 100644
index 000000000..3b8f510a8
--- /dev/null
+++ b/modules/memoserv/main/ignoretype.h
@@ -0,0 +1,29 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ignore.h"
+
+class IgnoreType : public Serialize::Type<IgnoreImpl>
+{
+ public:
+ Serialize::ObjectField<IgnoreImpl, MemoServ::MemoInfo *> mi;
+ Serialize::Field<IgnoreImpl, Anope::string> mask;
+
+ IgnoreType(Module *);
+};
diff --git a/modules/memoserv/main/memo.cpp b/modules/memoserv/main/memo.cpp
new file mode 100644
index 000000000..e148040f4
--- /dev/null
+++ b/modules/memoserv/main/memo.cpp
@@ -0,0 +1,85 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "memotype.h"
+
+MemoImpl::~MemoImpl()
+{
+}
+
+MemoServ::MemoInfo *MemoImpl::GetMemoInfo()
+{
+ return Get(&MemoType::mi);
+}
+
+void MemoImpl::SetMemoInfo(MemoServ::MemoInfo *mi)
+{
+ Set(&MemoType::mi, mi);
+}
+
+time_t MemoImpl::GetTime()
+{
+ return Get(&MemoType::time);
+}
+
+void MemoImpl::SetTime(const time_t &t)
+{
+ Set(&MemoType::time, t);
+}
+
+Anope::string MemoImpl::GetSender()
+{
+ return Get(&MemoType::sender);
+}
+
+void MemoImpl::SetSender(const Anope::string &s)
+{
+ Set(&MemoType::sender, s);
+}
+
+Anope::string MemoImpl::GetText()
+{
+ return Get(&MemoType::text);
+}
+
+void MemoImpl::SetText(const Anope::string &t)
+{
+ Set(&MemoType::text, t);
+}
+
+bool MemoImpl::GetUnread()
+{
+ return Get(&MemoType::unread);
+}
+
+void MemoImpl::SetUnread(const bool &b)
+{
+ Set(&MemoType::unread, b);
+}
+
+bool MemoImpl::GetReceipt()
+{
+ return Get(&MemoType::receipt);
+}
+
+void MemoImpl::SetReceipt(const bool &b)
+{
+ Set(&MemoType::receipt, b);
+}
+
diff --git a/modules/memoserv/main/memo.h b/modules/memoserv/main/memo.h
new file mode 100644
index 000000000..5eac706db
--- /dev/null
+++ b/modules/memoserv/main/memo.h
@@ -0,0 +1,53 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/memoserv.h"
+
+class MemoImpl : public MemoServ::Memo
+{
+ friend class MemoType;
+
+ MemoServ::MemoInfo *memoinfo = nullptr;
+ Anope::string text, sender;
+ time_t time = 0;
+ bool unread = false, receipt = false;
+
+ public:
+ MemoImpl(Serialize::TypeBase *type) : MemoServ::Memo(type) { }
+ MemoImpl(Serialize::TypeBase *type, Serialize::ID id) : MemoServ::Memo(type, id) { }
+ ~MemoImpl();
+
+ MemoServ::MemoInfo *GetMemoInfo() override;
+ void SetMemoInfo(MemoServ::MemoInfo *) override;
+
+ time_t GetTime() override;
+ void SetTime(const time_t &) override;
+
+ Anope::string GetSender() override;
+ void SetSender(const Anope::string &) override;
+
+ Anope::string GetText() override;
+ void SetText(const Anope::string &) override;
+
+ bool GetUnread() override;
+ void SetUnread(const bool &) override;
+
+ bool GetReceipt() override;
+ void SetReceipt(const bool &) override;
+};
diff --git a/modules/memoserv/main/memoinfo.cpp b/modules/memoserv/main/memoinfo.cpp
new file mode 100644
index 000000000..6fa8df8b1
--- /dev/null
+++ b/modules/memoserv/main/memoinfo.cpp
@@ -0,0 +1,82 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "memoinfotype.h"
+
+MemoServ::Memo *MemoInfoImpl::GetMemo(unsigned index)
+{
+ auto memos = GetMemos();
+ return index >= memos.size() ? nullptr : memos[index];
+}
+
+unsigned MemoInfoImpl::GetIndex(MemoServ::Memo *m)
+{
+ auto memos = GetMemos();
+ for (unsigned i = 0; i < memos.size(); ++i)
+ if (this->GetMemo(i) == m)
+ return i;
+ return -1; // XXX wtf?
+}
+
+void MemoInfoImpl::Del(unsigned index)
+{
+ delete GetMemo(index);
+}
+
+bool MemoInfoImpl::HasIgnore(User *u)
+{
+ for (MemoServ::Ignore *ign : GetIgnores())
+ {
+ const Anope::string &mask = ign->GetMask();
+ if (u->nick.equals_ci(mask) || (u->Account() && u->Account()->GetDisplay().equals_ci(mask)) || Anope::Match(u->GetMask(), mask))
+ return true;
+ }
+ return false;
+}
+
+Serialize::Object *MemoInfoImpl::GetOwner()
+{
+ return Get(&MemoInfoType::owner);
+}
+
+void MemoInfoImpl::SetOwner(Serialize::Object *o)
+{
+ Set(&MemoInfoType::owner, o);
+}
+
+int16_t MemoInfoImpl::GetMemoMax()
+{
+ return Get(&MemoInfoType::memomax);
+}
+
+void MemoInfoImpl::SetMemoMax(const int16_t &i)
+{
+ Set(&MemoInfoType::memomax, i);
+}
+
+std::vector<MemoServ::Memo *> MemoInfoImpl::GetMemos()
+{
+ return GetRefs<MemoServ::Memo *>();
+}
+
+std::vector<MemoServ::Ignore *> MemoInfoImpl::GetIgnores()
+{
+ return GetRefs<MemoServ::Ignore *>();
+}
+
diff --git a/modules/memoserv/main/memoinfo.h b/modules/memoserv/main/memoinfo.h
new file mode 100644
index 000000000..79deb496b
--- /dev/null
+++ b/modules/memoserv/main/memoinfo.h
@@ -0,0 +1,47 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/memoserv.h"
+
+class MemoInfoImpl : public MemoServ::MemoInfo
+{
+ friend class MemoInfoType;
+
+ Serialize::Object *owner = nullptr;
+ int16_t memomax = 0;
+
+ public:
+ MemoInfoImpl(Serialize::TypeBase *type) : MemoServ::MemoInfo(type) { }
+ MemoInfoImpl(Serialize::TypeBase *type, Serialize::ID id) : MemoServ::MemoInfo(type, id) { }
+
+ MemoServ::Memo *GetMemo(unsigned index) override;
+ unsigned GetIndex(MemoServ::Memo *m) override;
+ void Del(unsigned index) override;
+ bool HasIgnore(User *u) override;
+
+ Serialize::Object *GetOwner() override;
+ void SetOwner(Serialize::Object *) override;
+
+ int16_t GetMemoMax() override;
+ void SetMemoMax(const int16_t &) override;
+
+ std::vector<MemoServ::Memo *> GetMemos() override;
+ std::vector<MemoServ::Ignore *> GetIgnores() override;
+};
+
diff --git a/modules/memoserv/main/memoinfotype.cpp b/modules/memoserv/main/memoinfotype.cpp
new file mode 100644
index 000000000..3447de5c8
--- /dev/null
+++ b/modules/memoserv/main/memoinfotype.cpp
@@ -0,0 +1,29 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "memoinfotype.h"
+
+MemoInfoType::MemoInfoType(Module *me) : Serialize::Type<MemoInfoImpl>(me)
+ , owner(this, "owner", &MemoInfoImpl::owner, true)
+ , memomax(this, "memomax", &MemoInfoImpl::memomax)
+{
+
+}
+
diff --git a/modules/memoserv/main/memoinfotype.h b/modules/memoserv/main/memoinfotype.h
new file mode 100644
index 000000000..97af31917
--- /dev/null
+++ b/modules/memoserv/main/memoinfotype.h
@@ -0,0 +1,29 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "memoinfo.h"
+
+class MemoInfoType : public Serialize::Type<MemoInfoImpl>
+{
+ public:
+ Serialize::ObjectField<MemoInfoImpl, Serialize::Object *> owner;
+ Serialize::Field<MemoInfoImpl, int16_t> memomax;
+
+ MemoInfoType(Module *);
+};
diff --git a/modules/memoserv/main/memoserv.cpp b/modules/memoserv/main/memoserv.cpp
new file mode 100644
index 000000000..a8e9b4e81
--- /dev/null
+++ b/modules/memoserv/main/memoserv.cpp
@@ -0,0 +1,305 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/update.h"
+#include "modules/help.h"
+#include "modules/botserv/bot.h"
+#include "modules/memoserv.h"
+#include "memotype.h"
+#include "memoinfotype.h"
+#include "ignoretype.h"
+
+class MemoServCore : public Module, public MemoServ::MemoServService
+ , public EventHook<NickServ::Event::NickRegister>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::BotDelete>
+ , public EventHook<Event::NickIdentify>
+ , public EventHook<Event::JoinChannel>
+ , public EventHook<Event::UserAway>
+ , public EventHook<Event::NickUpdate>
+ , public EventHook<Event::Help>
+{
+ Reference<ServiceBot> MemoServ;
+
+ MemoInfoType memoinfo_type;
+ MemoType memo_type;
+ IgnoreType ignore_type;
+
+ bool SendMemoMail(NickServ::Account *nc, MemoServ::MemoInfo *mi, MemoServ::Memo *m)
+ {
+ Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<Anope::string>("memo_subject").c_str()),
+ message = Language::Translate(Config->GetBlock("mail")->Get<Anope::string>("memo_message").c_str());
+
+ subject = subject.replace_all_cs("%n", nc->GetDisplay());
+ subject = subject.replace_all_cs("%s", m->GetSender());
+ subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
+ subject = subject.replace_all_cs("%t", m->GetText());
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+
+ message = message.replace_all_cs("%n", nc->GetDisplay());
+ message = message.replace_all_cs("%s", m->GetSender());
+ message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
+ message = message.replace_all_cs("%t", m->GetText());
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+
+ return Mail::Send(nc, subject, message);
+ }
+
+ public:
+ MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , MemoServ::MemoServService(this)
+
+ , EventHook<NickServ::Event::NickRegister>(this)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::BotDelete>(this)
+ , EventHook<Event::NickIdentify>(this)
+ , EventHook<Event::JoinChannel>(this)
+ , EventHook<Event::UserAway>(this)
+ , EventHook<Event::NickUpdate>(this)
+ , EventHook<Event::Help>(this)
+
+ , memoinfo_type(this)
+ , memo_type(this)
+ , ignore_type(this)
+ {
+ MemoServ::service = this;
+ }
+
+ ~MemoServCore()
+ {
+ MemoServ::service = nullptr;
+ }
+
+ MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) override
+ {
+ bool ischan, isregistered;
+ MemoServ::MemoInfo *mi = GetMemoInfo(target, ischan, isregistered, true);
+
+ if (mi == NULL)
+ return MEMO_INVALID_TARGET;
+
+ User *sender = User::Find(source, true);
+ if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force)
+ {
+ time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
+ if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime)
+ return MEMO_TOO_FAST;
+ else if (!mi->GetMemoMax())
+ return MEMO_TARGET_FULL;
+ else if (mi->GetMemoMax() > 0 && mi->GetMemos().size() >= static_cast<unsigned>(mi->GetMemoMax()))
+ return MEMO_TARGET_FULL;
+ else if (mi->HasIgnore(sender))
+ return MEMO_SUCCESS;
+ }
+
+ if (sender != NULL)
+ sender->lastmemosend = Anope::CurTime;
+
+ MemoServ::Memo *m = Serialize::New<MemoServ::Memo *>();
+ m->SetMemoInfo(mi);
+ m->SetSender(source);
+ m->SetTime(Anope::CurTime);
+ m->SetText(message);
+ m->SetUnread(true);
+
+ EventManager::Get()->Dispatch(&MemoServ::Event::MemoSend::OnMemoSend, source, target, mi, m);
+
+ if (ischan)
+ {
+ ChanServ::Channel *ci = ChanServ::Find(target);
+
+ if (ci->c)
+ {
+ for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *cu = it->second;
+
+ if (ci->AccessFor(cu->user).HasPriv("MEMO"))
+ {
+ if (cu->user->Account() && cu->user->Account()->HasFieldS("MEMO_RECEIVE"))
+ cu->user->SendMessage(*MemoServ, _("There is a new memo on channel \002{0}\002. Type \002{1}{2} READ {3} {4}\002 to read it."), ci->GetName(), Config->StrictPrivmsg, MemoServ->nick, ci->GetName(), mi->GetMemos().size()); // XXX
+ }
+ }
+ }
+ }
+ else
+ {
+ NickServ::Account *nc = NickServ::FindNick(target)->GetAccount();
+
+ if (nc->HasFieldS("MEMO_RECEIVE"))
+ for (User *u : nc->users)
+ u->SendMessage(*MemoServ, _("You have a new memo from \002{0}\002. Type \002{1}{2} READ {3}\002 to read it."), source, Config->StrictPrivmsg, MemoServ->nick, mi->GetMemos().size());//XXX
+
+ /* let's get out the mail if set in the nickcore - certus */
+ if (nc->HasFieldS("MEMO_MAIL"))
+ SendMemoMail(nc, mi, m);
+ }
+
+ return MEMO_SUCCESS;
+ }
+
+ void Check(User *u) override
+ {
+ NickServ::Account *nc = u->Account();
+ if (!nc || !nc->GetMemos())
+ return;
+
+ auto memos = nc->GetMemos()->GetMemos();
+ unsigned i = 0, end = memos.size(), newcnt = 0;
+ for (; i < end; ++i)
+ if (memos[i]->GetUnread())
+ ++newcnt;
+ if (newcnt > 0)
+ u->SendMessage(*MemoServ, newcnt == 1 ? _("You have 1 new memo.") : _("You have %d new memos."), newcnt);
+ if (nc->GetMemos()->GetMemoMax() > 0 && memos.size() >= static_cast<unsigned>(nc->GetMemos()->GetMemoMax()))
+ {
+ if (memos.size() > static_cast<unsigned>(nc->GetMemos()->GetMemoMax()))
+ u->SendMessage(*MemoServ, _("You are over your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->GetMemos()->GetMemoMax());
+ else
+ u->SendMessage(*MemoServ, _("You have reached your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->GetMemos()->GetMemoMax());
+ }
+ }
+
+ MemoServ::MemoInfo *GetMemoInfo(const Anope::string &target, bool &is_registered, bool &ischan, bool create) override
+ {
+ if (!target.empty() && target[0] == '#')
+ {
+ ischan = true;
+ ChanServ::Channel *ci = ChanServ::Find(target);
+ if (ci != NULL)
+ {
+ is_registered = true;
+ if (create && !ci->GetMemos())
+ {
+ MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
+ mi->SetOwner(ci);
+ }
+ return ci->GetMemos();
+ }
+ else
+ is_registered = false;
+ }
+ else
+ {
+ ischan = false;
+ NickServ::Nick *na = NickServ::FindNick(target);
+ if (na != NULL)
+ {
+ is_registered = true;
+ if (create && !na->GetAccount()->GetMemos())
+ {
+ MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
+ mi->SetOwner(na->GetAccount());
+ }
+ return na->GetAccount()->GetMemos();
+ }
+ else
+ is_registered = false;
+ }
+
+ return NULL;
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &msnick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (msnick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(msnick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + msnick);
+
+ MemoServ = bi;
+ }
+
+ void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &) override
+ {
+ MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
+ mi->SetOwner(na->GetAccount());
+ mi->SetMemoMax(Config->GetModule(this)->Get<int>("maxmemos"));
+ }
+
+ void OnChanRegistered(ChanServ::Channel *ci) override
+ {
+ MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
+ mi->SetOwner(ci);
+ mi->SetMemoMax(Config->GetModule(this)->Get<int>("maxmemos"));
+ }
+
+ void OnBotDelete(ServiceBot *bi) override
+ {
+ if (bi == MemoServ)
+ MemoServ = NULL;
+ }
+
+ void OnNickIdentify(User *u) override
+ {
+ this->Check(u);
+ }
+
+ void OnJoinChannel(User *u, Channel *c) override
+ {
+ if (u->server && u->server->IsSynced() && c->ci && c->ci->GetMemos() && !c->ci->GetMemos()->GetMemos().empty() && c->ci->AccessFor(u).HasPriv("MEMO"))
+ {
+ if (c->ci->GetMemos()->GetMemos().size() == 1)
+ u->SendMessage(*MemoServ, _("There is \002{0}\002 memo on channel \002{1}\002."), c->ci->GetMemos()->GetMemos().size(), c->ci->GetName());
+ else
+ u->SendMessage(*MemoServ, _("There are \002{0}\002 memos on channel \002{1}\002."), c->ci->GetMemos()->GetMemos().size(), c->ci->GetName());
+ }
+ }
+
+ void OnUserAway(User *u, const Anope::string &message) override
+ {
+ if (message.empty())
+ this->Check(u);
+ }
+
+ void OnNickUpdate(User *u) override
+ {
+ this->Check(u);
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *MemoServ)
+ return EVENT_CONTINUE;
+ source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
+ "messages to other IRC users, whether they are online at\n"
+ "the time or not, or to channels(*). Both the sender's\n"
+ "nickname and the target nickname or channel must be\n"
+ "registered in order to send a memo.\n"
+ "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *MemoServ)
+ return;
+ source.Reply(_(" \n"
+ "Type \002%s%s HELP \037command\037\002 for help on any of the\n"
+ "above commands."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str());
+ }
+};
+
+MODULE_INIT(MemoServCore)
+
diff --git a/modules/memoserv/main/memotype.cpp b/modules/memoserv/main/memotype.cpp
new file mode 100644
index 000000000..13898de77
--- /dev/null
+++ b/modules/memoserv/main/memotype.cpp
@@ -0,0 +1,33 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "memotype.h"
+
+MemoType::MemoType(Module *me) : Serialize::Type<MemoImpl>(me)
+ , mi(this, "mi", &MemoImpl::memoinfo, true)
+ , time(this, "time", &MemoImpl::time)
+ , sender(this, "sender", &MemoImpl::sender)
+ , text(this, "text", &MemoImpl::text)
+ , unread(this, "unread", &MemoImpl::unread)
+ , receipt(this, "receipt", &MemoImpl::receipt)
+{
+
+}
+
diff --git a/modules/memoserv/main/memotype.h b/modules/memoserv/main/memotype.h
new file mode 100644
index 000000000..b9b136976
--- /dev/null
+++ b/modules/memoserv/main/memotype.h
@@ -0,0 +1,32 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "memo.h"
+
+class MemoType : public Serialize::Type<MemoImpl>
+{
+ public:
+ Serialize::ObjectField<MemoImpl, MemoServ::MemoInfo *> mi;
+ Serialize::Field<MemoImpl, time_t> time;
+ Serialize::Field<MemoImpl, Anope::string> sender;
+ Serialize::Field<MemoImpl, Anope::string> text;
+ Serialize::Field<MemoImpl, bool> unread, receipt;
+
+ MemoType(Module *);
+};
diff --git a/modules/memoserv/read.cpp b/modules/memoserv/read.cpp
new file mode 100644
index 000000000..62d6cd4d2
--- /dev/null
+++ b/modules/memoserv/read.cpp
@@ -0,0 +1,217 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+static void rsend_notify(CommandSource &source, MemoServ::MemoInfo *mi, MemoServ::Memo *m, const Anope::string &targ)
+{
+ /* Only send receipt if memos are allowed */
+ if (MemoServ::service && !Anope::ReadOnly)
+ {
+ /* Get nick alias for sender */
+ NickServ::Nick *na = NickServ::FindNick(m->GetSender());
+
+ if (!na)
+ return;
+
+ /* Get nick core for sender */
+ NickServ::Account *nc = na->GetAccount();
+
+ if (!nc)
+ return;
+
+ /* Text of the memo varies if the recipient was a
+ nick or channel */
+ Anope::string text = Anope::printf(Language::Translate(na->GetAccount(), _("\002[auto-memo]\002 The memo you sent to \002%s\002 has been viewed.")), targ.c_str());
+
+ /* Send notification */
+ MemoServ::service->Send(source.GetNick(), m->GetSender(), text, true);
+
+ /* Notify recipient of the memo that a notification has
+ been sent to the sender */
+ source.Reply(_("A notification memo has been sent to \002{0}\002 informing him/her you have read his/her memo."), nc->GetDisplay());
+ }
+
+ /* Remove receipt flag from the original memo */
+ m->SetReceipt(false);
+}
+
+class CommandMSRead : public Command
+{
+ static void DoRead(CommandSource &source, MemoServ::MemoInfo *mi, ChanServ::Channel *ci, unsigned index)
+ {
+ MemoServ::Memo *m = mi->GetMemo(index);
+ if (!m)
+ return;
+
+ if (ci)
+ source.Reply(_("Memo \002{0}\002 from \002{1}\002 (\002{2}\002)."), index + 1, m->GetSender(), Anope::strftime(m->GetTime(), source.GetAccount()));
+ else
+ source.Reply(_("Memo \002{0}\002 from \002{1}\002 (\002{2}\002)."), index + 1, m->GetSender(), Anope::strftime(m->GetTime(), source.GetAccount()));
+
+ ServiceBot *bi;
+ Anope::string cmd;
+ if (Command::FindCommandFromService("memoserv/del", bi, cmd))
+ {
+ if (ci)
+ source.Reply(_("To delete, use \002{0}{1} {2} {3} {4}\002"), Config->StrictPrivmsg, bi->nick, cmd, ci->GetName(), index + 1);
+ else
+ source.Reply(_("To delete, use \002{0}{1} {2} {3}\002"), Config->StrictPrivmsg, bi->nick, cmd, index + 1);
+ }
+
+ source.Reply(m->GetText());
+ m->SetUnread(false);
+
+ /* Check if a receipt notification was requested */
+ if (m->GetReceipt())
+ rsend_notify(source, mi, m, ci ? ci->GetName() : source.GetNick());
+ }
+
+ public:
+ CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2)
+ {
+ this->SetDesc(_("Read a memo or memos"));
+ this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ MemoServ::MemoInfo *mi;
+ ChanServ::Channel *ci = NULL;
+ Anope::string numstr = params[0], chan;
+
+ if (!numstr.empty() && numstr[0] == '#')
+ {
+ chan = numstr;
+ numstr = params.size() > 1 ? params[1] : "";
+
+ ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+
+ mi = ci->GetMemos();
+ }
+ else
+ mi = source.nc->GetMemos();
+
+ if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && numstr.find_first_not_of("0123456789.,-") != Anope::string::npos))
+ {
+ this->OnSyntaxError(source, numstr);
+ return;
+ }
+
+ if (!mi)
+ return;
+
+ auto memos = mi->GetMemos();
+
+ if (memos.empty())
+ {
+ if (!chan.empty())
+ source.Reply(_("\002{0}\002 has no memos."), chan);
+ else
+ source.Reply(_("You have no memos."));
+ return;
+ }
+
+ int i, end;
+
+ if (numstr.equals_ci("NEW"))
+ {
+ int readcount = 0;
+ for (i = 0, end = memos.size(); i < end; ++i)
+ if (mi->GetMemo(i)->GetUnread())
+ {
+ DoRead(source, mi, ci, i);
+ ++readcount;
+ }
+ if (!readcount)
+ {
+ if (!chan.empty())
+ source.Reply(_("\002{0}\002 has no new memos."), chan);
+ else
+ source.Reply(_("You have no new memos."));
+ }
+ }
+ else if (numstr.equals_ci("LAST"))
+ {
+ for (i = 0, end = memos.size() - 1; i < end; ++i);
+ DoRead(source, mi, ci, i);
+ }
+ else /* number[s] */
+ {
+ bool shown = false;
+
+ NumberList(numstr, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > memos.size())
+ return;
+
+ shown = true;
+ DoRead(source, mi, ci, number - 1);
+ },
+ []{});
+
+ if (!shown)
+ source.Reply(_("No memos to display."));
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sends you the text of the memos specified."
+ " If LAST is given, sends you the memo you most recently received."
+ " If NEW is given, sends you all of your new memos."
+ " Otherwise, sends you memo number \037num\037."
+ " You can also give a list of numbers, as in the example:\n"
+ "\n"
+ "Example:\n"
+ "\n"
+ " {0} 2-5,7-9\n"
+ " Displays memos numbered 2 through 5 and 7 through 9."),
+ source.command);
+ return true;
+ }
+};
+
+class MSRead : public Module
+{
+ CommandMSRead commandmsread;
+
+ public:
+ MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsread(this)
+ {
+
+ }
+};
+
+MODULE_INIT(MSRead)
diff --git a/modules/memoserv/rsend.cpp b/modules/memoserv/rsend.cpp
new file mode 100644
index 000000000..2656ffd3a
--- /dev/null
+++ b/modules/memoserv/rsend.cpp
@@ -0,0 +1,114 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSRSend : public Command
+{
+ public:
+ CommandMSRSend(Module *creator) : Command(creator, "memoserv/rsend", 2, 2)
+ {
+ this->SetDesc(_("Sends a memo and requests a read receipt"));
+ this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+#warning "this is completely disabled"
+#if 0
+ if (!MemoServ::service)
+ return;
+
+ if (Anope::ReadOnly && !source.IsOper())
+ {
+ source.Reply(_("Sorry, memo sending is temporarily disabled."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+ const Anope::string &text = params[1];
+ const NickServ::Nick *na = NULL;
+
+ /* prevent user from rsend to themselves */
+ if ((na = NickServ::FindNick(nick)) && na->GetAccount() == source.GetAccount())
+ {
+ source.Reply(_("You can not request a receipt when sending a memo to yourself."));
+ return;
+ }
+
+ if (Config->GetModule(this->GetOwner())->Get<bool>("operonly") && !source.IsServicesOper())
+ source.Reply(_("Access denied. This command is for operators only."));
+ else
+ {
+ MemoServ::MemoServService::MemoResult result = MemoServ::service->Send(source.GetNick(), nick, text);
+ if (result == MemoServ::MemoServService::MEMO_INVALID_TARGET)
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ else if (result == MemoServ::MemoServService::MEMO_TOO_FAST)
+ source.Reply(_("Please wait \002{0}\002 seconds before using the \002{1}\002 command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command);
+ else if (result == MemoServ::MemoServService::MEMO_TARGET_FULL)
+ source.Reply(_("Sorry, \002{0}\002 currently has too many memos and cannot receive more."), nick);
+ else
+ {
+ source.Reply(_("Memo sent to \002{0}\002."), nick);
+
+ bool ischan, isregistered;
+ MemoServ::MemoInfo *mi = MemoServ::service->GetMemoInfo(nick, ischan, isregistered, false);
+ if (mi == NULL)
+ throw CoreException("NULL mi in ms_rsend");
+ MemoServ::Memo *m = (mi->memos->size() ? mi->GetMemo(mi->memos->size() - 1) : NULL);
+ if (m != NULL)
+ m->receipt = true;
+ }
+ }
+#endif
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+#if 0
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Sends the named \037nick\037 or \037channel\037 a memo containing\n"
+ "\037memo-text\037. When sending to a nickname, the recipient will\n"
+ "receive a notice that he/she has a new memo. The target\n"
+ "nickname/channel must be registered.\n"
+ "Once the memo is read by its recipient, an automatic notification\n"
+ "memo will be sent to the sender informing him/her that the memo\n"
+ "has been read."));
+ return true;
+#endif
+ }
+};
+
+class MSRSend : public Module
+{
+ CommandMSRSend commandmsrsend;
+
+ public:
+ MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsrsend(this)
+ {
+ if (!MemoServ::service)
+ throw ModuleException("No MemoServ!");
+ throw ModuleException("XXX");
+ }
+};
+
+MODULE_INIT(MSRSend)
diff --git a/modules/memoserv/send.cpp b/modules/memoserv/send.cpp
new file mode 100644
index 000000000..f06e62bab
--- /dev/null
+++ b/modules/memoserv/send.cpp
@@ -0,0 +1,89 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSSend : public Command
+{
+ public:
+ CommandMSSend(Module *creator) : Command(creator, "memoserv/send", 2, 2)
+ {
+ this->SetDesc(_("Send a memo to a nick or channel"));
+ this->SetSyntax(_("{\037user\037 | \037channel\037} \037memo-text\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!MemoServ::service)
+ return;
+
+ const Anope::string &nick = params[0];
+ const Anope::string &text = params[1];
+
+ if (Anope::ReadOnly && !source.IsOper())
+ {
+ source.Reply(_("Sorry, memo sending is temporarily disabled."));
+ return;
+ }
+
+ if (source.GetAccount()->HasFieldS("UNCONFIRMED"))
+ {
+ source.Reply(_("You must confirm your account before you may send a memo."));
+ return;
+ }
+
+ MemoServ::MemoServService::MemoResult result = MemoServ::service->Send(source.GetNick(), nick, text);
+ if (result == MemoServ::MemoServService::MEMO_SUCCESS)
+ {
+ source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
+ Log(LOG_COMMAND, source, this) << "to send a memo to " << nick;
+ }
+ else if (result == MemoServ::MemoServService::MEMO_INVALID_TARGET)
+ source.Reply(_("\002{0}\002 is not a registered unforbidden nick or channel."), nick);
+ else if (result == MemoServ::MemoServService::MEMO_TOO_FAST)
+ source.Reply(_("Please wait \002{0}\002 seconds before using the \002{1}\002 command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command);
+ else if (result == MemoServ::MemoServService::MEMO_TARGET_FULL)
+ source.Reply(_("Sorry, \002{0}\002 currently has too many memos and cannot receive more."), nick);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sends the named \037user\037 or \037channel\037 a memo containing \037memo-text\037."
+ " The recipient will receive a notice that they have a new memo."
+ " The target user or channel must be registered."));
+ return true;
+ }
+};
+
+class MSSend : public Module
+{
+ CommandMSSend commandmssend;
+
+ public:
+ MSSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmssend(this)
+ {
+
+ if (!MemoServ::service)
+ throw ModuleException("No MemoServ!");
+ }
+};
+
+MODULE_INIT(MSSend)
diff --git a/modules/memoserv/sendall.cpp b/modules/memoserv/sendall.cpp
new file mode 100644
index 000000000..9ab2a649e
--- /dev/null
+++ b/modules/memoserv/sendall.cpp
@@ -0,0 +1,68 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSSendAll : public Command
+{
+ public:
+ CommandMSSendAll(Module *creator) : Command(creator, "memoserv/sendall", 1, 1)
+ {
+ this->SetDesc(_("Send a memo to all registered users"));
+ this->SetSyntax(_("\037memo-text\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!MemoServ::service)
+ return;
+
+ const Anope::string &text = params[0];
+
+ Log(LOG_ADMIN, source, this) << "to send " << text;
+
+ for (NickServ::Account *nc : NickServ::service->GetAccountList())
+ if (nc != source.nc)
+ MemoServ::service->Send(source.GetNick(), nc->GetDisplay(), text);
+
+ source.Reply(_("A mass memo has been sent to all registered users."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sends all registered users a memo containing \037memo-text\037."));
+ return true;
+ }
+};
+
+class MSSendAll : public Module
+{
+ CommandMSSendAll commandmssendall;
+
+ public:
+ MSSendAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmssendall(this)
+ {
+ if (!MemoServ::service)
+ throw ModuleException("No MemoServ!");
+ }
+};
+
+MODULE_INIT(MSSendAll)
diff --git a/modules/memoserv/set.cpp b/modules/memoserv/set.cpp
new file mode 100644
index 000000000..72194d518
--- /dev/null
+++ b/modules/memoserv/set.cpp
@@ -0,0 +1,322 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandMSSet : public Command
+{
+ private:
+ void DoNotify(CommandSource &source, const std::vector<Anope::string> &params, MemoServ::MemoInfo *mi)
+ {
+ const Anope::string &param = params[1];
+ NickServ::Account *nc = source.nc;
+ ServiceBot *MemoServ = Config->GetClient("MemoServ");
+
+ if (!MemoServ)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ nc->SetS<bool>("MEMO_SIGNON", true);
+ nc->SetS<bool>("MEMO_RECEIVE", true);
+ source.Reply(_("\002{0}\002 will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick);
+ }
+ else if (param.equals_ci("LOGON"))
+ {
+ nc->SetS<bool>("MEMO_SIGNON", true);
+ nc->UnsetS<bool>("MEMO_RECEIVE");
+ source.Reply(_("\002{0}\002 will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick);
+ }
+ else if (param.equals_ci("NEW"))
+ {
+ nc->UnsetS<bool>("MEMO_SIGNON");
+ nc->SetS<bool>("MEMO_RECEIVE", true);
+ source.Reply(_("\002{0}\002 will now notify you of memos when they are sent to you."), MemoServ->nick);
+ }
+ else if (param.equals_ci("MAIL"))
+ {
+ if (!nc->GetEmail().empty())
+ {
+ nc->SetS<bool>("MEMO_MAIL", true);
+ source.Reply(_("You will now be informed about new memos via email."));
+ }
+ else
+ source.Reply(_("There's no email address set for your nick."));
+ }
+ else if (param.equals_ci("NOMAIL"))
+ {
+ nc->UnsetS<bool>("MEMO_MAIL");
+ source.Reply(_("You will no longer be informed via email."));
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ nc->UnsetS<bool>("MEMO_SIGNON");
+ nc->UnsetS<bool>("MEMO_RECEIVE");
+ nc->UnsetS<bool>("MEMO_MAIL");
+ source.Reply(_("\002{0}\002 will not send you any notification of memos."), MemoServ->nick);
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ void DoLimit(CommandSource &source, const std::vector<Anope::string> &params, MemoServ::MemoInfo *mi)
+ {
+
+ Anope::string p1 = params[1];
+ Anope::string p2 = params.size() > 2 ? params[2] : "";
+ Anope::string p3 = params.size() > 3 ? params[3] : "";
+ Anope::string user, chan;
+ int16_t limit;
+ NickServ::Account *nc = source.nc;
+ ChanServ::Channel *ci = NULL;
+ bool is_servadmin = source.HasPriv("memoserv/set-limit");
+
+ if (p1[0] == '#')
+ {
+ chan = p1;
+ p1 = p2;
+ p2 = p3;
+ p3 = params.size() > 4 ? params[4] : "";
+
+ ci = ChanServ::Find(chan);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
+ return;
+ }
+
+ if (!is_servadmin && !source.AccessFor(ci).HasPriv("MEMO"))
+ {
+ source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
+ return;
+ }
+ mi = ci->GetMemos();
+ }
+ if (is_servadmin)
+ {
+ if (!p2.empty() && !p2.equals_ci("HARD") && chan.empty())
+ {
+ NickServ::Nick *na;
+ if (!(na = NickServ::FindNick(p1)))
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), p1);
+ return;
+ }
+ user = p1;
+ mi = na->GetAccount()->GetMemos();
+ nc = na->GetAccount();
+ p1 = p2;
+ p2 = p3;
+ }
+ else if (p1.empty() || (!p1.is_pos_number_only() && !p1.equals_ci("NONE")) || (!p2.empty() && !p2.equals_ci("HARD")))
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+ if (!chan.empty())
+ {
+ if (!p2.empty())
+ ci->SetS<bool>("MEMO_HARDMAX", true);
+ else
+ ci->UnsetS<bool>("MEMO_HARDMAX");
+ }
+ else
+ {
+ if (!p2.empty())
+ nc->SetS<bool>("MEMO_HARDMAX", true);
+ else
+ nc->UnsetS<bool>("MEMO_HARDMAX");
+ }
+ limit = -1;
+ try
+ {
+ limit = convertTo<int16_t>(p1);
+ }
+ catch (const ConvertException &) { }
+ }
+ else
+ {
+ if (p1.empty() || !p2.empty() || !isdigit(p1[0]))
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+ if (!chan.empty() && ci->HasFieldS("MEMO_HARDMAX"))
+ {
+ source.Reply(_("The memo limit for \002{0}\002 may not be changed."), chan);
+ return;
+ }
+ if (chan.empty() && nc->HasFieldS("MEMO_HARDMAX"))
+ {
+ source.Reply(_("You are not permitted to change your memo limit."));
+ return;
+ }
+ int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
+ limit = -1;
+ try
+ {
+ limit = convertTo<int16_t>(p1);
+ }
+ catch (const ConvertException &) { }
+ /* The first character is a digit, but we could still go negative
+ * from overflow... watch out! */
+ if (limit < 0 || (max_memos > 0 && limit > max_memos))
+ {
+ if (!chan.empty())
+ source.Reply(_("You cannot set the memo limit for \002{0}\002 higher than \002{1}\002."), chan, max_memos);
+ else
+ source.Reply(_("You cannot set your memo limit higher than \002{0}\002."), max_memos);
+ return;
+ }
+ }
+ mi->SetMemoMax(limit);
+ if (limit > 0)
+ {
+ if (chan.empty() && nc == source.nc)
+ source.Reply(_("Your memo limit has been set to \002{0}\002."), limit);
+ else
+ source.Reply(_("Memo limit for \002{0}\002 set to \002{1}\002."), !chan.empty() ? chan : user, limit);
+ }
+ else if (!limit)
+ {
+ if (chan.empty() && nc == source.nc)
+ source.Reply(_("You will no longer be able to receive memos."));
+ else
+ source.Reply(_("Memo limit for \002{0}\002 set to \0020\002."), !chan.empty() ? chan : user);
+ }
+ else
+ {
+ if (chan.empty() && nc == source.nc)
+ source.Reply(_("Your memo limit has been disabled."));
+ else
+ source.Reply(_("Memo limit \002disabled\002 for \002{0}\002."), !chan.empty() ? chan : user);
+ }
+ }
+ public:
+ CommandMSSet(Module *creator) : Command(creator, "memoserv/set", 2, 5)
+ {
+ this->SetDesc(_("Set options related to memos"));
+ this->SetSyntax(_("\037option\037 \037parameters\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+ MemoServ::MemoInfo *mi = source.nc->GetMemos();
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Sorry, memo option setting is temporarily disabled."));
+ else if (cmd.equals_ci("NOTIFY"))
+ return this->DoNotify(source, params, mi);
+ else if (cmd.equals_ci("LIMIT"))
+ return this->DoLimit(source, params, mi);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.empty())
+ {
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (!help)
+ return false;
+ source.Reply(_("Sets various memo options. \037option\037 can be one of:\n"
+ "\n"
+ " NOTIFY Changes when you will be notified about\n"
+ " new memos (only for nicknames)\n"
+ " LIMIT Sets the maximum number of memos you can\n"
+ " receive\n"
+ "\n"
+ "Type \002{0}{1} {2} {3} \037option\037\002 for more information on a specific option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, source.command);
+ }
+ else if (subcommand.equals_ci("NOTIFY"))
+ source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
+ "\n"
+ "Changes when you will be notified about new memos:\n"
+ "\n"
+ " ON You will be notified of memos when you log on,\n"
+ " when you unset /AWAY, and when they are sent\n"
+ " to you.\n"
+ "\n"
+ " LOGON You will only be notified of memos when you log\n"
+ " on or when you unset /AWAY.\n"
+ "\n"
+ " NEW You will only be notified of memos when they\n"
+ " are sent to you.\n"
+ "\n"
+ " MAIL You will be notified of memos by email as well as\n"
+ " any other settings you have.\n"
+ "\n"
+ " NOMAIL You will not be notified of memos by email.\n"
+ "\n"
+ " OFF You will not receive any notification of memos.\n"
+ "\n"
+ "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
+ else if (subcommand.equals_ci("LIMIT"))
+ {
+ int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
+ if (source.IsServicesOper())
+ source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
+ "\n"
+ "Sets the maximum number of memos a user or channel is allowed to have."
+ " Setting the limit to 0 prevents the user from receiving any memos; setting it to \002NONE\002 allows the user to receive and keep as many memos as they want."
+ " If you do not give a nickname or channel, your own limit is set.\n"
+ "\n"
+ "Adding \002HARD\002 prevents the user from changing the limit."
+ " Not adding \002HARD\002 has the opposite effect, allowing the user to change the limit, even if a previous limit was set.\n"
+ " \n"
+ "This use of the \002{0} LIMIT\002 command is limited to \002Services Operators\002."
+ " Other users may only enter a limit for themselves or a channel on which they have the \002MEMO\002 privilege on, may not remove their limit, may not set a limit above {1}, and may not set a hard limit."),
+ source.command, max_memos);
+ else
+ source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
+ "\n"
+ "Sets the maximum number of memos you, or the given channel, are allowed to have."
+ " If you set this to 0, no one will be able to send any memos to you."
+ "However, you cannot set this any higher than {0}."), max_memos);
+ }
+ else
+ return false;
+
+ return true;
+ }
+};
+
+class MSSet : public Module
+{
+ CommandMSSet commandmsset;
+ Serialize::Field<NickServ::Account, bool> memo_signon, memo_receive, memo_mail, memo_hardmax_nick;
+ Serialize::Field<ChanServ::Channel, bool> memo_hardmax_channel;
+
+ public:
+ MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsset(this)
+ , memo_signon(this, "MEMO_SIGNON")
+ , memo_receive(this, "MEMO_RECEIVE")
+ , memo_mail(this, "MEMO_MAIL")
+ , memo_hardmax_nick(this, "MEMO_HARDMAX")
+ , memo_hardmax_channel(this, "MEMO_HARDMAX")
+ {
+
+ }
+};
+
+MODULE_INIT(MSSet)
diff --git a/modules/memoserv/staff.cpp b/modules/memoserv/staff.cpp
new file mode 100644
index 000000000..45883bbb6
--- /dev/null
+++ b/modules/memoserv/staff.cpp
@@ -0,0 +1,65 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/memoserv.h"
+
+class CommandMSStaff : public Command
+{
+ public:
+ CommandMSStaff(Module *creator) : Command(creator, "memoserv/staff", 1, 1)
+ {
+ this->SetDesc(_("Send a memo to all opers/admins"));
+ this->SetSyntax(_("\037memo-text\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!MemoServ::service)
+ return;
+
+ const Anope::string &text = params[0];
+
+ for (NickServ::Account *nc : NickServ::service->GetAccountList())
+ if (source.nc != nc && nc->IsServicesOper())
+ MemoServ::service->Send(source.GetNick(), nc->GetDisplay(), text, true);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sends all services staff a memo containing \037memo-text\037."));
+
+ return true;
+ }
+};
+
+class MSStaff : public Module
+{
+ CommandMSStaff commandmsstaff;
+
+ public:
+ MSStaff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandmsstaff(this)
+ {
+ if (!MemoServ::service)
+ throw ModuleException("No MemoServ!");
+ }
+};
+
+MODULE_INIT(MSStaff)
diff --git a/modules/nickserv/CMakeLists.txt b/modules/nickserv/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/nickserv/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/nickserv/access.cpp b/modules/nickserv/access.cpp
new file mode 100644
index 000000000..bff710cc4
--- /dev/null
+++ b/modules/nickserv/access.cpp
@@ -0,0 +1,272 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv.h"
+#include "modules/nickserv/access.h"
+
+class NickAccessImpl : public NickAccess
+{
+ friend class NickAccessType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string mask;
+
+ public:
+ NickAccessImpl(Serialize::TypeBase *type) : NickAccess(type) { }
+ NickAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : NickAccess(type, id) { }
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+};
+
+class NickAccessType : public Serialize::Type<NickAccessImpl>
+{
+ public:
+ Serialize::ObjectField<NickAccessImpl, NickServ::Account *> account;
+ Serialize::Field<NickAccessImpl, Anope::string> mask;
+
+ NickAccessType(Module *creator) : Serialize::Type<NickAccessImpl>(creator)
+ , account(this, "account", &NickAccessImpl::account, true)
+ , mask(this, "mask", &NickAccessImpl::mask)
+ {
+ }
+};
+
+NickServ::Account *NickAccessImpl::GetAccount()
+{
+ return Get(&NickAccessType::account);
+}
+
+void NickAccessImpl::SetAccount(NickServ::Account *acc)
+{
+ Set(&NickAccessType::account, acc);
+}
+
+Anope::string NickAccessImpl::GetMask()
+{
+ return Get(&NickAccessType::mask);
+}
+
+void NickAccessImpl::SetMask(const Anope::string &m)
+{
+ Set(&NickAccessType::mask, m);
+}
+
+class CommandNSAccess : public Command
+{
+ private:
+ void DoAdd(CommandSource &source, NickServ::Account *nc, const Anope::string &mask)
+ {
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ std::vector<NickAccess *> access = nc->GetRefs<NickAccess *>();
+
+ if (access.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("accessmax", "32"))
+ {
+ source.Reply(_("Sorry, the maximum of \002{0}\002 access entries has been reached."), Config->GetModule(this->GetOwner())->Get<unsigned>("accessmax"));
+ return;
+ }
+
+ for (NickAccess *a : access)
+ if (a->GetMask().equals_ci(mask))
+ {
+ source.Reply(_("Mask \002{0}\002 already present on the access list of \002{1}\002."), mask, nc->GetDisplay());
+ return;
+ }
+
+ NickAccess *a = Serialize::New<NickAccess *>();
+ a->SetAccount(nc);
+ a->SetMask(mask);
+
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 added to the access list of \002{1}\002."), mask, nc->GetDisplay());
+ }
+
+ void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &mask)
+ {
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ for (NickAccess *a : nc->GetRefs<NickAccess *>())
+ if (a->GetMask().equals_ci(mask))
+ {
+ a->Delete();
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), mask, nc->GetDisplay());
+ return;
+ }
+
+
+ source.Reply(_("\002{0}\002 not found on the access list of \002{1}\002."), mask, nc->GetDisplay());
+ }
+
+ void DoList(CommandSource &source, NickServ::Account *nc, const Anope::string &mask)
+ {
+ std::vector<NickAccess *> access = nc->GetRefs<NickAccess *>();
+ if (access.empty())
+ {
+ source.Reply(_("The access list of \002{0}\002 is empty."), nc->GetDisplay());
+ return;
+ }
+
+ source.Reply(_("Access list for \002{0}\002:"), nc->GetDisplay());
+ for (NickAccess *a : access)
+ {
+ if (!mask.empty() && !Anope::Match(a->GetMask(), mask))
+ continue;
+
+ source.Reply(" {0}", a->GetMask());
+ }
+ }
+ public:
+ CommandNSAccess(Module *creator) : Command(creator, "nickserv/access", 1, 3)
+ {
+ this->SetDesc(_("Modify the list of authorized addresses"));
+ this->SetSyntax(_("ADD [\037nickname\037] \037mask\037"));
+ this->SetSyntax(_("DEL [\037nickname\037] \037mask\037"));
+ this->SetSyntax(_("LIST [\037nickname\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+ Anope::string nick, mask;
+
+ if (cmd.equals_ci("LIST"))
+ nick = params.size() > 1 ? params[1] : "";
+ else
+ {
+ nick = params.size() == 3 ? params[1] : "";
+ mask = params.size() > 1 ? params[params.size() - 1] : "";
+ }
+
+ NickServ::Account *nc;
+ if (!nick.empty() && source.HasPriv("nickserv/access"))
+ {
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->IsServicesOper() && !cmd.equals_ci("LIST"))
+ {
+ source.Reply(_("You may view but not modify the access list of other Services Operators."));
+ return;
+ }
+
+ nc = na->GetAccount();
+ }
+ else
+ nc = source.nc;
+
+ if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos))
+ {
+ source.Reply(_("Mask must be in the form \037user\037@\037host\037."));
+ source.Reply(_("\002%s%s HELP %s\002 for more information."), Config->StrictPrivmsg, source.service->nick, source.command); // XXX
+ }
+ else if (cmd.equals_ci("LIST"))
+ return this->DoList(source, nc, mask);
+ else if (nc->HasFieldS("NS_SUSPENDED"))
+ source.Reply(_("\002{0}\002 is suspended."), nc->GetDisplay());
+ else if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, nc, mask);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, nc, mask);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Modifies or displays the access list for your account."
+ " The access list is a list of addresses that {1} uses to recognize you."
+ " If you match one of the hosts on the access list, services will not force you to change your nickname if the \002KILL\002 option is set."
+ " Furthermore, if the \002SECURE\002 option is disabled, services will recognize you just based on your hostmask, without having to supply a password."
+ " To gain access to channels when only recognized by your hostmask, the channel must too have the \002SECURE\002 option off."
+ " Services Operators may provide \037nickname\037 to modify other user's access lists.\n"
+ "\n"
+ "Examples:\n"
+ " \n"
+ " {command} ADD anyone@*.bepeg.com\n"
+ " Allows access to user \"anyone\" from any machine in the \"bepeg.com\" domain.\n"
+ "\n"
+ " {command} DEL anyone@*.bepeg.com\n"
+ " Reverses the previous command.\n"
+ "\n"
+ " {command} LIST\n"
+ " Displays the current access list."),
+ source.command, source.service->nick);
+ return true;
+ }
+};
+
+class NSAccess : public Module
+ , public EventHook<NickServ::Event::NickRegister>
+{
+ CommandNSAccess commandnsaccess;
+ NickAccessType nick_type;
+
+ public:
+ NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<NickServ::Event::NickRegister>(this)
+ , commandnsaccess(this)
+ , nick_type(this)
+ {
+ }
+
+ void OnNickRegister(User *u, NickServ::Nick *na, const Anope::string &) override
+ {
+ if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
+ {
+ NickAccess *a = Serialize::New<NickAccess *>();
+ a->SetAccount(na->GetAccount());
+ a->SetMask(u->Mask());
+
+ u->SendMessage(Config->GetClient("NickServ"),
+ _("\002{0}\002 has been registered under your hostmask: \002{1}\002"), na->GetNick(), a->GetMask());
+ }
+ }
+};
+
+MODULE_INIT(NSAccess)
diff --git a/modules/nickserv/ajoin.cpp b/modules/nickserv/ajoin.cpp
new file mode 100644
index 000000000..98d93e8fe
--- /dev/null
+++ b/modules/nickserv/ajoin.cpp
@@ -0,0 +1,396 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/nickserv/ajoin.h"
+
+class AutoJoinImpl : public AutoJoin
+{
+ friend class AutoJoinType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string channel, key;
+
+ public:
+ AutoJoinImpl(Serialize::TypeBase *type) : AutoJoin(type) { }
+ AutoJoinImpl(Serialize::TypeBase *type, Serialize::ID id) : AutoJoin(type, id) { }
+
+ NickServ::Account *GetOwner() override;
+ void SetOwner(NickServ::Account *acc) override;
+
+ Anope::string GetChannel() override;
+ void SetChannel(const Anope::string &c) override;
+
+ Anope::string GetKey() override;
+ void SetKey(const Anope::string &k) override;
+};
+
+class AutoJoinType : public Serialize::Type<AutoJoinImpl>
+{
+ public:
+ Serialize::ObjectField<AutoJoinImpl, NickServ::Account *> owner;
+ Serialize::Field<AutoJoinImpl, Anope::string> channel, key;
+
+ AutoJoinType(Module *me) : Serialize::Type<AutoJoinImpl>(me)
+ , owner(this, "owner", &AutoJoinImpl::account, true)
+ , channel(this, "channel", &AutoJoinImpl::channel)
+ , key(this, "key", &AutoJoinImpl::key)
+ {
+ }
+};
+
+NickServ::Account *AutoJoinImpl::GetOwner()
+{
+ return Get(&AutoJoinType::owner);
+}
+
+void AutoJoinImpl::SetOwner(NickServ::Account *acc)
+{
+ Set(&AutoJoinType::owner, acc);
+}
+
+Anope::string AutoJoinImpl::GetChannel()
+{
+ return Get(&AutoJoinType::channel);
+}
+
+void AutoJoinImpl::SetChannel(const Anope::string &c)
+{
+ Set(&AutoJoinType::channel, c);
+}
+
+Anope::string AutoJoinImpl::GetKey()
+{
+ return Get(&AutoJoinType::key);
+}
+
+void AutoJoinImpl::SetKey(const Anope::string &k)
+{
+ Set(&AutoJoinType::key, k);
+}
+
+class CommandNSAJoin : public Command
+{
+ void DoList(CommandSource &source, NickServ::Account *nc)
+ {
+ std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();
+
+ if (channels.empty())
+ {
+ source.Reply(_("The auto join list of \002{0}\002 is empty."), nc->GetDisplay());
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Key"));
+ for (unsigned i = 0; i < channels.size(); ++i)
+ {
+ AutoJoin *aj = channels[i];
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Channel"] = aj->GetChannel();
+ entry["Key"] = aj->GetKey();
+ list.AddEntry(entry);
+ }
+
+ source.Reply(_("Auto join list of \002{0}\002:"), nc->GetDisplay());
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ void DoAdd(CommandSource &source, NickServ::Account *nc, const Anope::string &chans, const Anope::string &keys)
+ {
+ std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();
+
+ Anope::string addedchans;
+ Anope::string alreadyadded;
+ Anope::string invalidkey;
+ commasepstream ksep(keys, true);
+ commasepstream csep(chans);
+ for (Anope::string chan, key; csep.GetToken(chan);)
+ {
+ ksep.GetToken(key);
+
+ unsigned i = 0;
+ for (; i < channels.size(); ++i)
+ if (channels[i]->GetChannel().equals_ci(chan))
+ break;
+
+ if (channels.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax"))
+ {
+ source.Reply(_("Sorry, the maximum of \002{0}\002 auto join entries has been reached."), Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax"));
+ return;
+ }
+
+ if (i != channels.size())
+ alreadyadded += chan + ", ";
+ else if (IRCD->IsChannelValid(chan) == false)
+ source.Reply(_("\002{0}\002 isn't a valid channel."), chan);
+ else
+ {
+ Channel *c = Channel::Find(chan);
+ Anope::string k;
+ if (c && c->GetParam("KEY", k) && key != k)
+ {
+ invalidkey += chan + ", ";
+ continue;
+ }
+
+ AutoJoin *entry = Serialize::New<AutoJoin *>();
+ entry->SetOwner(nc);
+ entry->SetChannel(chan);
+ entry->SetKey(key);
+
+ addedchans += chan + ", ";
+ }
+ }
+
+ if (!alreadyadded.empty())
+ {
+ alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2);
+ source.Reply(_("\002{0}\002 is already on the auto join list of \002{1}\002."), alreadyadded, nc->GetDisplay());
+ }
+
+ if (!invalidkey.empty())
+ {
+ invalidkey = invalidkey.substr(0, invalidkey.length() - 2);
+ source.Reply(_("\002{0}\002 had an invalid key specified, and was ignored."), invalidkey);
+ }
+
+ if (addedchans.empty())
+ return;
+
+ addedchans = addedchans.substr(0, addedchans.length() - 2);
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 added to the auto join list of \002{1}\002."), addedchans, nc->GetDisplay());
+ }
+
+ void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &chans)
+ {
+ std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();
+ Anope::string delchans;
+ Anope::string notfoundchans;
+ commasepstream sep(chans);
+
+ for (Anope::string chan; sep.GetToken(chan);)
+ {
+ unsigned i = 0;
+ for (; i < channels.size(); ++i)
+ if (channels[i]->GetChannel().equals_ci(chan))
+ break;
+
+ if (i == channels.size())
+ notfoundchans += chan + ", ";
+ else
+ {
+ delete channels[i];
+ delchans += chan + ", ";
+ }
+ }
+
+ if (!notfoundchans.empty())
+ {
+ notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2);
+ source.Reply(_("\002{0}\002 was not found on the auto join list of \002{1}\002."), notfoundchans, nc->GetDisplay());
+ }
+
+ if (delchans.empty())
+ return;
+
+ delchans = delchans.substr(0, delchans.length() - 2);
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 was removed from the auto join list of \002{1}\002."), delchans, nc->GetDisplay());
+ }
+
+ public:
+ CommandNSAJoin(Module *creator) : Command(creator, "nickserv/ajoin", 1, 4)
+ {
+ this->SetDesc(_("Manage your auto join list"));
+ this->SetSyntax(_("ADD [\037nickname\037] \037channel\037 [\037key\037]"));
+ this->SetSyntax(_("DEL [\037nickname\037] \037channel\037"));
+ this->SetSyntax(_("LIST [\037nickname\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+ Anope::string nick, param, param2;
+
+ if (cmd.equals_ci("LIST"))
+ nick = params.size() > 1 ? params[1] : "";
+ else
+ nick = (params.size() > 2 && IRCD->IsChannelValid(params[2])) ? params[1] : "";
+
+ NickServ::Account *nc;
+ if (!nick.empty() && !source.HasCommand("nickserv/ajoin"))
+ {
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ nc = na->GetAccount();
+ param = params.size() > 2 ? params[2] : "";
+ param2 = params.size() > 3 ? params[3] : "";
+ }
+ else
+ {
+ nc = source.nc;
+ param = params.size() > 1 ? params[1] : "";
+ param2 = params.size() > 2 ? params[2] : "";
+ }
+
+ if (cmd.equals_ci("LIST"))
+ return this->DoList(source, nc);
+ else if (nc->HasFieldS("NS_SUSPENDED"))
+ source.Reply(_("\002{0}\002 isn't registered."), nc->GetDisplay());
+ else if (param.empty())
+ this->OnSyntaxError(source, "");
+ else if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode."));
+ else if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, nc, param, param2);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, nc, param);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command manages your auto join list."
+ " When you identify you will automatically join the channels on your auto join list."
+ " Services Operators may provide \037nickname\037 to modify other users' auto join lists."));
+ return true;
+ }
+};
+
+class NSAJoin : public Module
+ , public EventHook<Event::UserLogin>
+{
+ CommandNSAJoin commandnsajoin;
+ AutoJoinType ajtype;
+
+ public:
+ NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserLogin>(this)
+ , commandnsajoin(this)
+ , ajtype(this)
+ {
+
+ if (!IRCD || !IRCD->CanSVSJoin)
+ throw ModuleException("Your IRCd does not support SVSJOIN");
+
+ }
+
+ void OnUserLogin(User *u) override
+ {
+ ServiceBot *NickServ = Config->GetClient("NickServ");
+ if (!NickServ)
+ return;
+
+ std::vector<AutoJoin *> channels = u->Account()->GetRefs<AutoJoin *>();
+ if (channels.empty())
+ return;
+
+ /* Set +r now, so we can ajoin users into +R channels */
+ ModeManager::ProcessModes();
+
+ for (AutoJoin *entry : channels)
+ {
+ Channel *c = Channel::Find(entry->GetChannel());
+ ChanServ::Channel *ci;
+
+ if (c)
+ ci = c->ci;
+ else
+ ci = ChanServ::Find(entry->GetChannel());
+
+ bool need_invite = false;
+ Anope::string key = entry->GetKey();
+ ChanServ::AccessGroup u_access;
+
+ if (ci != NULL)
+ {
+ if (ci->HasFieldS("CS_SUSPENDED"))
+ continue;
+ u_access = ci->AccessFor(u);
+ }
+ if (c != NULL)
+ {
+ if (c->FindUser(u) != NULL)
+ continue;
+ else if (c->HasMode("OPERONLY") && !u->HasMode("OPER"))
+ continue;
+ else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN"))
+ continue;
+ else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExtOK("ssl")))
+ continue;
+ else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false)
+ need_invite = true;
+ else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false)
+ need_invite = true;
+
+ if (c->HasMode("KEY"))
+ {
+ Anope::string k;
+ if (c->GetParam("KEY", k))
+ {
+ if (u_access.HasPriv("GETKEY"))
+ key = k;
+ else if (key != k)
+ need_invite = true;
+ }
+ }
+ if (c->HasMode("LIMIT"))
+ {
+ Anope::string l;
+ if (c->GetParam("LIMIT", l))
+ {
+ try
+ {
+ unsigned limit = convertTo<unsigned>(l);
+ if (c->users.size() >= limit)
+ need_invite = true;
+ }
+ catch (const ConvertException &) { }
+ }
+ }
+ }
+
+ if (need_invite && c != NULL)
+ {
+ if (!u_access.HasPriv("INVITE"))
+ continue;
+ IRCD->SendInvite(NickServ, c, u);
+ }
+
+ IRCD->SendSVSJoin(NickServ, u, entry->GetChannel(), key);
+ }
+ }
+};
+
+MODULE_INIT(NSAJoin)
diff --git a/modules/nickserv/alist.cpp b/modules/nickserv/alist.cpp
new file mode 100644
index 000000000..3c8b573b0
--- /dev/null
+++ b/modules/nickserv/alist.cpp
@@ -0,0 +1,142 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+
+class CommandNSAList : public Command
+{
+ static bool ChannelSort(ChanServ::Channel *ci1, ChanServ::Channel *ci2)
+ {
+ return ci::less()(ci1->GetName(), ci2->GetName());
+ }
+
+ public:
+ CommandNSAList(Module *creator) : Command(creator, "nickserv/alist", 0, 2)
+ {
+ this->SetDesc(_("List channels you have access on"));
+ this->SetSyntax(_("[\037nickname\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ Anope::string nick = source.GetNick();
+ NickServ::Account *nc = source.nc;
+
+ if (params.size() && source.HasPriv("nickserv/alist"))
+ {
+ nick = params[0];
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+ nc = na->GetAccount();
+ }
+
+ ListFormatter list(source.GetAccount());
+ int chan_count = 0;
+
+ list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Access")).AddColumn(_("Description"));
+
+ std::vector<ChanServ::Channel *> chans = nc->GetRefs<ChanServ::Channel *>();
+ std::sort(chans.begin(), chans.end(), ChannelSort);
+ for (ChanServ::Channel *ci : chans)
+ {
+ ListFormatter::ListEntry entry;
+
+ if (ci->GetFounder() == nc)
+ {
+ ++chan_count;
+ entry["Number"] = stringify(chan_count);
+ entry["Channel"] = (ci->HasFieldS("CS_NO_EXPIRE") ? "!" : "") + ci->GetName();
+ entry["Access"] = Language::Translate(source.GetAccount(), _("Founder"));
+ entry["Description"] = ci->GetDesc();
+ list.AddEntry(entry);
+ continue;
+ }
+
+ if (ci->GetSuccessor() == nc)
+ {
+ ++chan_count;
+ entry["Number"] = stringify(chan_count);
+ entry["Channel"] = (ci->HasFieldS("CS_NO_EXPIRE") ? "!" : "") + ci->GetName();
+ entry["Access"] = Language::Translate(source.GetAccount(), _("Successor"));
+ entry["Description"] = ci->GetDesc();
+ list.AddEntry(entry);
+ continue;
+ }
+
+ ChanServ::AccessGroup access = ci->AccessFor(nc, false);
+ if (access.empty())
+ continue;
+
+ ++chan_count;
+
+ entry["Number"] = stringify(chan_count);
+ entry["Channel"] = (ci->HasFieldS("CS_NO_EXPIRE") ? "!" : "") + ci->GetName();
+ for (unsigned j = 0; j < access.size(); ++j)
+ entry["Access"] = entry["Access"] + ", " + access[j]->AccessSerialize();
+ entry["Access"] = entry["Access"].substr(2);
+ entry["Description"] = ci->GetDesc();
+ list.AddEntry(entry);
+ }
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ if (!chan_count)
+ {
+ source.Reply(_("\002{0}\002 has no access in any channels."), nc->GetDisplay());
+ }
+ else
+ {
+ source.Reply(_("Channels that \002{0}\002 has access on:"), nc->GetDisplay());
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of list - \002{0}\002 channels shown."), chan_count);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Lists all channels you have access on.\n"
+ " \n"
+ "Channels that have the \037NOEXPIRE\037 option set will be prefixed by an exclamation mark. The nickname parameter is limited to Services Operators"));
+
+ return true;
+ }
+};
+
+class NSAList : public Module
+{
+ CommandNSAList commandnsalist;
+
+ public:
+ NSAList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsalist(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSAList)
diff --git a/modules/nickserv/cert.cpp b/modules/nickserv/cert.cpp
new file mode 100644
index 000000000..c7bd2a207
--- /dev/null
+++ b/modules/nickserv/cert.cpp
@@ -0,0 +1,391 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/nickserv/cert.h"
+#include "modules/nickserv.h"
+
+static Anope::hash_map<NickServ::Account *> certmap;
+
+class CertServiceImpl : public CertService
+{
+ public:
+ CertServiceImpl(Module *o) : CertService(o) { }
+
+ NickServ::Account* FindAccountFromCert(const Anope::string &cert) override
+ {
+ Anope::hash_map<NickServ::Account *>::iterator it = certmap.find(cert);
+ if (it != certmap.end())
+ return it->second;
+ return NULL;
+ }
+
+ bool Matches(User *u, NickServ::Account *nc) override
+ {
+ std::vector<NSCertEntry *> cl = nc->GetRefs<NSCertEntry *>();
+ return !u->fingerprint.empty() && FindCert(cl, u->fingerprint);
+ }
+
+ NSCertEntry *FindCert(const std::vector<NSCertEntry *> &cl, const Anope::string &certfp) override
+ {
+ for (NSCertEntry *e : cl)
+ if (e->GetCert() == certfp)
+ return e;
+ return nullptr;
+ }
+};
+
+class NSCertEntryImpl : public NSCertEntry
+{
+ friend class NSCertEntryType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string cert;
+
+ public:
+ NSCertEntryImpl(Serialize::TypeBase *type) : NSCertEntry(type) { }
+ NSCertEntryImpl(Serialize::TypeBase *type, Serialize::ID id) : NSCertEntry(type, id) { }
+ ~NSCertEntryImpl();
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ Anope::string GetCert() override;
+ void SetCert(const Anope::string &) override;
+};
+
+class NSCertEntryType : public Serialize::Type<NSCertEntryImpl>
+{
+ public:
+ struct Account : Serialize::ObjectField<NSCertEntryImpl, NickServ::Account *>
+ {
+ using Serialize::ObjectField<NSCertEntryImpl, NickServ::Account *>::ObjectField;
+
+ void SetField(NSCertEntryImpl *s, NickServ::Account *acc) override
+ {
+ const Anope::string &cert = s->GetCert();
+ if (!cert.empty())
+ certmap.erase(cert);
+
+ Serialize::ObjectField<NSCertEntryImpl, NickServ::Account *>::SetField(s, acc);
+
+ if (!cert.empty() && s->GetAccount())
+ certmap[cert] = acc;
+ }
+ } nc;
+
+ struct Mask : Serialize::Field<NSCertEntryImpl, Anope::string>
+ {
+ using Serialize::Field<NSCertEntryImpl, Anope::string>::Field;
+
+ void SetField(NSCertEntryImpl *s, const Anope::string &m) override
+ {
+ const Anope::string &old = GetField(s);
+ if (!old.empty())
+ certmap.erase(old);
+
+ Serialize::Field<NSCertEntryImpl, Anope::string>::SetField(s, m);
+
+ if (!m.empty() && s->GetAccount())
+ certmap[m] = s->GetAccount();
+ }
+ } mask;
+
+ NSCertEntryType(Module *me) : Serialize::Type<NSCertEntryImpl>(me)
+ , nc(this, "nc", &NSCertEntryImpl::account, true)
+ , mask(this, "mask", &NSCertEntryImpl::cert)
+ {
+ }
+};
+
+NSCertEntryImpl::~NSCertEntryImpl()
+{
+ const Anope::string &old = GetCert();
+ if (!old.empty())
+ certmap.erase(old);
+}
+
+NickServ::Account *NSCertEntryImpl::GetAccount()
+{
+ return Get<NickServ::Account *>(&NSCertEntryType::nc);
+}
+
+void NSCertEntryImpl::SetAccount(NickServ::Account *nc)
+{
+ Set(&NSCertEntryType::nc, nc);
+}
+
+Anope::string NSCertEntryImpl::GetCert()
+{
+ return Get<Anope::string>(&NSCertEntryType::mask);
+}
+
+void NSCertEntryImpl::SetCert(const Anope::string &mask)
+{
+ Set(&NSCertEntryType::mask, mask);
+}
+
+class CommandNSCert : public Command
+{
+ NSCertEntry *FindCert(const std::vector<NSCertEntry *> &cl, const Anope::string &certfp)
+ {
+ for (NSCertEntry *e : cl)
+ if (e->GetCert() == certfp)
+ return e;
+ return nullptr;
+ }
+
+ void DoAdd(CommandSource &source, NickServ::Account *nc, Anope::string certfp)
+ {
+ std::vector<NSCertEntry *> cl = nc->GetRefs<NSCertEntry *>();
+ unsigned max = Config->GetModule(this->GetOwner())->Get<unsigned>("max", "5");
+
+ if (cl.size() >= max)
+ {
+ source.Reply(_("Sorry, the maximum of \002{0}\002 certificate entries has been reached."), max);
+ return;
+ }
+
+ if (source.GetAccount() == nc)
+ {
+ User *u = source.GetUser();
+
+ if (!u || u->fingerprint.empty())
+ {
+ source.Reply(_("You are not using a client certificate."));
+ return;
+ }
+
+ certfp = u->fingerprint;
+ }
+
+ if (FindCert(cl, certfp))
+ {
+ source.Reply(_("Fingerprint \002{0}\002 already present on the certificate list of \002{0}\002."), certfp, nc->GetDisplay());
+ return;
+ }
+
+ if (certmap.find(certfp) != certmap.end())
+ {
+ source.Reply(_("Fingerprint \002{0}\002 is already in use."), certfp);
+ return;
+ }
+
+ NSCertEntry *e = Serialize::New<NSCertEntry *>();
+ e->SetAccount(nc);
+ e->SetCert(certfp);
+
+ // XXX fire events
+
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD certificate fingerprint " << certfp << " to " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 added to the certificate list of \002{1}\002."), certfp, nc->GetDisplay());
+ }
+
+ void DoDel(CommandSource &source, NickServ::Account *nc, Anope::string certfp)
+ {
+ std::vector<NSCertEntry *> cl = nc->GetRefs<NSCertEntry *>();
+
+ if (certfp.empty())
+ {
+ User *u = source.GetUser();
+ if (u)
+ certfp = u->fingerprint;
+ }
+
+ if (certfp.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ NSCertEntry *cert = FindCert(cl, certfp);
+ if (!cert)
+ {
+ source.Reply(_("\002{0}\002 not found on the certificate list of \002{1}\002."), certfp, nc->GetDisplay());
+ return;
+ }
+
+ cert->Delete();
+
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE certificate fingerprint " << certfp << " from " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), certfp, nc->GetDisplay());
+ }
+
+ void DoList(CommandSource &source, NickServ::Account *nc)
+ {
+ std::vector<NSCertEntry *> cl = nc->GetRefs<NSCertEntry *>();
+
+ if (cl.empty())
+ {
+ source.Reply(_("The certificate list of \002{0}\002 is empty."), nc->GetDisplay());
+ return;
+ }
+
+ source.Reply(_("Certificate list for \002{0}\002:"), nc->GetDisplay());
+ for (NSCertEntry *e : cl)
+ source.Reply(" {0}", e->GetCert());
+ }
+
+ public:
+ CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3)
+ {
+ this->SetDesc(_("Modify the nickname client certificate list"));
+ this->SetSyntax(_("ADD [\037nickname\037] [\037fingerprint\037]"));
+ this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037"));
+ this->SetSyntax(_("LIST [\037nickname\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+ Anope::string nick, certfp;
+
+ if (cmd.equals_ci("LIST"))
+ nick = params.size() > 1 ? params[1] : "";
+ else
+ {
+ nick = params.size() == 3 ? params[1] : "";
+ certfp = params.size() > 1 ? params[params.size() - 1] : "";
+ }
+
+ NickServ::Account *nc;
+ if (!nick.empty() && source.HasPriv("nickserv/access"))
+ {
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->IsServicesOper() && !cmd.equals_ci("LIST"))
+ {
+ source.Reply(_("You may view, but not modify, the certificate list of other Services Operators."));
+ return;
+ }
+
+ nc = na->GetAccount();
+ }
+ else
+ nc = source.nc;
+
+ if (cmd.equals_ci("LIST"))
+ return this->DoList(source, nc);
+ else if (nc->HasFieldS("NS_SUSPENDED"))
+ source.Reply(_("\002{0}\002 is suspended."), nc->GetDisplay());
+ else if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode."));
+ else if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, nc, certfp);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, nc, certfp);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Modifies or displays the certificate list for your account."
+ "If you connect to IRC and provide a client certificate with a matching fingerprint in the certificate list, you will be automatically identified to services."
+ " Services Operators may provide \037nickname\037 to modify other users' certificate lists.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ " {0} ADD\n"
+ " Adds your current fingerprint to the certificate list and automatically identifies you when you connect to IRC using this certificate.\n"
+ "\n"
+ " {0} DEL <fingerprint>\n"
+ " Removes \"<fingerprint>\" from your certificate list."));
+ return true;
+ }
+};
+
+class NSCert : public Module
+ , public EventHook<Event::Fingerprint>
+ , public EventHook<NickServ::Event::NickValidate>
+{
+ CommandNSCert commandnscert;
+ CertServiceImpl cs;
+
+ public:
+ NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::Fingerprint>(this)
+ , EventHook<NickServ::Event::NickValidate>(this)
+ , commandnscert(this)
+ , cs(this)
+ {
+ if (!IRCD || !IRCD->CanCertFP)
+ throw ModuleException("Your IRCd does not support ssl client certificates");
+ }
+
+ void OnFingerprint(User *u) override
+ {
+ ServiceBot *NickServ = Config->GetClient("NickServ");
+ if (!NickServ || u->IsIdentified())
+ return;
+
+ NickServ::Account *nc = cs.FindAccountFromCert(u->fingerprint);
+ if (!nc || nc->HasFieldS("NS_SUSPENDED"))
+ return;
+
+ unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
+ if (maxlogins && nc->users.size() >= maxlogins)
+ {
+ u->SendMessage(NickServ, _("Account \002{0}\002 has already reached the maximum number of simultaneous logins ({1})."), nc->GetDisplay(), maxlogins);
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (na && na->GetAccount() == nc)
+ u->Identify(na);
+ else
+ u->Login(nc);
+
+ u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified to \002%s\002."), nc->GetDisplay().c_str());
+ Log(NickServ) << u->GetMask() << " automatically identified for account " << nc->GetDisplay() << " via SSL certificate fingerprint";
+ }
+
+ EventReturn OnNickValidate(User *u, NickServ::Nick *na) override
+ {
+ if (u->fingerprint.empty())
+ return EVENT_CONTINUE;
+
+ if (cs.Matches(u, na->GetAccount()))
+ {
+ ServiceBot *NickServ = Config->GetClient("NickServ");
+
+ unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
+ if (maxlogins && na->GetAccount()->users.size() >= maxlogins)
+ {
+ u->SendMessage(NickServ, _("Account \002{0}\002 has already reached the maximum number of simultaneous logins ({1})."), na->GetAccount()->GetDisplay(), maxlogins);
+ return EVENT_CONTINUE;
+ }
+
+ u->Identify(na);
+ u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified."));
+ Log(NickServ) << u->GetMask() << " automatically identified for account " << na->GetAccount()->GetDisplay() << " via SSL certificate fingerprint";
+ return EVENT_ALLOW;
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(NSCert)
diff --git a/modules/nickserv/drop.cpp b/modules/nickserv/drop.cpp
new file mode 100644
index 000000000..22d3b59fb
--- /dev/null
+++ b/modules/nickserv/drop.cpp
@@ -0,0 +1,96 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/nickserv/drop.h"
+
+class CommandNSDrop : public Command
+{
+ public:
+ CommandNSDrop(Module *creator) : Command(creator, "nickserv/drop", 1, 1)
+ {
+ this->SetSyntax(_("\037nickname\037"));
+ this->SetDesc(_("Cancel the registration of a nickname"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &nick = params[0];
+
+ if (Anope::ReadOnly && !source.HasPriv("nickserv/drop"))
+ {
+ source.Reply(_("Sorry, nickname de-registration is temporarily disabled."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ bool is_mine = source.GetAccount() == na->GetAccount();
+
+ if (!is_mine && !source.HasPriv("nickserv/drop"))
+ {
+ source.Reply(_("Access denied. You do not have the correct operator privileges to drop other user's nicknames."));
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->GetAccount()->IsServicesOper())
+ {
+ source.Reply(_("You may not drop other Services Operators' nicknames."));
+ return;
+ }
+
+ EventManager::Get()->Dispatch(&Event::NickDrop::OnNickDrop, source, na);
+
+ Log(!is_mine ? LOG_ADMIN : LOG_COMMAND, source, this) << "to drop nickname " << na->GetNick() << " (group: " << na->GetAccount()->GetDisplay() << ") (email: " << (!na->GetAccount()->GetEmail().empty() ? na->GetAccount()->GetEmail() : "none") << ")";
+ na->Delete();
+
+ source.Reply(_("\002{0}\002 has been dropped."), nick);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Unregisters \037nickname\037. Once your nickname is dropped you may lose all of your access and channels that you may own. Any other user will be free to register \037nickname\037."));
+ if (!source.HasPriv("nickserv/drop"))
+ source.Reply(_("You may drop any nickname within your group."));
+ else
+ source.Reply(_("As a Services Operator, you may drop any nick."));
+
+ return true;
+ }
+};
+
+class NSDrop : public Module
+{
+ CommandNSDrop commandnsdrop;
+
+ public:
+ NSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsdrop(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSDrop)
diff --git a/modules/nickserv/getemail.cpp b/modules/nickserv/getemail.cpp
new file mode 100644
index 000000000..0a996e7b0
--- /dev/null
+++ b/modules/nickserv/getemail.cpp
@@ -0,0 +1,70 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandNSGetEMail : public Command
+{
+ public:
+ CommandNSGetEMail(Module *creator) : Command(creator, "nickserv/getemail", 1, 1)
+ {
+ this->SetDesc(_("Matches and returns all users that registered using given email"));
+ this->SetSyntax(_("\037email\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &email = params[0];
+ int j = 0;
+
+ Log(LOG_ADMIN, source, this) << "on " << email;
+
+ for (NickServ::Account *nc : NickServ::service->GetAccountList())
+ if (!nc->GetEmail().empty() && Anope::Match(nc->GetEmail(), email))
+ {
+ ++j;
+ source.Reply(_("Email matched: \002{0}\002 (\002{1}\002) to \002{2}\002."), nc->GetDisplay(), nc->GetEmail(), email);
+ }
+
+ if (j <= 0)
+ {
+ source.Reply(_("There are no accounts with an email that matches \002{0}\002."), email);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Returns the matching accounts whose email address is \037email\037."));
+ return true;
+ }
+};
+
+class NSGetEMail : public Module
+{
+ CommandNSGetEMail commandnsgetemail;
+
+ public:
+ NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsgetemail(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSGetEMail)
diff --git a/modules/nickserv/group.cpp b/modules/nickserv/group.cpp
new file mode 100644
index 000000000..7c0f41809
--- /dev/null
+++ b/modules/nickserv/group.cpp
@@ -0,0 +1,389 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/cert.h"
+#include "modules/nickserv/group.h"
+
+class NSGroupRequestListener : public NickServ::IdentifyRequestListener
+{
+ CommandSource source;
+ Command *cmd;
+ Anope::string nick;
+ Reference<NickServ::Nick> target;
+
+ public:
+ NSGroupRequestListener(CommandSource &src, Command *c, const Anope::string &n, NickServ::Nick *targ) : source(src), cmd(c), nick(n), target(targ) { }
+
+ void OnSuccess(NickServ::IdentifyRequest *) override
+ {
+ if (!source.GetUser() || source.GetUser()->nick != nick || !target)
+ return;
+
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ /* If the nick is already registered, drop it. */
+ if (na)
+ {
+ EventManager::Get()->Dispatch(&Event::ChangeCoreDisplay::OnChangeCoreDisplay, na->GetAccount(), u->nick);
+ delete na;
+ }
+
+ na = Serialize::New<NickServ::Nick *>();
+ na->SetNick(nick);
+ na->SetAccount(target->GetAccount());
+ na->SetLastUsermask(u->GetIdent() + "@" + u->GetDisplayedHost());
+ na->SetLastRealname(u->realname);
+ na->SetLastSeen(Anope::CurTime);
+ na->SetTimeRegistered(Anope::CurTime);
+
+ u->Login(target->GetAccount());
+ EventManager::Get()->Dispatch(&Event::NickGroup::OnNickGroup, u, target);
+
+ Log(LOG_COMMAND, source, cmd) << "to make " << nick << " join group of " << target->GetNick() << " (" << target->GetAccount()->GetDisplay() << ") (email: " << (!target->GetAccount()->GetEmail().empty() ? target->GetAccount()->GetEmail() : "none") << ")";
+ source.Reply(_("You are now in the group of \002{0}\002."), target->GetNick());
+
+ u->lastnickreg = Anope::CurTime;
+
+ }
+
+ void OnFail(NickServ::IdentifyRequest *) override
+ {
+ if (!source.GetUser())
+ return;
+
+ Log(LOG_COMMAND, source, cmd) << "and failed to group to " << target->GetNick();
+ source.Reply(_("Password incorrect."));
+ source.GetUser()->BadPassword();
+ }
+};
+
+class CommandNSGroup : public Command
+{
+ ServiceReference<CertService> certservice;
+
+ public:
+ CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 0, 2)
+ {
+ this->SetDesc(_("Join a group"));
+ this->SetSyntax(_("\037[target]\037 \037[password]\037"));
+ this->AllowUnregistered(true);
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+
+ Anope::string nick;
+ if (params.empty())
+ {
+ NickServ::Account* core = u->Account();
+ if (core)
+ nick = core->GetDisplay();
+ }
+ else
+ nick = params[0];
+
+ if (nick.empty())
+ {
+ this->SendSyntax(source);
+ return;
+ }
+
+ const Anope::string &pass = params.size() > 1 ? params[1] : "";
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, nickname grouping is temporarily disabled."));
+ return;
+ }
+
+ if (!IRCD->IsNickValid(u->nick))
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u->nick);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ {
+ if (!u->HasMode("OPER") && u->nick.find_ci(o->GetName()) != Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 may not be registered because it is too similar to an operator nick."), u->nick);
+ return;
+ }
+ }
+
+ NickServ::Nick *target, *na = NickServ::FindNick(u->nick);
+ const Anope::string &guestnick = Config->GetModule("nickserv")->Get<Anope::string>("guestnickprefix", "Guest");
+ time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
+ unsigned maxaliases = Config->GetModule(this->GetOwner())->Get<unsigned>("maxaliases");
+ if (!(target = NickServ::FindNick(nick)))
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ if (Anope::CurTime < u->lastnickreg + reg_delay)
+ {
+ source.Reply(_("Please wait \002{0}\002 seconds before using the \002{1}\002 command again."), (reg_delay + u->lastnickreg) - Anope::CurTime, source.command);
+ return;
+ }
+
+ if (target->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ {
+ Log(LOG_COMMAND, source, this) << "and tried to group to suspended nick " << target->GetNick();
+ source.Reply(_("\002{0}\002 is suspended."), target->GetNick());
+ return;
+ }
+
+ if (na && Config->GetModule(this->GetOwner())->Get<bool>("nogroupchange"))
+ {
+ source.Reply(_("Your nick is already registered."));
+ return;
+ }
+
+ if (na && target->GetAccount() == na->GetAccount())
+ {
+ source.Reply(_("You are already a member of the group of \002{0}\002."), target->GetNick());
+ return;
+ }
+
+ if (na && na->GetAccount() != u->Account())
+ {
+ source.Reply(_("\002{0}\002 is already registered."), na->GetNick());
+ return;
+ }
+
+ if (na && Config->GetModule(this->GetOwner())->Get<bool>("nogroupchange"))
+ {
+ source.Reply(_("You are already registered."));
+ return;
+ }
+
+ if (maxaliases && target->GetAccount()->GetRefs<NickServ::Nick *>().size() >= maxaliases && !target->GetAccount()->IsServicesOper())
+ {
+ source.Reply(_("There are too many nicknames in your group."));
+ return;
+ }
+
+ if (u->nick.length() <= guestnick.length() + 7 &&
+ u->nick.length() >= guestnick.length() + 1 &&
+ !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890"))
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u->nick);
+ return;
+ }
+
+ bool ok = false;
+ if (!na && u->Account() == target->GetAccount())
+ ok = true;
+
+ if (certservice && certservice->Matches(u, target->GetAccount()))
+ ok = true;
+
+ if (ok == false && !pass.empty())
+ {
+ NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new NSGroupRequestListener(source, this, u->nick, target), this->GetOwner(), target->GetAccount()->GetDisplay(), pass);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, source.GetUser(), req);
+ req->Dispatch();
+ }
+ else
+ {
+ NSGroupRequestListener req(source, this, u->nick, target);
+
+ if (ok)
+ req.OnSuccess(nullptr);
+ else
+ req.OnFail(nullptr);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command makes your nickname join the \037target\037 nickname's group."
+ " \037password\037 is the password of the target nickname.\n"
+ "\n"
+ "Nicknames in the same group share channel privileges, memos, and most settings, including password."
+ "\n"
+ "You may be able to use this command even if you have not registered your nick yet."
+ " If your nick is already registered, you'll need to identify yourself before using this command."));
+ return true;
+ }
+};
+
+class CommandNSUngroup : public Command
+{
+ public:
+ CommandNSUngroup(Module *creator) : Command(creator, "nickserv/ungroup", 0, 1)
+ {
+ this->SetDesc(_("Remove a nick from a group"));
+ this->SetSyntax(_("[\037nickname\037]"));
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+ Anope::string nick = !params.empty() ? params[0] : "";
+ NickServ::Nick *na = NickServ::FindNick(!nick.empty() ? nick : u->nick);
+
+ if (u->Account()->GetRefs<NickServ::Nick *>().size() == 1)
+ {
+ source.Reply(_("Your nickname is not grouped to anything, so you can't ungroup it."));
+ return;
+ }
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), !nick.empty() ? nick : u->nick);
+ return;
+ }
+
+ if (na->GetAccount() != u->Account())
+ {
+ source.Reply(_("\002{0}\002 is not in your group."), na->GetNick());
+ return;
+ }
+
+
+ NickServ::Account *oldcore = na->GetAccount();
+
+ if (na->GetNick().equals_ci(oldcore->GetDisplay()))
+ oldcore->SetDisplay(oldcore->GetRef<NickServ::Nick *>());
+
+ NickServ::Account *nc = Serialize::New<NickServ::Account *>();
+ nc->SetDisplay(na->GetNick());
+ na->SetAccount(nc);
+
+ nc->SetPassword(oldcore->GetPassword());
+ if (!oldcore->GetEmail().empty())
+ nc->SetEmail(oldcore->GetEmail());
+ nc->SetLanguage(oldcore->GetLanguage());
+
+ source.Reply(_("\002{0}\002 has been ungrouped from \002{1}\002."), na->GetNick(), oldcore->GetDisplay());
+
+ User *user = User::Find(na->GetNick(), true);
+ if (user)
+ /* The user on the nick who was ungrouped may be identified to the old group, set -r */
+ user->RemoveMode(source.service, "REGISTERED");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command ungroups your nickname, or if given, the specificed \037nickname\037, from the group it is in."
+ " The ungrouped nick keeps its registration time, password, email, and language. Everything else is reset."
+ " You may not ungroup yourself if there is only one nickname in your group."));
+ return true;
+ }
+};
+
+class CommandNSGList : public Command
+{
+ public:
+ CommandNSGList(Module *creator) : Command(creator, "nickserv/glist", 0, 1)
+ {
+ this->SetDesc(_("Lists all nicknames in your group"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &nick = !params.empty() ? params[0] : "";
+ NickServ::Account *nc;
+
+ if (!nick.empty() && source.IsServicesOper())
+ {
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ nc = na->GetAccount();
+ }
+ else
+ nc = source.GetAccount();
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Nick")).AddColumn(_("Expires"));
+ time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire", "21d"),
+ unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
+ for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>())
+ {
+ Anope::string expires;
+ if (na2->HasFieldS("NS_NO_EXPIRE"))
+ expires = _("Does not expire");
+ else if (!nickserv_expire || Anope::NoExpire)
+ ;
+ else if (na2->GetAccount()->HasFieldS("UNCONFIRMED") && unconfirmed_expire)
+ expires = Anope::strftime(na2->GetTimeRegistered() + unconfirmed_expire, source.GetAccount());
+ else
+ expires = Anope::strftime(na2->GetLastSeen() + nickserv_expire, source.GetAccount());
+
+ ListFormatter::ListEntry entry;
+ entry["Nick"] = na2->GetNick();
+ entry["Expires"] = expires;
+ list.AddEntry(entry);
+ }
+
+ source.Reply(nc != source.GetAccount() ? _("List of nicknames in the group of \002%s\002:") : _("List of nicknames in your group:"), nc->GetDisplay().c_str());
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("%d nickname(s) in the group."), replies.size());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (source.IsServicesOper())
+ source.Reply(_("Without a parameter, lists all nicknames that are in your group.\n"
+ "\n"
+ "With a parameter, lists all nicknames that are in the group of the given nick.\n"
+ "Specifying a nick is limited to \002Services Operators\002."),
+ source.command);
+ else
+ source.Reply(_("Lists all nicknames in your group."));
+
+ return true;
+ }
+};
+
+class NSGroup : public Module
+{
+ CommandNSGroup commandnsgroup;
+ CommandNSUngroup commandnsungroup;
+ CommandNSGList commandnsglist;
+
+ public:
+ NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsgroup(this)
+ , commandnsungroup(this)
+ , commandnsglist(this)
+ {
+ if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
+ }
+};
+
+MODULE_INIT(NSGroup)
diff --git a/modules/nickserv/identify.cpp b/modules/nickserv/identify.cpp
new file mode 100644
index 000000000..13e578b69
--- /dev/null
+++ b/modules/nickserv/identify.cpp
@@ -0,0 +1,133 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class NSIdentifyRequestListener : public NickServ::IdentifyRequestListener
+{
+ CommandSource source;
+ Command *cmd;
+
+ public:
+ NSIdentifyRequestListener(CommandSource &s, Command *c) : source(s), cmd(c) { }
+
+ void OnSuccess(NickServ::IdentifyRequest *req) override
+ {
+ if (!source.GetUser())
+ return;
+
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), req->GetAccount());
+ return;
+ }
+
+ if (u->IsIdentified())
+ Log(LOG_COMMAND, source, cmd) << "to log out of account " << u->Account()->GetDisplay();
+
+ Log(LOG_COMMAND, source, cmd) << "and identified for account " << na->GetAccount()->GetDisplay();
+ source.Reply(_("Password accepted - you are now recognized as \002{0}\002."), na->GetAccount()->GetDisplay());
+ u->Identify(na);
+ }
+
+ void OnFail(NickServ::IdentifyRequest *req) override
+ {
+ if (!source.GetUser())
+ return;
+
+ bool accountexists = NickServ::FindNick(req->GetAccount()) != NULL;
+ Log(LOG_COMMAND, source, cmd) << "and failed to identify to" << (accountexists ? " " : " nonexistent ") << "account " << req->GetAccount();
+ if (accountexists)
+ {
+ source.Reply(_("Password incorrect."));
+ source.GetUser()->BadPassword();
+ }
+ else
+ source.Reply("\002{0}\002 isn't registered.", req->GetAccount());
+ }
+};
+
+class CommandNSIdentify : public Command
+{
+ public:
+ CommandNSIdentify(Module *creator) : Command(creator, "nickserv/identify", 1, 2)
+ {
+ this->SetDesc(_("Identify yourself with your password"));
+ this->SetSyntax(_("[\037account\037] \037password\037"));
+ this->AllowUnregistered(true);
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+
+ const Anope::string &nick = params.size() == 2 ? params[0] : u->nick;
+ Anope::string pass = params[params.size() - 1];
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na && na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ {
+ source.Reply(_("\002{0}\002 is suspended."), na->GetNick());
+ return;
+ }
+
+ if (u->Account() && na && u->Account() == na->GetAccount())
+ {
+ source.Reply(_("You are already identified."));
+ return;
+ }
+
+ unsigned int maxlogins = Config->GetModule(this->GetOwner())->Get<unsigned int>("maxlogins");
+ if (na && maxlogins && na->GetAccount()->users.size() >= maxlogins)
+ {
+ source.Reply(_("Account \002{0}\002 has already reached the maximum number of simultaneous logins ({1})."), na->GetAccount()->GetDisplay(), maxlogins);
+ return;
+ }
+
+ NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new NSIdentifyRequestListener(source, this), this->GetOwner(), na ? na->GetAccount()->GetDisplay() : nick, pass);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, u, req);
+
+ req->Dispatch();
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Logs you in to account \037account\037. If no \037account\037 is given, your current nickname is used."
+ " Many commands require you to authenticate with this command before you use them. \037password\037 should be the same one you registered with."));
+ return true;
+ }
+};
+
+class NSIdentify : public Module
+{
+ CommandNSIdentify commandnsidentify;
+
+ public:
+ NSIdentify(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
+ commandnsidentify(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSIdentify)
diff --git a/modules/nickserv/info.cpp b/modules/nickserv/info.cpp
new file mode 100644
index 000000000..593cfa116
--- /dev/null
+++ b/modules/nickserv/info.cpp
@@ -0,0 +1,284 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv/set.h"
+
+class CommandNSInfo : public Command
+{
+ public:
+ CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2)
+ {
+ this->SetDesc(_("Displays information about a given nickname"));
+ this->SetSyntax(_("[\037nickname\037]"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ const Anope::string &nick = params.size() ? params[0] : (source.nc ? source.nc->GetDisplay() : source.GetNick());
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ bool has_auspex = source.HasPriv("nickserv/auspex");
+
+ if (!na)
+ {
+ if (ServiceBot::Find(nick, true))
+ source.Reply(_("\002{0}\002 is part of this Network's Services."), nick);
+ else
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ bool nick_online = false, show_hidden = false;
+
+ /* Is the real owner of the nick we're looking up online? -TheShadow */
+ User *u2 = User::Find(na->GetNick(), true);
+ if (u2 && u2->Account() == na->GetAccount())
+ {
+ nick_online = true;
+ na->SetLastSeen(Anope::CurTime);
+ }
+
+ if (has_auspex || na->GetAccount() == source.GetAccount())
+ show_hidden = true;
+
+ source.Reply(_("\002{0}\002 is \002{1}\002"), na->GetNick(), na->GetLastRealname());
+
+ if (na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ source.Reply(_("\002{0}\002 has not confirmed their account."), na->GetNick());
+
+ if (na->GetAccount()->IsServicesOper() && (show_hidden || !na->GetAccount()->HasFieldS("HIDE_STATUS")))
+ source.Reply(_("\002{0}\002 is a Services Operator of type \002{1}\002."), na->GetNick(), na->GetAccount()->o->GetType()->GetName());
+
+ InfoFormatter info(source.nc);
+
+ if (nick_online)
+ {
+ bool shown = false;
+ if (show_hidden && !na->GetLastRealhost().empty())
+ {
+ info[_("Online from")] = na->GetLastRealhost();
+ shown = true;
+ }
+ if ((show_hidden || !na->GetAccount()->HasFieldS("HIDE_MASK")) && (!shown || na->GetLastUsermask() != na->GetLastRealhost()))
+ info[_("Online from")] = na->GetLastUsermask();
+ else
+ source.Reply(_("\002{0}\002 is currently online."), na->GetNick());
+ }
+ else
+ {
+ Anope::string shown;
+ if (show_hidden || !na->GetAccount()->HasFieldS("HIDE_MASK"))
+ {
+ info[_("Last seen address")] = na->GetLastUsermask();
+ shown = na->GetLastUsermask();
+ }
+
+ if (show_hidden && !na->GetLastRealhost().empty() && na->GetLastRealhost() != shown)
+ info[_("Last seen address")] = na->GetLastRealhost();
+ }
+
+ info[_("Registered")] = Anope::strftime(na->GetTimeRegistered(), source.GetAccount());
+
+ if (!nick_online)
+ info[_("Last seen")] = Anope::strftime(na->GetLastSeen(), source.GetAccount());
+
+ if (!na->GetLastQuit().empty() && (show_hidden || !na->GetAccount()->HasFieldS("HIDE_QUIT")))
+ info[_("Last quit message")] = na->GetLastQuit();
+
+ if (!na->GetAccount()->GetEmail().empty() && (show_hidden || !na->GetAccount()->HasFieldS("HIDE_EMAIL")))
+ info[_("Email address")] = na->GetAccount()->GetEmail();
+
+ if (show_hidden)
+ {
+ if (na->HasVhost())
+ {
+ if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
+ info[_("VHost")] = na->GetVhostIdent() + "@" + na->GetVhostHost();
+ else
+ info[_("VHost")] = na->GetVhostHost();
+ }
+ }
+
+ EventManager::Get()->Dispatch(&Event::NickInfo::OnNickInfo, source, na, info, show_hidden);
+
+ std::vector<Anope::string> replies;
+ info.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Displays information about the given nickname, such as\n"
+ "the nick's owner, last seen address and time, and nick\n"
+ "options. If no nick is given, and you are identified,\n"
+ "your account name is used, else your current nickname is\n"
+ "used."));
+
+ return true;
+ }
+};
+
+
+class CommandNSSetHide : public Command
+{
+ public:
+ CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Hide certain pieces of nickname information"));
+ this->SetSyntax("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param, const Anope::string &arg)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ const char *onmsg, *offmsg, *flag;
+
+ if (param.equals_ci("EMAIL"))
+ {
+ flag = "HIDE_EMAIL";
+ onmsg = _("The \002e-mail address\002 of \002{0}\002 will now be \002hidden\002.");
+ offmsg = _("The \002e-mail address\002 of \002{0}\002 will now be \002shown\002.");
+ }
+ else if (param.equals_ci("USERMASK"))
+ {
+ flag = "HIDE_MASK";
+ onmsg = _("The \002last seen host mask\002 of \002{0}\002 will now be \002hidden\002.");
+ offmsg = _("The \002last seen host mask\002 of \002{0}\002 will now be \002shown\002.");
+ }
+ else if (param.equals_ci("STATUS"))
+ {
+ flag = "HIDE_STATUS";
+ onmsg = _("The \002services operator status\002 of \002{0}\002 will now be \002hidden\002.");
+ offmsg = _("The \002services operator status\002 of \002{0}\002 will now be \002shown\002.");
+ }
+ else if (param.equals_ci("QUIT"))
+ {
+ flag = "HIDE_QUIT";
+ onmsg = _("The \002last quit message\002 of \002{0}\002 will now be \002hidden\002.");
+ offmsg = _("The \002last quit message\002 of \002{0}\002 will now be \002shown\002.");
+ }
+ else
+ {
+ this->OnSyntaxError(source, "HIDE");
+ return;
+ }
+
+ if (arg.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->GetDisplay();
+ nc->SetS<bool>(flag, true);
+ source.Reply(onmsg, nc->GetDisplay(), source.service->nick);
+ }
+ else if (arg.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->GetDisplay();
+ nc->UnsetS<bool>(flag);
+ source.Reply(offmsg, nc->GetDisplay(), source.service->nick);
+ }
+ else
+ this->OnSyntaxError(source, "HIDE");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Allows you to prevent certain pieces of information from being displayed when someone does a %s \002INFO\002 on you." //XXX
+ " You can hide the e-mail address (\002EMAIL\002), last seen hostmask (\002USERMASK\002), the services access status (\002STATUS\002) and last quit message (\002QUIT\002)."
+ "The second parameter specifies whether the information should\n"
+ "be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick);
+ return true;
+ }
+};
+
+class CommandNSSASetHide : public CommandNSSetHide
+{
+ public:
+ CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3)
+ {
+ this->SetSyntax(_("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->ClearSyntax();
+ this->Run(source, params[0], params[1], params[2]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Allows you to prevent certain pieces of information from being displayed when someone does a %s \002INFO\002 on the \037nickname\037. "
+ " You can hide the e-mail address (\002EMAIL\002), last seen hostmask (\002USERMASK\002), the services access status (\002STATUS\002) and last quit message (\002QUIT\002)."
+ " The second parameter specifies whether the information should be displayed (\002OFF\002) or hidden (\002ON\002)."),
+ source.service->nick);
+ return true;
+ }
+};
+
+class NSInfo : public Module
+{
+ CommandNSInfo commandnsinfo;
+
+ CommandNSSetHide commandnssethide;
+ CommandNSSASetHide commandnssasethide;
+
+ Serialize::Field<NickServ::Account, bool> hide_email, hide_usermask, hide_status, hide_quit;
+
+ public:
+ NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsinfo(this)
+ , commandnssethide(this)
+ , commandnssasethide(this)
+ , hide_email(this, "HIDE_EMAIL")
+ , hide_usermask(this, "HIDE_MASK")
+ , hide_status(this, "HIDE_STATUS")
+ , hide_quit(this, "HIDE_QUIT")
+ {
+
+ }
+};
+
+MODULE_INIT(NSInfo)
diff --git a/modules/nickserv/list.cpp b/modules/nickserv/list.cpp
new file mode 100644
index 000000000..4b4a12d36
--- /dev/null
+++ b/modules/nickserv/list.cpp
@@ -0,0 +1,299 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv/set.h"
+
+class CommandNSList : public Command
+{
+ public:
+ CommandNSList(Module *creator) : Command(creator, "nickserv/list", 1, 2)
+ {
+ this->SetDesc(_("List all registered nicknames that match a given pattern"));
+ this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ Anope::string pattern = params[0];
+ const NickServ::Account *mync;
+ unsigned nnicks;
+ bool is_servadmin = source.HasCommand("nickserv/list");
+ int count = 0, from = 0, to = 0;
+ bool suspended, nsnoexpire, unconfirmed;
+ unsigned listmax = Config->GetModule(this->GetOwner())->Get<unsigned>("listmax", "50");
+
+ suspended = nsnoexpire = unconfirmed = false;
+
+ if (pattern[0] == '#')
+ {
+ Anope::string n1, n2;
+ sepstream(pattern.substr(1), '-').GetToken(n1, 0);
+ sepstream(pattern, '-').GetToken(n2, 1);
+ try
+ {
+ from = convertTo<int>(n1);
+ to = convertTo<int>(n2);
+ }
+ catch (const ConvertException &)
+ {
+ source.Reply(_("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002."));
+ return;
+ }
+
+ pattern = "*";
+ }
+
+ nnicks = 0;
+
+ if (is_servadmin && params.size() > 1)
+ {
+ Anope::string keyword;
+ spacesepstream keywords(params[1]);
+ while (keywords.GetToken(keyword))
+ {
+ if (keyword.equals_ci("NOEXPIRE"))
+ nsnoexpire = true;
+ if (keyword.equals_ci("SUSPENDED"))
+ suspended = true;
+ if (keyword.equals_ci("UNCONFIRMED"))
+ unconfirmed = true;
+ }
+ }
+
+ mync = source.nc;
+ ListFormatter list(source.GetAccount());
+
+ list.AddColumn(_("Nick")).AddColumn(_("Last usermask"));
+
+ // XXX wtf
+ Anope::map<NickServ::Nick *> ordered_map;
+ for (NickServ::Nick *na : NickServ::service->GetNickList())
+ ordered_map[na->GetNick()] = na;
+
+ for (Anope::map<NickServ::Nick *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
+ {
+ NickServ::Nick *na = it->second;
+
+ /* Don't show private nicks to non-services admins. */
+ if (na->GetAccount()->HasFieldS("NS_PRIVATE") && !is_servadmin && na->GetAccount() != mync)
+ continue;
+ else if (nsnoexpire && !na->HasFieldS("NS_NO_EXPIRE"))
+ continue;
+ else if (suspended && !na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ continue;
+ else if (unconfirmed && !na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ continue;
+
+ /* We no longer compare the pattern against the output buffer.
+ * Instead we build a nice nick!user@host buffer to compare.
+ * The output is then generated separately. -TheShadow */
+ Anope::string buf = Anope::printf("%s!%s", na->GetNick().c_str(), !na->GetLastUsermask().empty() ? na->GetLastUsermask().c_str() : "*@*");
+ if (na->GetNick().equals_ci(pattern) || Anope::Match(buf, pattern, false, true))
+ {
+ if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax)
+ {
+ bool isnoexpire = false;
+ if (is_servadmin && na->HasFieldS("NS_NO_EXPIRE"))
+ isnoexpire = true;
+
+ ListFormatter::ListEntry entry;
+ entry["Nick"] = (isnoexpire ? "!" : "") + na->GetNick();
+ if (na->GetAccount()->HasFieldS("HIDE_MASK") && !is_servadmin && na->GetAccount() != mync)
+ entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Hostname hidden]"));
+ else if (na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
+ else if (na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Unconfirmed]"));
+ else
+ entry["Last usermask"] = na->GetLastUsermask();
+ list.AddEntry(entry);
+ }
+ ++count;
+ }
+ }
+
+ source.Reply(_("List of entries matching \002{0}\002:"), pattern);
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of list - \002{0}\002/\002{1}\002 matches shown."), nnicks > listmax ? listmax : nnicks, nnicks);
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Lists all registered nicknames which match the given pattern, in \037nick!user@host\037 format."
+ " Nicks with the \002PRIVATE\002 option set will only be displayed to Services Operators with the proper access."
+ " Nicks with the \002NOEXPIRE\002 option set will have a \002!\002 prefixed to the nickname for Services Operators to see.\n"
+ "\n"
+ "Note that a preceding '#' specifies a range.\n"
+ "\n"
+ "If the SUSPENDED, UNCONFIRMED or NOEXPIRE options are given, only\n"
+ "nicks which, respectively, are SUSPENDED, UNCONFIRMED or have the\n"
+ "NOEXPIRE flag set will be displayed. If multiple options are\n"
+ "given, all nicks matching at least one option will be displayed.\n"
+ "Note that these options are limited to \037Services Operators\037.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ " {0} *!joeuser@foo.com\n"
+ " Lists all registered nicks owned by joeuser@foo.com.\n"
+ "\n"
+ " {0} *Bot*!*@*\n"
+ " Lists all registered nicks with \002Bot\002 in their names (case insensitive).\n"
+ "\n"
+ " {0} * NOEXPIRE\n"
+ " Lists all registered nicks which have been set to not expire.\n"
+ "\n"
+ " {0} #51-100\n"
+ " Lists all registered nicks within the given range (51-100)."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your pattern in // if this is desired."), regexengine);
+ }
+
+ return true;
+ }
+};
+
+
+class CommandNSSetPrivate : public Command
+{
+ public:
+ CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Prevent your account from appearing in the LIST command"));
+ this->SetSyntax("{ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->GetDisplay();
+ nc->SetS<bool>("NS_PRIVATE", true);
+ source.Reply(_("Private option is now \002on\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->GetDisplay();
+ nc->UnsetS<bool>("NS_PRIVATE");
+ source.Reply(_("Private option is now \002off\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "PRIVATE");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the privacy option on or off for your account."
+ " When \002PRIVATE\002 is set, your account will not appear in the account list."
+ " However, anyone who knows your account can still request information about it."));
+ return true;
+ }
+};
+
+class CommandNSSASetPrivate : public CommandNSSetPrivate
+{
+ public:
+ CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the privacy option on or off for \037account\037."
+ " When \002PRIVATE\002 is set, the account will not appear in the account list."
+ " However, anyone who knows your account can still request information about it."));
+ return true;
+ }
+};
+
+
+class NSList : public Module
+ , public EventHook<Event::NickInfo>
+{
+ CommandNSList commandnslist;
+
+ CommandNSSetPrivate commandnssetprivate;
+ CommandNSSASetPrivate commandnssasetprivate;
+
+ Serialize::Field<NickServ::Account, bool> priv;
+
+ public:
+ NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::NickInfo>(this)
+ , commandnslist(this)
+ , commandnssetprivate(this)
+ , commandnssasetprivate(this)
+ , priv(this, "NS_PRIVATE")
+ {
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_all) override
+ {
+ if (!show_all)
+ return;
+
+ if (priv.HasExt(na->GetAccount()))
+ info.AddOption(_("Private"));
+ }
+};
+
+MODULE_INIT(NSList)
diff --git a/modules/nickserv/logout.cpp b/modules/nickserv/logout.cpp
new file mode 100644
index 000000000..6a9d119ad
--- /dev/null
+++ b/modules/nickserv/logout.cpp
@@ -0,0 +1,109 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv.h"
+
+class CommandNSLogout : public Command
+{
+ public:
+ CommandNSLogout(Module *creator) : Command(creator, "nickserv/logout", 0, 2)
+ {
+ this->SetDesc(_("Reverses the effect of the IDENTIFY command"));
+ this->SetSyntax(_("[\037nickname\037 [REVALIDATE]]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ const Anope::string &nick = !params.empty() ? params[0] : "";
+ const Anope::string &param = params.size() > 1 ? params[1] : "";
+
+ if (!source.IsServicesOper() && !nick.empty())
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ User *u2 = !nick.empty() ? User::Find(nick, true) : source.GetUser();
+ if (!u2)
+ {
+ source.Reply(_("\002{0}\002 isn't currently online."), !nick.empty() ? nick : source.GetNick());
+ return;
+ }
+
+ if (!nick.empty() && u2->IsServicesOper())
+ {
+ source.Reply(_("You can't logout \002{0}\002, they are a Services Operator."), nick);
+ return;
+ }
+
+#warning "revalidate"
+#if 0
+ if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE") && NickServ::service)
+ NickServ::service->Validate(u2);
+#endif
+
+ u2->super_admin = false; /* Dont let people logout and remain a SuperAdmin */
+ Log(LOG_COMMAND, source, this) << "to logout " << u2->nick;
+
+ if (!nick.empty())
+ source.Reply(_("\002{0}\002 has been logged out."), nick);
+ else
+ source.Reply(_("You have been logged out."));
+
+ IRCD->SendLogout(u2);
+ u2->RemoveMode(source.service, "REGISTERED");
+ u2->Logout();
+
+ /* Send out an event */
+ EventManager::Get()->Dispatch(&Event::NickLogout::OnNickLogout, u2);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Logs you out of your account"));
+ #if 0
+ source.Reply(_("Without a parameter, reverses the effect of the \002IDENTIFY\002\n"
+ "command, i.e. make you not recognized as the real owner of the nick\n"
+ "anymore. Note, however, that you won't be asked to reidentify\n"
+ "yourself.\n"
+ " \n"
+ "With a parameter, does the same for the given nick. If you\n"
+ "specify \002REVALIDATE\002 as well, Services will ask the given nick\n"
+ "to re-identify. This is limited to \002Services Operators\002."));
+ #endif
+
+ return true;
+ }
+};
+
+class NSLogout : public Module
+{
+ CommandNSLogout commandnslogout;
+
+ public:
+ NSLogout(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnslogout(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSLogout)
diff --git a/modules/nickserv/main/CMakeLists.txt b/modules/nickserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/nickserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/nickserv/main/account.cpp b/modules/nickserv/main/account.cpp
new file mode 100644
index 000000000..1c2266e59
--- /dev/null
+++ b/modules/nickserv/main/account.cpp
@@ -0,0 +1,136 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "accounttype.h"
+#include "modules/nickserv/access.h"
+
+AccountImpl::~AccountImpl()
+{
+ NickServ::nickcore_map& map = NickServ::service->GetAccountMap();
+ map.erase(this->GetDisplay());
+}
+
+void AccountImpl::Delete()
+{
+ EventManager::Get()->Dispatch(&Event::DelCore::OnDelCore, this);
+
+ for (unsigned i = users.size(); i > 0; --i)
+ users[i - 1]->Logout();
+
+ return Serialize::Object::Delete();
+}
+
+Anope::string AccountImpl::GetDisplay()
+{
+ return Get<Anope::string>(&AccountType::display);
+}
+
+void AccountImpl::SetDisplay(const Anope::string &disp)
+{
+ Set(&AccountType::display, disp);
+}
+
+Anope::string AccountImpl::GetPassword()
+{
+ return Get(&AccountType::pass);
+}
+
+void AccountImpl::SetPassword(const Anope::string &pass)
+{
+ Set(&AccountType::pass, pass);
+}
+
+Anope::string AccountImpl::GetEmail()
+{
+ return Get(&AccountType::email);
+}
+
+void AccountImpl::SetEmail(const Anope::string &email)
+{
+ Set(&AccountType::email, email);
+}
+
+Anope::string AccountImpl::GetLanguage()
+{
+ return Get(&AccountType::language);
+}
+
+void AccountImpl::SetLanguage(const Anope::string &lang)
+{
+ Set(&AccountType::language, lang);
+}
+
+MemoServ::MemoInfo *AccountImpl::GetMemos()
+{
+ return GetRef<MemoServ::MemoInfo *>();
+}
+
+void AccountImpl::SetDisplay(NickServ::Nick *na)
+{
+ if (na->GetAccount() != this || na->GetNick() == this->GetDisplay())
+ return;
+
+ EventManager::Get()->Dispatch(&Event::ChangeCoreDisplay::OnChangeCoreDisplay, this, na->GetNick());
+
+ NickServ::nickcore_map& map = NickServ::service->GetAccountMap();
+
+ /* Remove the core from the list */
+ map.erase(this->GetDisplay());
+
+ this->SetDisplay(na->GetNick());
+
+ NickServ::Account* &nc = map[this->GetDisplay()];
+ if (nc)
+ Log(LOG_DEBUG) << "Duplicate account " << this->GetDisplay() << " in nickcore table?";
+
+ nc = this;
+}
+
+bool AccountImpl::IsServicesOper() const
+{
+ return this->o != NULL;
+}
+
+bool AccountImpl::IsOnAccess(User *u)
+{
+ Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3;
+ if (!u->vhost.empty())
+ buf2 = u->GetIdent() + "@" + u->vhost;
+ if (!u->GetCloakedHost().empty())
+ buf3 = u->GetIdent() + "@" + u->GetCloakedHost();
+
+ for (NickAccess *access : GetRefs<NickAccess *>())
+ {
+ Anope::string a = access->GetMask();
+ if (Anope::Match(buf, a) || (!buf2.empty() && Anope::Match(buf2, a)) || (!buf3.empty() && Anope::Match(buf3, a)))
+ return true;
+ }
+ return false;
+}
+
+unsigned int AccountImpl::GetChannelCount()
+{
+ unsigned int i = 0;
+ for (ChanServ::Channel *c : GetRefs<ChanServ::Channel *>())
+ if (c->GetFounder() == this)
+ ++i;
+ return i;
+}
+
diff --git a/modules/nickserv/main/account.h b/modules/nickserv/main/account.h
new file mode 100644
index 000000000..461a3d865
--- /dev/null
+++ b/modules/nickserv/main/account.h
@@ -0,0 +1,58 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/nickserv.h"
+
+class AccountImpl : public NickServ::Account
+{
+ friend class AccountType;
+
+ Anope::string display, password, email, language;
+
+ public:
+ AccountImpl(Serialize::TypeBase *type) : NickServ::Account(type) { }
+ AccountImpl(Serialize::TypeBase *type, Serialize::ID id) : NickServ::Account(type, id) { }
+ ~AccountImpl();
+ void Delete() override;
+
+ Anope::string GetDisplay() override;
+ void SetDisplay(const Anope::string &) override;
+
+ Anope::string GetPassword() override;
+ void SetPassword(const Anope::string &) override;
+
+ Anope::string GetEmail() override;
+ void SetEmail(const Anope::string &) override;
+
+ Anope::string GetLanguage() override;
+ void SetLanguage(const Anope::string &) override;
+
+ MemoServ::MemoInfo *GetMemos() override;
+
+ void SetDisplay(NickServ::Nick *na) override;
+ bool IsServicesOper() const override;
+ /*void AddAccess(const Anope::string &entry) override;
+ Anope::string GetAccess(unsigned entry) const override;
+ unsigned GetAccessCount() const override;
+ bool FindAccess(const Anope::string &entry) override;
+ void EraseAccess(const Anope::string &entry) override;
+ void ClearAccess() override;*/
+ bool IsOnAccess(User *u) override;
+ unsigned int GetChannelCount() override;
+};
diff --git a/modules/nickserv/main/accounttype.cpp b/modules/nickserv/main/accounttype.cpp
new file mode 100644
index 000000000..16abea415
--- /dev/null
+++ b/modules/nickserv/main/accounttype.cpp
@@ -0,0 +1,60 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "accounttype.h"
+
+AccountType::AccountType(Module *me) : Serialize::Type<AccountImpl>(me)
+ , display(this, "display", &AccountImpl::display)
+ , pass(this, "pass", &AccountImpl::password)
+ , email(this, "email", &AccountImpl::email)
+ , language(this, "language", &AccountImpl::language)
+{
+
+}
+
+void AccountType::Display::SetField(AccountImpl *acc, const Anope::string &disp)
+{
+ NickServ::nickcore_map& map = NickServ::service->GetAccountMap();
+
+ if (!acc->GetDisplay().empty())
+ map.erase(acc->GetDisplay());
+
+ Serialize::Field<AccountImpl, Anope::string>::SetField(acc, disp);
+
+ if (!disp.empty())
+ map[disp] = acc;
+
+ acc->o = Oper::Find(disp);
+}
+
+NickServ::Account *AccountType::FindAccount(const Anope::string &acc)
+{
+ Serialize::ID id;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeFind, this, &this->display, acc, id);
+ if (result == EVENT_ALLOW)
+ return RequireID(id);
+
+ NickServ::nickcore_map &map = NickServ::service->GetAccountMap();
+ auto it = map.find(acc);
+ if (it != map.end())
+ return it->second;
+ return nullptr;
+}
+
diff --git a/modules/nickserv/main/accounttype.h b/modules/nickserv/main/accounttype.h
new file mode 100644
index 000000000..4cdba74b0
--- /dev/null
+++ b/modules/nickserv/main/accounttype.h
@@ -0,0 +1,42 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "account.h"
+
+class AccountType : public Serialize::Type<AccountImpl>
+{
+ public:
+ /* Name of the account */
+ struct Display : Serialize::Field<AccountImpl, Anope::string>
+ {
+ using Serialize::Field<AccountImpl, Anope::string>::Field;
+
+ void SetField(AccountImpl *s, const Anope::string &) override;
+ } display;
+ /* User password in form of hashm:data */
+ Serialize::Field<AccountImpl, Anope::string> pass;
+ Serialize::Field<AccountImpl, Anope::string> email;
+ /* Locale name of the language of the user. Empty means default language */
+ Serialize::Field<AccountImpl, Anope::string> language;
+
+
+ AccountType(Module *);
+
+ NickServ::Account *FindAccount(const Anope::string &nick);
+};
diff --git a/modules/nickserv/main/identifyrequest.cpp b/modules/nickserv/main/identifyrequest.cpp
new file mode 100644
index 000000000..a99db9441
--- /dev/null
+++ b/modules/nickserv/main/identifyrequest.cpp
@@ -0,0 +1,81 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "identifyrequest.h"
+
+IdentifyRequestImpl::IdentifyRequestImpl(NickServ::IdentifyRequestListener *li, Module *o, const Anope::string &acc, const Anope::string &pass) : NickServ::IdentifyRequest(li, o, acc, pass)
+{
+ std::set<NickServ::IdentifyRequest *> &requests = NickServ::service->GetIdentifyRequests();
+ requests.insert(this);
+}
+
+IdentifyRequestImpl::~IdentifyRequestImpl()
+{
+ std::set<NickServ::IdentifyRequest *> &requests = NickServ::service->GetIdentifyRequests();
+ requests.erase(this);
+ delete l;
+}
+
+void IdentifyRequestImpl::Hold(Module *m)
+{
+ holds.insert(m);
+}
+
+void IdentifyRequestImpl::Release(Module *m)
+{
+ holds.erase(m);
+ if (holds.empty() && dispatched)
+ {
+ if (!success)
+ l->OnFail(this);
+ delete this;
+ }
+}
+
+void IdentifyRequestImpl::Success(Module *m)
+{
+ if (!success)
+ {
+ l->OnSuccess(this);
+ success = true;
+ }
+}
+
+void IdentifyRequestImpl::Dispatch()
+{
+ if (holds.empty())
+ {
+ if (!success)
+ l->OnFail(this);
+ delete this;
+ }
+ else
+ dispatched = true;
+}
+
+void IdentifyRequestImpl::Unload(Module *m)
+{
+ if (this->GetOwner() != m)
+ return;
+
+ if (!success)
+ l->OnFail(this);
+ delete this;
+}
+
diff --git a/modules/nickserv/main/identifyrequest.h b/modules/nickserv/main/identifyrequest.h
new file mode 100644
index 000000000..6670b5244
--- /dev/null
+++ b/modules/nickserv/main/identifyrequest.h
@@ -0,0 +1,33 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/nickserv.h"
+
+class IdentifyRequestImpl : public NickServ::IdentifyRequest
+{
+ public:
+ IdentifyRequestImpl(NickServ::IdentifyRequestListener *, Module *o, const Anope::string &acc, const Anope::string &pass);
+ virtual ~IdentifyRequestImpl();
+
+ void Hold(Module *m) override;
+ void Release(Module *m) override;
+ void Success(Module *m) override;
+ void Dispatch() override;
+ void Unload(Module *);
+};
diff --git a/modules/nickserv/main/mode.cpp b/modules/nickserv/main/mode.cpp
new file mode 100644
index 000000000..864ec2123
--- /dev/null
+++ b/modules/nickserv/main/mode.cpp
@@ -0,0 +1,42 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/nickserv.h"
+#include "modetype.h"
+
+NickServ::Account *ModeImpl::GetAccount()
+{
+ return Get(&NSModeType::account);
+}
+
+void ModeImpl::SetAccount(NickServ::Account *a)
+{
+ Set(&NSModeType::account, a);
+}
+
+Anope::string ModeImpl::GetMode()
+{
+ return Get(&NSModeType::mode);
+}
+
+void ModeImpl::SetMode(const Anope::string &m)
+{
+ Set(&NSModeType::mode, m);
+}
+
diff --git a/modules/nickserv/main/mode.h b/modules/nickserv/main/mode.h
new file mode 100644
index 000000000..a8db73b7e
--- /dev/null
+++ b/modules/nickserv/main/mode.h
@@ -0,0 +1,37 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class ModeImpl : public NickServ::Mode
+{
+ friend class NSModeType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string mode;
+
+ public:
+ ModeImpl(Serialize::TypeBase *type) : NickServ::Mode(type) { }
+ ModeImpl(Serialize::TypeBase *type, Serialize::ID id) : NickServ::Mode(type, id) { }
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ Anope::string GetMode() override;
+ void SetMode(const Anope::string &) override;
+};
+
diff --git a/modules/nickserv/main/modetype.h b/modules/nickserv/main/modetype.h
new file mode 100644
index 000000000..8bc8c7f7f
--- /dev/null
+++ b/modules/nickserv/main/modetype.h
@@ -0,0 +1,33 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mode.h"
+
+class NSModeType : public Serialize::Type<ModeImpl>
+{
+ public:
+ Serialize::ObjectField<ModeImpl, NickServ::Account *> account;
+ Serialize::Field<ModeImpl, Anope::string> mode;
+
+ NSModeType(Module *creator) : Serialize::Type<ModeImpl>(creator)
+ , account(this, "account", &ModeImpl::account, true)
+ , mode(this, "mode", &ModeImpl::mode)
+ {
+ }
+};
diff --git a/modules/nickserv/main/nick.cpp b/modules/nickserv/main/nick.cpp
new file mode 100644
index 000000000..3fc1e6b05
--- /dev/null
+++ b/modules/nickserv/main/nick.cpp
@@ -0,0 +1,199 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "nicktype.h"
+
+NickImpl::~NickImpl()
+{
+ /* Remove us from the aliases list */
+ NickServ::nickalias_map &map = NickServ::service->GetNickMap();
+ map.erase(GetNick());
+}
+
+void NickImpl::Delete()
+{
+ EventManager::Get()->Dispatch(&Event::DelNick::OnDelNick, this);
+
+ if (this->GetAccount())
+ {
+ /* Next: see if our core is still useful. */
+ std::vector<NickServ::Nick *> aliases = this->GetAccount()->GetRefs<NickServ::Nick *>();
+
+ auto it = std::find(aliases.begin(), aliases.end(), this);
+ if (it != aliases.end())
+ aliases.erase(it);
+
+ if (aliases.empty())
+ {
+ /* just me */
+ this->GetAccount()->Delete();
+ }
+ else
+ {
+ /* Display updating stuff */
+ if (GetNick().equals_ci(this->GetAccount()->GetDisplay()))
+ this->GetAccount()->SetDisplay(aliases[0]);
+ }
+ }
+
+ return Serialize::Object::Delete();
+}
+
+Anope::string NickImpl::GetNick()
+{
+ return Get<Anope::string>(&NickType::nick);
+}
+
+void NickImpl::SetNick(const Anope::string &nick)
+{
+ Set(&NickType::nick, nick);
+}
+
+Anope::string NickImpl::GetLastQuit()
+{
+ return Get(&NickType::last_quit);
+}
+
+void NickImpl::SetLastQuit(const Anope::string &lq)
+{
+ Set(&NickType::last_quit, lq);
+}
+
+Anope::string NickImpl::GetLastRealname()
+{
+ return Get(&NickType::last_realname);
+}
+
+void NickImpl::SetLastRealname(const Anope::string &lr)
+{
+ Set(&NickType::last_realname, lr);
+}
+
+Anope::string NickImpl::GetLastUsermask()
+{
+ return Get(&NickType::last_usermask);
+}
+
+void NickImpl::SetLastUsermask(const Anope::string &lu)
+{
+ Set(&NickType::last_usermask, lu);
+}
+
+Anope::string NickImpl::GetLastRealhost()
+{
+ return Get(&NickType::last_realhost);
+}
+
+void NickImpl::SetLastRealhost(const Anope::string &lr)
+{
+ Set(&NickType::last_realhost, lr);
+}
+
+time_t NickImpl::GetTimeRegistered()
+{
+ return Get(&NickType::time_registered);
+}
+
+void NickImpl::SetTimeRegistered(const time_t &tr)
+{
+ Set(&NickType::time_registered, tr);
+}
+
+time_t NickImpl::GetLastSeen()
+{
+ return Get(&NickType::last_seen);
+}
+
+void NickImpl::SetLastSeen(const time_t &ls)
+{
+ Set(&NickType::last_seen, ls);
+}
+
+NickServ::Account *NickImpl::GetAccount()
+{
+ return Get(&NickType::nc);
+}
+
+void NickImpl::SetAccount(NickServ::Account *acc)
+{
+ Set(&NickType::nc, acc);
+}
+
+void NickImpl::SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created)
+{
+ Set(&NickType::vhost_ident, ident);
+ Set(&NickType::vhost_host, host);
+ Set(&NickType::vhost_creator, creator);
+ Set(&NickType::vhost_created, created);
+}
+
+void NickImpl::RemoveVhost()
+{
+ Anope::string e;
+ Set(&NickType::vhost_ident, e);
+ Set(&NickType::vhost_host, e);
+ Set(&NickType::vhost_creator, e);
+ Set(&NickType::vhost_created, 0);
+}
+
+bool NickImpl::HasVhost()
+{
+ return !GetVhostHost().empty();
+}
+
+Anope::string NickImpl::GetVhostIdent()
+{
+ return Get(&NickType::vhost_ident);
+}
+
+void NickImpl::SetVhostIdent(const Anope::string &i)
+{
+ Set(&NickType::vhost_ident, i);
+}
+
+Anope::string NickImpl::GetVhostHost()
+{
+ return Get(&NickType::vhost_host);
+}
+
+void NickImpl::SetVhostHost(const Anope::string &h)
+{
+ Set(&NickType::vhost_host, h);
+}
+
+Anope::string NickImpl::GetVhostCreator()
+{
+ return Get(&NickType::vhost_creator);
+}
+
+void NickImpl::SetVhostCreator(const Anope::string &c)
+{
+ Set(&NickType::vhost_creator, c);
+}
+
+time_t NickImpl::GetVhostCreated()
+{
+ return Get(&NickType::vhost_created);
+}
+
+void NickImpl::SetVhostCreated(const time_t &cr)
+{
+ Set(&NickType::vhost_created, cr);
+}
diff --git a/modules/nickserv/main/nick.h b/modules/nickserv/main/nick.h
new file mode 100644
index 000000000..ce0111b59
--- /dev/null
+++ b/modules/nickserv/main/nick.h
@@ -0,0 +1,72 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+class NickImpl : public NickServ::Nick
+{
+ friend class NickType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string nick, last_quit, last_realname, last_usermask, last_realhost;
+ time_t time_registered = 0, last_seen = 0;
+ Anope::string vhost_ident, vhost_host, vhost_creator;
+ time_t vhost_created = 0;
+
+ public:
+ NickImpl(Serialize::TypeBase *type) : NickServ::Nick(type) { }
+ NickImpl(Serialize::TypeBase *type, Serialize::ID id) : NickServ::Nick(type, id) { }
+ ~NickImpl();
+ void Delete() override;
+
+ Anope::string GetNick() override;
+ void SetNick(const Anope::string &) override;
+
+ Anope::string GetLastQuit() override;
+ void SetLastQuit(const Anope::string &) override;
+
+ Anope::string GetLastRealname() override;
+ void SetLastRealname(const Anope::string &) override;
+
+ Anope::string GetLastUsermask() override;
+ void SetLastUsermask(const Anope::string &) override;
+
+ Anope::string GetLastRealhost() override;
+ void SetLastRealhost(const Anope::string &) override;
+
+ time_t GetTimeRegistered() override;
+ void SetTimeRegistered(const time_t &) override;
+
+ time_t GetLastSeen() override;
+ void SetLastSeen(const time_t &) override;
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *acc) override;
+
+ void SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created = Anope::CurTime) override;
+ void RemoveVhost() override;
+ bool HasVhost() override;
+
+ Anope::string GetVhostIdent() override;
+ void SetVhostIdent(const Anope::string &) override;
+ Anope::string GetVhostHost() override;
+ void SetVhostHost(const Anope::string &) override;
+ Anope::string GetVhostCreator() override;
+ void SetVhostCreator(const Anope::string &) override;
+ time_t GetVhostCreated() override;
+ void SetVhostCreated(const time_t &) override;
+};
diff --git a/modules/nickserv/main/nickserv.cpp b/modules/nickserv/main/nickserv.cpp
new file mode 100644
index 000000000..8f33caf87
--- /dev/null
+++ b/modules/nickserv/main/nickserv.cpp
@@ -0,0 +1,693 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv/group.h"
+#include "modules/nickserv/update.h"
+#include "modules/help.h"
+#include "modules/nickserv.h"
+#include "identifyrequest.h"
+#include "nicktype.h"
+#include "accounttype.h"
+#include "modetype.h"
+
+class NickServCollide;
+static std::set<NickServCollide *> collides;
+
+/** Timer for colliding nicks to force people off of nicknames
+ */
+class NickServCollide : public Timer
+{
+ NickServ::NickServService *service;
+ Reference<User> u;
+ time_t ts;
+ Reference<NickServ::Nick> na;
+
+ public:
+ NickServCollide(Module *me, NickServ::NickServService *nss, User *user, NickServ::Nick *nick, time_t delay) : Timer(me, delay), service(nss), u(user), ts(user->timestamp), na(nick)
+ {
+ collides.insert(this);
+ }
+
+ ~NickServCollide()
+ {
+ collides.erase(this);
+ }
+
+ NickServ::Nick *GetNick()
+ {
+ return na;
+ }
+
+ User *GetUser()
+ {
+ return u;
+ }
+
+ void Tick(time_t t) override
+ {
+ if (!u || !na)
+ return;
+ /* If they identified or don't exist anymore, don't kill them. */
+ if (u->Account() == na->GetAccount() || u->timestamp > ts)
+ return;
+
+ service->Collide(u, na);
+ }
+};
+
+/** Timer for removing HELD status from nicks.
+ */
+class NickServHeld : public Timer
+{
+ Reference<NickServ::Nick> na;
+ Anope::string nick;
+ public:
+ NickServHeld(Module *me, NickServ::Nick *n, long l) : Timer(me, l), na(n), nick(na->GetNick())
+ {
+ n->SetS<bool>("HELD", true);
+ }
+
+ void Tick(time_t) override
+ {
+ if (na)
+ na->UnsetS<bool>("HELD");
+ }
+};
+
+class NickServRelease;
+static Anope::map<NickServRelease *> NickServReleases;
+
+/** Timer for releasing nicks to be available for use
+ */
+class NickServRelease : public User, public Timer
+{
+ Anope::string nick;
+
+ public:
+ NickServRelease(Module *me, NickServ::Nick *na, time_t delay) : User(na->GetNick(), Config->GetModule("nickserv")->Get<Anope::string>("enforceruser", "user"),
+ Config->GetModule("nickserv")->Get<Anope::string>("enforcerhost", "services.localhost.net"), "", "", Me, "Services Enforcer", Anope::CurTime, "", IRCD->UID_Retrieve(), NULL), Timer(me, delay), nick(na->GetNick())
+ {
+ /* Erase the current release timer and use the new one */
+ Anope::map<NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
+ if (nit != NickServReleases.end())
+ {
+ IRCD->SendQuit(nit->second, "");
+ delete nit->second;
+ }
+
+ NickServReleases.insert(std::make_pair(this->nick, this));
+
+ IRCD->SendClientIntroduction(this);
+ }
+
+ ~NickServRelease()
+ {
+ IRCD->SendQuit(this, "");
+ NickServReleases.erase(this->nick);
+ }
+
+ void Tick(time_t t) override { }
+};
+
+class NickServCore : public Module, public NickServ::NickServService
+ , public EventHook<Event::Shutdown>
+ , public EventHook<Event::Restart>
+ , public EventHook<Event::UserLogin>
+ , public EventHook<Event::DelNick>
+ , public EventHook<Event::DelCore>
+ , public EventHook<Event::ChangeCoreDisplay>
+ , public EventHook<Event::NickIdentify>
+ , public EventHook<Event::NickGroup>
+ , public EventHook<Event::NickUpdate>
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::PostUserLogoff>
+ , public EventHook<Event::ServerSync>
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::UserModeSet>
+ , public EventHook<Event::Help>
+ , public EventHook<Event::ExpireTick>
+ , public EventHook<Event::NickInfo>
+ , public EventHook<Event::ModuleUnload>
+ , public EventHook<NickServ::Event::NickRegister>
+ , public EventHook<Event::UserQuit>
+{
+ Reference<ServiceBot> NickServ;
+ std::vector<Anope::string> defaults;
+ ExtensibleItem<bool> held, collided;
+ std::set<NickServ::IdentifyRequest *> identifyrequests;
+ NickServ::nickalias_map NickList;
+ NickServ::nickcore_map AccountList;
+ NickType nick_type;
+ AccountType account_type;
+ NSModeType mode_type;
+
+ void OnCancel(User *u, NickServ::Nick *na)
+ {
+ if (collided.HasExt(na))
+ {
+ collided.Unset(na);
+
+ new NickServHeld(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
+
+ if (IRCD->CanSVSHold)
+ IRCD->SendSVSHold(na->GetNick(), Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
+ else
+ new NickServRelease(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
+ }
+ }
+
+ public:
+ NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , NickServ::NickServService(this)
+
+ , EventHook<Event::Shutdown>(this)
+ , EventHook<Event::Restart>(this)
+ , EventHook<Event::UserLogin>(this)
+ , EventHook<Event::DelNick>(this)
+ , EventHook<Event::DelCore>(this)
+ , EventHook<Event::ChangeCoreDisplay>(this)
+ , EventHook<Event::NickIdentify>(this)
+ , EventHook<Event::NickGroup>(this)
+ , EventHook<Event::NickUpdate>(this)
+ , EventHook<Event::UserConnect>(this)
+ , EventHook<Event::PostUserLogoff>(this)
+ , EventHook<Event::ServerSync>(this)
+ , EventHook<Event::UserNickChange>(this)
+ , EventHook<Event::UserModeSet>(this)
+ , EventHook<Event::Help>(this)
+ , EventHook<Event::ExpireTick>(this)
+ , EventHook<Event::NickInfo>(this)
+ , EventHook<Event::ModuleUnload>(this)
+ , EventHook<NickServ::Event::NickRegister>(this)
+ , EventHook<Event::UserQuit>(this)
+
+ , held(this, "HELD")
+ , collided(this, "COLLIDED")
+ , nick_type(this)
+ , account_type(this)
+ , mode_type(this)
+ {
+ NickServ::service = this;
+ }
+
+ ~NickServCore()
+ {
+ OnShutdown();
+ NickServ::service = nullptr;
+ }
+
+ void OnShutdown() override
+ {
+ /* On shutdown, restart, or mod unload, remove all of our holds for nicks (svshold or qlines)
+ * because some IRCds do not allow us to have these automatically expire
+ */
+ for (NickServ::Nick *na : nick_type.List<NickServ::Nick *>())
+ this->Release(na);
+ }
+
+ void OnRestart() override
+ {
+ OnShutdown();
+ }
+
+ void Validate(User *u) override
+ {
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (!na)
+ return;
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&NickServ::Event::NickValidate::OnNickValidate, u, na);
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ this->Collide(u, na);
+ return;
+ }
+ else if (MOD_RESULT == EVENT_ALLOW)
+ return;
+
+ if (!na->GetAccount()->HasFieldS("NS_SECURE") && u->IsRecognized())
+ {
+ na->SetLastSeen(Anope::CurTime);
+ na->SetLastUsermask(u->GetIdent() + "@" + u->GetDisplayedHost());
+ na->SetLastRealname(u->realname);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ return;
+
+ bool on_access = u->IsRecognized(false);
+
+ if (on_access || !na->GetAccount()->HasFieldS("KILL_IMMED"))
+ {
+ if (na->GetAccount()->HasFieldS("NS_SECURE"))
+ u->SendMessage(*NickServ, _("This nickname is registered and protected. If this is your nickname, type \002{0}{1} IDENTIFY \037password\037\002. Otherwise, please choose a different nickname."), Config->StrictPrivmsg, NickServ->nick); // XXX
+ else
+ u->SendMessage(*NickServ, _("This nickname is owned by someone else. If this is your nickname, type \002{0}{1} IDENTIFY \037password\037\002. Otherwise, please choose a different nickname."), Config->StrictPrivmsg, NickServ->nick); // XXX
+ }
+ if (na->GetAccount()->HasFieldS("KILLPROTECT") && !on_access)
+ {
+ if (na->GetAccount()->HasFieldS("KILL_IMMED"))
+ {
+ u->SendMessage(*NickServ, _("This nickname has been registered; you may not use it."));
+ this->Collide(u, na);
+ }
+ else if (na->GetAccount()->HasFieldS("KILL_QUICK"))
+ {
+ time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "20s");
+ u->SendMessage(*NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str());
+ new NickServCollide(this, this, u, na, killquick);
+ }
+ else
+ {
+ time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "60s");
+ u->SendMessage(*NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str());
+ new NickServCollide(this, this, u, na, kill);
+ }
+ }
+
+ }
+
+ void OnUserLogin(User *u) override
+ {
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (na && na->GetAccount() == u->Account() && !Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ u->SetMode(NickServ, "REGISTERED");
+
+ const Anope::string &modesonid = Config->GetModule(this)->Get<Anope::string>("modesonid");
+ if (!modesonid.empty())
+ u->SetModes(NickServ, "%s", modesonid.c_str());
+ }
+
+ void Collide(User *u, NickServ::Nick *na) override
+ {
+ if (na)
+ collided.Set(na, true);
+
+ if (IRCD->CanSVSNick)
+ {
+ unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
+ const Anope::string &guestprefix = Config->GetModule("nickserv")->Get<Anope::string>("guestnickprefix", "Guest");
+
+ Anope::string guestnick;
+
+ int i = 0;
+ do
+ {
+ guestnick = guestprefix + stringify(static_cast<uint16_t>(rand()));
+ if (guestnick.length() > nicklen)
+ guestnick = guestnick.substr(0, nicklen);
+ }
+ while (User::Find(guestnick, true) && i++ < 10);
+
+ if (i == 11)
+ u->Kill(*NickServ, "Services nickname-enforcer kill");
+ else
+ {
+ u->SendMessage(*NickServ, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str());
+ IRCD->SendForceNickChange(u, guestnick, Anope::CurTime);
+ }
+ }
+ else
+ u->Kill(*NickServ, "Services nickname-enforcer kill");
+ }
+
+ void Release(NickServ::Nick *na) override
+ {
+ if (held.HasExt(na))
+ {
+ if (IRCD->CanSVSHold)
+ IRCD->SendSVSHoldDel(na->GetNick());
+ else
+ {
+ User *u = User::Find(na->GetNick(), true);
+ if (u && u->server == Me)
+ {
+ u->Quit();
+ }
+ }
+
+ held.Unset(na);
+ }
+ collided.Unset(na); /* clear pending collide */
+ }
+
+ NickServ::IdentifyRequest *CreateIdentifyRequest(NickServ::IdentifyRequestListener *l, Module *o, const Anope::string &acc, const Anope::string &pass) override
+ {
+ return new IdentifyRequestImpl(l, o, acc, pass);
+ }
+
+ std::set<NickServ::IdentifyRequest *>& GetIdentifyRequests() override
+ {
+ return identifyrequests;
+ }
+
+ std::vector<NickServ::Nick *> GetNickList() override
+ {
+ return nick_type.List<NickServ::Nick *>();
+ }
+
+ NickServ::nickalias_map& GetNickMap() override
+ {
+ return NickList;
+ }
+
+ std::vector<NickServ::Account *> GetAccountList() override
+ {
+ return account_type.List<NickServ::Account *>();
+ }
+
+ NickServ::nickcore_map& GetAccountMap() override
+ {
+ return AccountList;
+ }
+
+ NickServ::Nick *FindNick(const Anope::string &nick) override
+ {
+ return nick_type.FindNick(nick);
+ }
+
+ NickServ::Account *FindAccount(const Anope::string &acc) override
+ {
+ return account_type.FindAccount(acc);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &nsnick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (nsnick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(nsnick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + nsnick);
+
+ NickServ = bi;
+
+ spacesepstream(conf->GetModule(this)->Get<Anope::string>("defaults", "ns_secure memo_signon memo_receive")).GetTokens(defaults);
+ if (defaults.empty())
+ {
+ defaults.push_back("NS_SECURE");
+ defaults.push_back("MEMO_SIGNON");
+ defaults.push_back("MEMO_RECEIVE");
+ }
+ else if (defaults[0].equals_ci("none"))
+ defaults.clear();
+ }
+
+ void OnDelNick(NickServ::Nick *na) override
+ {
+ User *u = User::Find(na->GetNick(), true);
+ if (u && u->Account() == na->GetAccount())
+ {
+ IRCD->SendLogout(u);
+ u->RemoveMode(NickServ, "REGISTERED");
+ u->Logout();
+ }
+ }
+
+ void OnDelCore(NickServ::Account *nc) override
+ {
+ Log(NickServ, "nick") << "Deleting nickname group " << nc->GetDisplay();
+
+ /* Clean up this nick core from any users online */
+ for (unsigned int i = nc->users.size(); i > 0; --i)
+ {
+ User *user = nc->users[i - 1];
+ IRCD->SendLogout(user);
+ user->RemoveMode(NickServ, "REGISTERED");
+ user->Logout();
+ EventManager::Get()->Dispatch(&Event::NickLogout::OnNickLogout, user);
+ }
+ }
+
+ void OnChangeCoreDisplay(NickServ::Account *nc, const Anope::string &newdisplay) override
+ {
+ Log(LOG_NORMAL, "nick", NickServ) << "Changing " << nc->GetDisplay() << " nickname group display to " << newdisplay;
+ }
+
+ void OnNickIdentify(User *u) override
+ {
+ Configuration::Block *block = Config->GetModule(this);
+
+ if (block->Get<bool>("modeonid", "yes"))
+
+ for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *cc = it->second;
+ Channel *c = cc->chan;
+ if (c)
+ c->SetCorrectModes(u, true);
+ }
+
+ const Anope::string &modesonid = block->Get<Anope::string>("modesonid");
+ if (!modesonid.empty())
+ u->SetModes(NickServ, "%s", modesonid.c_str());
+
+ if (block->Get<bool>("forceemail", "yes") && u->Account()->GetEmail().empty())
+ {
+ u->SendMessage(*NickServ, _("You must now supply an e-mail for your nick.\n"
+ "This e-mail will allow you to retrieve your password in\n"
+ "case you forget it."));
+ u->SendMessage(*NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n"
+ "Your privacy is respected; this e-mail won't be given to\n"
+ "any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
+ }
+
+ for (std::set<NickServCollide *>::iterator it = collides.begin(); it != collides.end(); ++it)
+ {
+ NickServCollide *c = *it;
+ if (c->GetUser() == u && c->GetNick() && c->GetNick()->GetAccount() == u->Account())
+ {
+ delete c;
+ break;
+ }
+ }
+ }
+
+ void OnNickGroup(User *u, NickServ::Nick *target) override
+ {
+ if (!target->GetAccount()->HasFieldS("UNCONFIRMED"))
+ u->SetMode(NickServ, "REGISTERED");
+ }
+
+ void OnNickUpdate(User *u) override
+ {
+ for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *cc = it->second;
+ Channel *c = cc->chan;
+ if (c)
+ c->SetCorrectModes(u, true);
+ }
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ if (u->Quitting() || !u->server->IsSynced() || u->server->IsULined())
+ return;
+
+ const NickServ::Nick *na = NickServ::FindNick(u->nick);
+
+ const Anope::string &unregistered_notice = Config->GetModule(this)->Get<Anope::string>("unregistered_notice");
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na && !u->Account())
+ u->SendMessage(*NickServ, unregistered_notice.replace_all_cs("%n", u->nick));
+ else if (na && !u->IsIdentified(true))
+ this->Validate(u);
+ }
+
+ void OnPostUserLogoff(User *u) override
+ {
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (na)
+ OnCancel(u, na);
+ }
+
+ void OnServerSync(Server *s) override
+ {
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+
+ if (u->server == s)
+ {
+ if (u->HasMode("REGISTERED") && !u->IsIdentified(true))
+ u->RemoveMode(NickServ, "REGISTERED");
+ if (!u->IsIdentified())
+ this->Validate(u);
+ }
+ }
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &oldnick) override
+ {
+ NickServ::Nick *old_na = NickServ::FindNick(oldnick), *na = NickServ::FindNick(u->nick);
+ /* If the new nick isn't registered or it's registered and not yours */
+ if (!na || na->GetAccount() != u->Account())
+ {
+ /* Remove +r, but keep an account associated with the user */
+ u->RemoveMode(NickServ, "REGISTERED");
+
+ this->Validate(u);
+ }
+ else
+ {
+ /* Reset +r and re-send account (even though it really should be set at this point) */
+ IRCD->SendLogin(u, na);
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && na->GetAccount() == u->Account() && !na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ u->SetMode(NickServ, "REGISTERED");
+ Log(u, "", NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->GetDisplay();
+ }
+
+ if (!u->nick.equals_ci(oldnick) && old_na)
+ OnCancel(u, old_na);
+ }
+
+ void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (u->server->IsSynced() && mname == "REGISTERED" && !u->IsIdentified(true))
+ u->RemoveMode(NickServ, mname);
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *NickServ)
+ return EVENT_CONTINUE;
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ source.Reply(_("\002%s\002 allows you to register a nickname and\n"
+ "prevent others from using it. The following\n"
+ "commands allow for registration and maintenance of\n"
+ "nicknames; to use them, type \002%s%s \037command\037\002.\n"
+ "For more information on a specific command, type\n"
+ "\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
+ else
+ source.Reply(_("\002%s\002 allows you to register an account.\n"
+ "The following commands allow for registration and maintenance of\n"
+ "accounts; to use them, type \002%s%s \037command\037\002.\n"
+ "For more information on a specific command, type\n"
+ "\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *NickServ)
+ return;
+ if (source.IsServicesOper())
+ source.Reply(_(" \n"
+ "Services Operators can also drop any nickname without needing\n"
+ "to identify for the nick, and may view the access list for\n"
+ "any nickname."));
+ time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
+ if (nickserv_expire >= 86400)
+ source.Reply(_(" \n"
+ "Accounts that are not used anymore are subject to\n"
+ "the automatic expiration, i.e. they will be deleted\n"
+ "after %d days if not used."), nickserv_expire / 86400);
+ source.Reply(_(" \n"
+ "\002NOTICE:\002 This service is intended to provide a way for\n"
+ "IRC users to ensure their identity is not compromised.\n"
+ "It is \002NOT\002 intended to facilitate \"stealing\" of\n"
+ "nicknames or other malicious actions. Abuse of %s\n"
+ "will result in, at minimum, loss of the abused\n"
+ "nickname(s)."), NickServ->nick.c_str());
+ }
+
+ void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &) override
+ {
+ /* Set default flags */
+ for (unsigned i = 0; i < defaults.size(); ++i)
+ na->GetAccount()->SetS<bool>(defaults[i].upper(), true);
+ }
+
+ void OnUserQuit(User *u, const Anope::string &msg) override
+ {
+ if (u->server && !u->server->GetQuitReason().empty() && Config->GetModule(this)->Get<bool>("hidenetsplitquit"))
+ return;
+
+ /* Update last quit and last seen for the user */
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+ if (na && !na->GetAccount()->HasFieldS("NS_SUSPENDED") && (u->IsRecognized() || u->IsIdentified(true)))
+ {
+ na->SetLastSeen(Anope::CurTime);
+ na->SetLastQuit(msg);
+ }
+ }
+
+ void OnExpireTick() override
+ {
+ if (Anope::NoExpire || Anope::ReadOnly)
+ return;
+
+ time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
+
+ for (NickServ::Nick *na : nick_type.List<NickServ::Nick *>())
+ {
+ User *u = User::Find(na->GetNick(), true);
+ if (u && (u->IsIdentified(true) || u->IsRecognized()))
+ na->SetLastSeen(Anope::CurTime);
+
+ bool expire = false;
+
+ if (nickserv_expire && Anope::CurTime - na->GetLastSeen() >= nickserv_expire)
+ expire = true;
+
+ EventManager::Get()->Dispatch(&NickServ::Event::PreNickExpire::OnPreNickExpire, na, expire);
+
+ if (expire)
+ {
+ Log(LOG_NORMAL, "nickserv/expire", NickServ) << "Expiring nickname " << na->GetNick() << " (group: " << na->GetAccount()->GetDisplay() << ") (e-mail: " << (na->GetAccount()->GetEmail().empty() ? "none" : na->GetAccount()->GetEmail()) << ")";
+ EventManager::Get()->Dispatch(&NickServ::Event::NickExpire::OnNickExpire, na);
+ delete na;
+ }
+ }
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
+ {
+ if (!na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ {
+ time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
+ if (!na->HasFieldS("NS_NO_EXPIRE") && nickserv_expire && !Anope::NoExpire && (source.HasPriv("nickserv/auspex") || na->GetLastSeen() != Anope::CurTime))
+ info[_("Expires")] = Anope::strftime(na->GetLastSeen() + nickserv_expire, source.GetAccount());
+ }
+ else
+ {
+ time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
+ info[_("Expires")] = Anope::strftime(na->GetTimeRegistered() + unconfirmed_expire, source.GetAccount());
+ }
+ }
+
+ void OnModuleUnload(User *u, Module *m) override
+ {
+ for (std::set<NickServ::IdentifyRequest *>::iterator it = identifyrequests.begin(), it_end = identifyrequests.end(); it != it_end;)
+ {
+ IdentifyRequestImpl *ir = anope_dynamic_static_cast<IdentifyRequestImpl *>(*it);
+ ++it;
+
+ ir->Unload(m);
+ }
+ }
+};
+
+MODULE_INIT(NickServCore)
+
diff --git a/modules/nickserv/main/nicktype.cpp b/modules/nickserv/main/nicktype.cpp
new file mode 100644
index 000000000..465cf2062
--- /dev/null
+++ b/modules/nickserv/main/nicktype.cpp
@@ -0,0 +1,64 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "nicktype.h"
+
+NickType::NickType(Module *me) : Serialize::Type<NickImpl>(me)
+ , nick(this, "nick", &NickImpl::nick)
+ , last_quit(this, "last_quit", &NickImpl::last_quit)
+ , last_realname(this, "last_realname", &NickImpl::last_realname)
+ , last_usermask(this, "last_usermask", &NickImpl::last_usermask)
+ , last_realhost(this, "last_realhost", &NickImpl::last_realhost)
+ , time_registered(this, "time_registered", &NickImpl::time_registered)
+ , last_seen(this, "last_seen", &NickImpl::last_seen)
+ , vhost_ident(this, "vhost_ident", &NickImpl::vhost_ident)
+ , vhost_host(this, "vhost_host", &NickImpl::vhost_host)
+ , vhost_creator(this, "vhost_creator", &NickImpl::vhost_creator)
+ , vhost_created(this, "vhost_created", &NickImpl::vhost_created)
+ , nc(this, "nc", &NickImpl::account)
+{
+
+}
+
+void NickType::Nick::SetField(NickImpl *na, const Anope::string &value)
+{
+ /* Remove us from the aliases list */
+ NickServ::nickalias_map &map = NickServ::service->GetNickMap();
+ map.erase(GetField(na));
+
+ Serialize::Field<NickImpl, Anope::string>::SetField(na, value);
+
+ map[value] = na;
+}
+
+NickServ::Nick *NickType::FindNick(const Anope::string &n)
+{
+ Serialize::ID id;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeFind, this, &this->nick, n, id);
+ if (result == EVENT_ALLOW)
+ return RequireID(id);
+
+ NickServ::nickalias_map &map = NickServ::service->GetNickMap();
+ auto it = map.find(n);
+ if (it != map.end())
+ return it->second;
+ return nullptr;
+}
+
diff --git a/modules/nickserv/main/nicktype.h b/modules/nickserv/main/nicktype.h
new file mode 100644
index 000000000..cd875953a
--- /dev/null
+++ b/modules/nickserv/main/nicktype.h
@@ -0,0 +1,51 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nick.h"
+
+class NickType : public Serialize::Type<NickImpl>
+{
+ public:
+ struct Nick : Serialize::Field<NickImpl, Anope::string>
+ {
+ using Serialize::Field<NickImpl, Anope::string>::Field;
+
+ void SetField(NickImpl *s, const Anope::string &value) override;
+ } nick;
+ Serialize::Field<NickImpl, Anope::string> last_quit;
+ Serialize::Field<NickImpl, Anope::string> last_realname;
+ /* Last usermask this nick was seen on, eg user@host */
+ Serialize::Field<NickImpl, Anope::string> last_usermask;
+ /* Last uncloaked usermask, requires nickserv/auspex to see */
+ Serialize::Field<NickImpl, Anope::string> last_realhost;
+ Serialize::Field<NickImpl, time_t> time_registered;
+ Serialize::Field<NickImpl, time_t> last_seen;
+
+ Serialize::Field<NickImpl, Anope::string> vhost_ident;
+ Serialize::Field<NickImpl, Anope::string> vhost_host;
+ Serialize::Field<NickImpl, Anope::string> vhost_creator;
+ Serialize::Field<NickImpl, time_t> vhost_created;
+
+ /* Account this nick is tied to. Multiple nicks can be tied to a single account. */
+ Serialize::ObjectField<NickImpl, NickServ::Account *> nc;
+
+ NickType(Module *);
+
+ NickServ::Nick *FindNick(const Anope::string &nick);
+};
diff --git a/modules/ns_maxemail.cpp b/modules/nickserv/maxemail.cpp
index a3016311a..0660e7b92 100644
--- a/modules/ns_maxemail.cpp
+++ b/modules/nickserv/maxemail.cpp
@@ -1,20 +1,28 @@
-/* ns_maxemail.cpp - Limit the amount of times an email address
- * can be used for a NickServ account.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Included in the Anope module pack since Anope 1.7.9
- * Anope Coder: GeniusDex <geniusdex@anope.org>
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Please read COPYING and README for further details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
class NSMaxEmail : public Module
+ , public EventHook<Event::PreCommand>
{
- bool clean;
+ bool clean = false;
/* strip dots from username, and remove anything after the first + */
Anope::string CleanMail(const Anope::string &email)
@@ -46,14 +54,14 @@ class NSMaxEmail : public Module
return false;
if (NSEmailMax == 1)
- source.Reply(_("The email address \002%s\002 has reached its usage limit of 1 user."), email.c_str());
+ source.Reply(_("The email address \002{0}\002 has reached its usage limit of \0021\002 user."), email);
else
- source.Reply(_("The email address \002%s\002 has reached its usage limit of %d users."), email.c_str(), NSEmailMax);
+ source.Reply(_("The email address \002{0}\002 has reached its usage limit of \002{1}\002 users."), email, NSEmailMax);
return true;
}
- int CountEmail(const Anope::string &email, NickCore *unc)
+ int CountEmail(const Anope::string &email, NickServ::Account *unc)
{
int count = 0;
@@ -62,13 +70,11 @@ class NSMaxEmail : public Module
Anope::string cleanemail = clean ? CleanMail(email) : email;
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
+ for (NickServ::Account *nc : NickServ::service->GetAccountList())
{
- const NickCore *nc = it->second;
-
- Anope::string cleannc = clean ? CleanMail(nc->email) : nc->email;
+ Anope::string cleannc = clean ? CleanMail(nc->GetEmail()) : nc->GetEmail();
- if (unc != nc && cleanemail == cleannc)
+ if (unc != nc && cleanemail.equals_ci(cleannc))
++count;
}
@@ -77,33 +83,33 @@ class NSMaxEmail : public Module
public:
NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
- , clean(false)
+ , EventHook<Event::PreCommand>(this)
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
clean = conf->GetModule(this)->Get<bool>("remove_aliases", "true");
}
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
{
if (source.IsOper())
return EVENT_CONTINUE;
- if (command->name == "nickserv/register")
+ if (command->GetName() == "nickserv/register")
{
if (this->CheckLimitReached(source, params.size() > 1 ? params[1] : ""))
return EVENT_STOP;
}
- else if (command->name == "nickserv/set/email")
+ else if (command->GetName() == "nickserv/set/email")
{
if (this->CheckLimitReached(source, params.size() > 0 ? params[0] : ""))
return EVENT_STOP;
}
- else if (command->name == "nickserv/ungroup" && source.GetAccount())
+ else if (command->GetName() == "nickserv/ungroup" && source.GetAccount())
{
- if (this->CheckLimitReached(source, source.GetAccount()->email))
+ if (this->CheckLimitReached(source, source.GetAccount()->GetEmail()))
return EVENT_STOP;
}
diff --git a/modules/nickserv/recover.cpp b/modules/nickserv/recover.cpp
new file mode 100644
index 000000000..287965373
--- /dev/null
+++ b/modules/nickserv/recover.cpp
@@ -0,0 +1,307 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/cert.h"
+#include "modules/nickserv.h"
+
+typedef std::map<Anope::string, ChannelStatus> NSRecoverInfo;
+
+class NSRecoverSvsnick
+{
+ public:
+ Reference<User> from;
+ Anope::string to;
+};
+
+class NSRecoverRequestListener : public NickServ::IdentifyRequestListener
+{
+ CommandSource source;
+ Command *cmd;
+ Anope::string user;
+ Anope::string pass;
+
+ public:
+ NSRecoverRequestListener(CommandSource &src, Command *c, const Anope::string &nick, const Anope::string &p) : source(src), cmd(c), user(nick), pass(p) { }
+
+ void OnSuccess(NickServ::IdentifyRequest *) override
+ {
+ User *u = User::Find(user, true);
+ if (!source.GetUser() || !source.service)
+ return;
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ return;
+
+ Log(LOG_COMMAND, source, cmd) << "for " << na->GetNick();
+
+ /* Nick is being held by us, release it */
+ if (na->HasFieldS("HELD"))
+ {
+ NickServ::service->Release(na);
+ source.Reply(_("Service's hold on \002{0}\002 has been released."), na->GetNick());
+ }
+ else if (!u)
+ {
+ source.Reply(_("No one is using your nick, and services are not holding it."));
+ }
+ // If the user being recovered is identified for the account of the nick then the user is the
+ // same person that is executing the command, so kill them off (old GHOST command).
+ else if (u->Account() == na->GetAccount())
+ {
+ if (!source.GetAccount() && na->GetAccount()->HasFieldS("NS_SECURE"))
+ {
+ source.GetUser()->Login(u->Account());
+ Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->GetDisplay();
+ }
+
+ if (Config->GetModule("ns_recover")->Get<bool>("restoreonrecover"))
+ {
+ if (!u->chans.empty())
+ {
+ NSRecoverInfo i;
+ for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
+ i[it->first->name] = it->second->status;
+ source.GetUser()->Extend<NSRecoverInfo>("recover", i);
+ }
+ }
+
+ u->SendMessage(*source.service, _("This nickname has been recovered by \002{0}\002. If you did not do this, then \002{0}\002 may have your password, and you should change it."),
+ source.GetNick());
+
+ Anope::string buf = source.command.upper() + " command used by " + source.GetNick();
+ u->Kill(*source.service, buf);
+
+ source.Reply(_("Ghost with your nick has been killed."));
+
+ if (IRCD->CanSVSNick)
+ IRCD->SendForceNickChange(source.GetUser(), user, Anope::CurTime);
+ }
+ /* User is not identified or not identified to the same account as the person using this command */
+ else
+ {
+ if (!source.GetAccount() && na->GetAccount()->HasFieldS("NS_SECURE"))
+ {
+ source.GetUser()->Login(na->GetAccount()); // Identify the user using the command if they arent identified
+ Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->GetNick() << " (" << na->GetAccount()->GetDisplay() << ")";
+ source.Reply(_("You have been logged in as \002{0}\002."), na->GetAccount()->GetDisplay());
+ }
+
+ u->SendMessage(*source.service, _("This nickname has been recovered by \002{0}\002."), source.GetNick());
+
+ if (IRCD->CanSVSNick)
+ {
+ NSRecoverSvsnick svs;
+
+ svs.from = source.GetUser();
+ svs.to = u->nick;
+
+ u->Extend<NSRecoverSvsnick>("svsnick", svs);
+ }
+
+ if (NickServ::service)
+ NickServ::service->Collide(u, na);
+
+ if (IRCD->CanSVSNick)
+ {
+ /* If we can svsnick then release our hold and svsnick the user using the command */
+ if (NickServ::service)
+ NickServ::service->Release(na);
+
+ source.Reply(_("You have regained control of \002{0}\002."), u->nick);
+ }
+ else
+ source.Reply(_("The user with your nick has been removed. Use this command again to release services's hold on your nick."));
+ }
+ }
+
+ void OnFail(NickServ::IdentifyRequest *) override
+ {
+ if (NickServ::FindNick(user) != NULL)
+ {
+ source.Reply(_("Access denied."));
+ if (!pass.empty())
+ {
+ Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << user;
+ if (source.GetUser())
+ source.GetUser()->BadPassword();
+ }
+ }
+ else
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ }
+};
+
+class CommandNSRecover : public Command
+{
+ ServiceReference<CertService> certservice;
+
+ public:
+ CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2)
+ {
+ this->SetDesc(_("Regains control of your nick"));
+ this->SetSyntax(_("\037nickname\037 [\037password\037]"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &nick = params[0];
+ const Anope::string &pass = params.size() > 1 ? params[1] : "";
+
+ User *user = User::Find(nick, true);
+
+ if (user && source.GetUser() == user)
+ {
+ source.Reply(_("You can't %s yourself!"), source.command.lower().c_str());
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ if (na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ {
+ source.Reply(_("\002{0}\002 is suspended."), na->GetNick());
+ return;
+ }
+
+ bool ok = false;
+ if (source.GetAccount() == na->GetAccount())
+ ok = true;
+ else if (!na->GetAccount()->HasFieldS("NS_SECURE") && source.GetUser() && na->GetAccount()->IsOnAccess(source.GetUser()))
+ ok = true;
+
+ if (certservice && source.GetUser() && certservice->Matches(source.GetUser(), na->GetAccount()))
+ ok = true;
+
+ if (ok == false && !pass.empty())
+ {
+ NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new NSRecoverRequestListener(source, this, na->GetNick(), pass), GetOwner(), na->GetNick(), pass);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, source.GetUser(), req);
+ req->Dispatch();
+ }
+ else
+ {
+ NSRecoverRequestListener req(source, this, na->GetNick(), pass);
+
+ if (ok)
+ req.OnSuccess(nullptr);
+ else
+ req.OnFail(nullptr);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Recovers your nickname from another user or from services."
+ "If services are currently holding your nickname, the hold will be released."
+ " If another user is holding your nickname and is identified they will be killed."
+ " If they are not identified they will be forced off of the nickname."));
+ return true;
+ }
+};
+
+class NSRecover : public Module
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::JoinChannel>
+{
+ CommandNSRecover commandnsrecover;
+ ExtensibleItem<NSRecoverInfo> recover;
+ ExtensibleItem<NSRecoverSvsnick> svsnick;
+
+ public:
+ NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserNickChange>(this)
+ , EventHook<Event::JoinChannel>(this)
+ , commandnsrecover(this)
+ , recover(this, "recover")
+ , svsnick(this, "svsnick")
+ {
+
+ if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
+
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &oldnick) override
+ {
+ if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
+ {
+ NSRecoverInfo *ei = recover.Get(u);
+ ServiceBot *NickServ = Config->GetClient("NickServ");
+
+ if (ei != NULL && NickServ != NULL)
+ for (NSRecoverInfo::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
+ {
+ Channel *c = Channel::Find(it->first);
+ const Anope::string &cname = it->first;
+ ++it;
+
+ /* User might already be on the channel */
+ if (u->FindChannel(c))
+ this->OnJoinChannel(u, c);
+ else if (IRCD->CanSVSJoin)
+ IRCD->SendSVSJoin(NickServ, u, cname, "");
+ }
+ }
+
+ NSRecoverSvsnick *svs = svsnick.Get(u);
+ if (svs)
+ {
+ if (svs->from)
+ {
+ // svsnick from to to
+ IRCD->SendForceNickChange(svs->from, svs->to, Anope::CurTime);
+ }
+
+ svsnick.Unset(u);
+ }
+ }
+
+ void OnJoinChannel(User *u, Channel *c) override
+ {
+ if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
+ {
+ NSRecoverInfo *ei = recover.Get(u);
+
+ if (ei != NULL)
+ {
+ NSRecoverInfo::iterator it = ei->find(c->name);
+ if (it != ei->end())
+ {
+ for (size_t i = 0; i < it->second.Modes().length(); ++i)
+ c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(it->second.Modes()[i]), u->GetUID());
+
+ ei->erase(it);
+ if (ei->empty())
+ recover.Unset(u);
+ }
+ }
+ }
+ }
+};
+
+MODULE_INIT(NSRecover)
diff --git a/modules/nickserv/register.cpp b/modules/nickserv/register.cpp
new file mode 100644
index 000000000..02da01f5d
--- /dev/null
+++ b/modules/nickserv/register.cpp
@@ -0,0 +1,445 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv.h"
+
+static bool SendRegmail(User *u, NickServ::Nick *na, ServiceBot *bi);
+
+class CommandNSConfirm : public Command
+{
+ public:
+ CommandNSConfirm(Module *creator) : Command(creator, "nickserv/confirm", 1, 2)
+ {
+ this->SetDesc(_("Confirm a passcode"));
+ this->SetSyntax(_("\037passcode\037"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &passcode = params[0];
+
+ if (source.nc && !source.nc->HasFieldS("UNCONFIRMED") && source.HasPriv("nickserv/confirm"))
+ {
+ NickServ::Nick *na = NickServ::FindNick(passcode);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), passcode);
+ return;
+ }
+
+ if (na->GetAccount()->HasFieldS("UNCONFIRMED") == false)
+ {
+ source.Reply(_("\002{0}\002 is already confirmed."), na->GetNick());
+ return;
+ }
+
+ na->GetAccount()->UnsetS<bool>("UNCONFIRMED");
+ EventManager::Get()->Dispatch(&NickServ::Event::NickConfirm::OnNickConfirm, source.GetUser(), na->GetAccount());
+ Log(LOG_ADMIN, source, this) << "to confirm nick " << na->GetNick() << " (" << na->GetAccount()->GetDisplay() << ")";
+ source.Reply(_("\002{0}\002 has been confirmed."), na->GetNick());
+
+ /* Login the users online already */
+ for (User *u : na->GetAccount()->users)
+ {
+ IRCD->SendLogin(u, na);
+
+ NickServ::Nick *u_na = NickServ::FindNick(u->nick);
+
+ /* Set +r if they're on a nick in the group */
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && u_na && u_na->GetAccount() == na->GetAccount())
+ u->SetMode(source.service, "REGISTERED");
+ }
+ }
+ else if (source.nc)
+ {
+ Anope::string *code = source.nc->GetExt<Anope::string>("passcode");
+ if (code == nullptr || *code != passcode)
+ {
+ source.Reply(_("Invalid passcode."));
+ return;
+ }
+
+ NickServ::Account *nc = source.nc;
+ nc->Shrink<Anope::string>("passcode");
+ Log(LOG_COMMAND, source, this) << "to confirm their email";
+ source.Reply(_("Your email address of \002{0}\002 has been confirmed."), source.nc->GetEmail());
+ nc->UnsetS<bool>("UNCONFIRMED");
+
+ EventManager::Get()->Dispatch(&NickServ::Event::NickConfirm::OnNickConfirm, source.GetUser(), nc);
+
+ if (source.GetUser())
+ {
+ NickServ::Nick *na = NickServ::FindNick(source.GetNick());
+ if (na)
+ {
+ IRCD->SendLogin(source.GetUser(), na);
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && na->GetAccount() == source.GetAccount() && !na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ source.GetUser()->SetMode(source.service, "REGISTERED");
+ }
+ }
+ }
+ else
+ source.Reply(_("Invalid passcode."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command is used by several commands as a way to confirm changes made to your account.\n"
+ "\n"
+ "This is most commonly used to confirm your email address once you register or change it.\n"
+ "\n"
+ "This is also used after when resetting your password to force identify you to your account so you may change your password."));
+ if (source.HasPriv("nickserv/confirm"))
+ source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n"
+ "replace \037passcode\037 with a users nick to force validate them."));
+ return true;
+ }
+};
+
+class CommandNSRegister : public Command
+{
+ public:
+ CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2)
+ {
+ this->SetDesc(_("Register a nickname"));
+ if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
+ this->SetSyntax(_("\037password\037 \037email\037"));
+ else
+ this->SetSyntax(_("\037password\037 \037[email]\037"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+ Anope::string u_nick = source.GetNick();
+ size_t nicklen = u_nick.length();
+ Anope::string pass = params[0];
+ Anope::string email = params.size() > 1 ? params[1] : "";
+ const Anope::string &nsregister = Config->GetModule(this->GetOwner())->Get<Anope::string>("registration");
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Sorry, nickname registration is temporarily disabled."));
+ return;
+ }
+
+ if (nsregister.equals_ci("disable"))
+ {
+ source.Reply(_("Registration is currently disabled."));
+ return;
+ }
+
+ time_t nickregdelay = Config->GetModule(this->GetOwner())->Get<time_t>("nickregdelay");
+ time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
+ if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay)
+ {
+ source.Reply(_("You must have been using this nickname for at least {0} seconds to register."), nickregdelay);
+ return;
+ }
+
+ /* Prevent "Guest" nicks from being registered. -TheShadow */
+
+ /* Guest nick can now have a series of between 1 and 7 digits.
+ * --lara
+ */
+ const Anope::string &guestnick = Config->GetModule("nickserv")->Get<Anope::string>("guestnickprefix", "Guest");
+ if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u_nick);
+ return;
+ }
+
+ if (!IRCD->IsNickValid(u_nick))
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u_nick);
+ return;
+ }
+
+ if (ServiceBot::Find(u_nick, true))
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u_nick);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ {
+ if (!source.IsOper() && u_nick.find_ci(o->GetName()) != Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 may not be registered because it is too similar to an operator nick."), u_nick);
+ return;
+ }
+ }
+
+ unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
+
+ if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty())
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ if (u && Anope::CurTime < u->lastnickreg + reg_delay)
+ {
+ source.Reply(_("Please wait \002{0}\002 seconds before using the {1} command again."), (u->lastnickreg + reg_delay) - Anope::CurTime, source.command);
+ return;
+ }
+
+ if (NickServ::FindNick(u_nick) != NULL)
+ {
+ source.Reply(_("\002{0}\002 is already registered."), u_nick);
+ return;
+ }
+
+ if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5))
+ {
+ source.Reply(_("Please try again with a more obscure password. Passwords should be at least five characters long, should not be something easily guessed"
+ " (e.g. your real name or your nickname), and cannot contain the space or tab characters."));
+ return;
+ }
+
+ if (pass.length() > Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"))
+ {
+ source.Reply(_("Your password is too long, it can not contain more than \002{0}\002 characters."), Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"));
+ return;
+ }
+
+ if (!email.empty() && !Mail::Validate(email))
+ {
+ source.Reply(_("\002{0}\002 is not a valid e-mail address."), email);
+ return;
+ }
+
+ NickServ::Account *nc = Serialize::New<NickServ::Account *>();
+ nc->SetDisplay(u_nick);
+
+ NickServ::Nick *na = Serialize::New<NickServ::Nick *>();
+ na->SetNick(u_nick);
+ na->SetAccount(nc);
+ na->SetTimeRegistered(Anope::CurTime);
+ na->SetLastSeen(Anope::CurTime);
+
+ Anope::string epass;
+ Anope::Encrypt(pass, epass);
+ nc->SetPassword(epass);
+ if (!email.empty())
+ nc->SetEmail(email);
+
+ if (u)
+ {
+ na->SetLastUsermask(u->GetIdent() + "@" + u->GetDisplayedHost());
+ na->SetLastRealname(u->realname);
+ }
+ else
+ na->SetLastRealname(source.GetNick());
+
+ Log(LOG_COMMAND, source, this) << "to register " << na->GetNick() << " (email: " << (!na->GetAccount()->GetEmail().empty() ? na->GetAccount()->GetEmail() : "none") << ")";
+
+ source.Reply(_("\002{0}\002 has been registered."), u_nick);
+
+ if (nsregister.equals_ci("admin"))
+ {
+ nc->SetS<bool>("UNCONFIRMED", true);
+ // User::Identify() called below will notify the user that their registration is pending
+ }
+ else if (nsregister.equals_ci("mail"))
+ {
+ if (!email.empty())
+ {
+ nc->SetS<bool>("UNCONFIRMED", true);
+ SendRegmail(NULL, na, source.service);
+ }
+ }
+
+ EventManager::Get()->Dispatch(&NickServ::Event::NickRegister::OnNickRegister, source.GetUser(), na, pass);
+
+ if (u)
+ {
+ u->Identify(na);
+ u->lastnickreg = Anope::CurTime;
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Registers your nickname. Once your nickname is registered, you will be able to use most features of services, including owning and managing channels."
+ "Make sure you remember the password - you'll need it to identify yourself later. Your email address will only be used if you forget your password."));
+
+ if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
+ {
+ source.Reply(" ");
+ source.Reply(_("The \037email\037 parameter is optional and will set the email\n"
+ "for your nick immediately.\n"
+ "Your privacy is respected; this e-mail won't be given to\n"
+ "any third-party person. You may also wish to \002SET HIDE\002 it\n"
+ "after registering if it isn't the default setting already."));
+ }
+
+ if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ {
+ source.Reply(" ");
+ source.Reply(_("This command also creates a new group for your nickname, which will allow you to group other nicknames later, which share the same configuration, the same set of memos and the same channel privileges."));
+ }
+ return true;
+ }
+};
+
+class CommandNSResend : public Command
+{
+ public:
+ CommandNSResend(Module *creator) : Command(creator, "nickserv/resend", 0, 0)
+ {
+ this->SetDesc(_("Resend registration confirmation email"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!Config->GetModule(this->GetOwner())->Get<Anope::string>("registration").equals_ci("mail"))
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(source.GetNick());
+
+ if (na == NULL)
+ {
+ source.Reply(_("Your nickname isn't registered."));
+ return;
+ }
+
+ if (na->GetAccount() != source.GetAccount() || !source.nc->HasFieldS("UNCONFIRMED"))
+ {
+ source.Reply(_("Your account is already confirmed."));
+ return;
+ }
+
+ if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->GetOwner())->Get<time_t>("resenddelay"))
+ {
+ source.Reply(_("Cannot send mail now; please retry a little later."));
+ return;
+ }
+
+ if (!SendRegmail(source.GetUser(), na, source.service))
+ {
+ Log(this->GetOwner()) << "Unable to resend registration verification code for " << source.GetNick();
+ return;
+ }
+
+ na->GetAccount()->lastmail = Anope::CurTime;
+ source.Reply(_("Your passcode has been re-sent to \002{0}\002."), na->GetAccount()->GetEmail());
+ Log(LOG_COMMAND, source, this) << "to resend registration verification code";
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (!Config->GetModule(this->GetOwner())->Get<Anope::string>("registration").equals_ci("mail"))
+ return false;
+
+ source.Reply(_("This command will resend you the registration confirmation email."));
+ return true;
+ }
+
+ void OnServHelp(CommandSource &source) override
+ {
+ if (Config->GetModule(this->GetOwner())->Get<Anope::string>("registration").equals_ci("mail"))
+ Command::OnServHelp(source);
+ }
+};
+
+class NSRegister : public Module
+ , public EventHook<Event::NickIdentify>
+ , public EventHook<NickServ::Event::PreNickExpire>
+{
+ CommandNSRegister commandnsregister;
+ CommandNSConfirm commandnsconfirm;
+ CommandNSResend commandnsrsend;
+
+ Serialize::Field<NickServ::Account, bool> unconfirmed;
+ Serialize::Field<NickServ::Account, Anope::string> passcode;
+
+ public:
+ NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::NickIdentify>(this)
+ , EventHook<NickServ::Event::PreNickExpire>(this)
+ , commandnsregister(this)
+ , commandnsconfirm(this)
+ , commandnsrsend(this)
+ , unconfirmed(this, "UNCONFIRMED")
+ , passcode(this, "passcode")
+ {
+ if (Config->GetModule(this)->Get<Anope::string>("registration").equals_ci("disable"))
+ throw ModuleException("Module " + Module::name + " will not load with registration disabled.");
+ }
+
+ void OnNickIdentify(User *u) override
+ {
+ ServiceBot *NickServ;
+ if (unconfirmed.HasExt(u->Account()) && (NickServ = Config->GetClient("NickServ")))
+ {
+ const Anope::string &nsregister = Config->GetModule(this)->Get<Anope::string>("registration");
+ if (nsregister.equals_ci("admin"))
+ u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
+ else
+ u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you."));
+ NickServ::Nick *this_na = NickServ::FindNick(u->Account()->GetDisplay());
+ time_t time_registered = Anope::CurTime - this_na->GetTimeRegistered();
+ time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
+ if (unconfirmed_expire > time_registered)
+ u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s."), Anope::Duration(unconfirmed_expire - time_registered, u->Account()).c_str());
+ }
+ }
+
+ void OnPreNickExpire(NickServ::Nick *na, bool &expire) override
+ {
+ if (unconfirmed.HasExt(na->GetAccount()))
+ {
+ time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
+ if (unconfirmed_expire && Anope::CurTime - na->GetTimeRegistered() >= unconfirmed_expire)
+ expire = true;
+ }
+ }
+};
+
+static bool SendRegmail(User *u, NickServ::Nick *na, ServiceBot *bi)
+{
+ NickServ::Account *nc = na->GetAccount();
+
+ Anope::string *code = na->GetAccount()->GetExt<Anope::string>("passcode");
+ if (code == NULL)
+ code = na->GetAccount()->Extend<Anope::string>("passcode", Anope::Random(9));
+
+ Anope::string subject = Language::Translate(na->GetAccount(), Config->GetBlock("mail")->Get<Anope::string>("registration_subject").c_str()),
+ message = Language::Translate(na->GetAccount(), Config->GetBlock("mail")->Get<Anope::string>("registration_message").c_str());
+
+ subject = subject.replace_all_cs("%n", na->GetNick());
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ subject = subject.replace_all_cs("%c", *code);
+
+ message = message.replace_all_cs("%n", na->GetNick());
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ message = message.replace_all_cs("%c", *code);
+
+ return Mail::Send(u, nc, bi, subject, message);
+}
+
+MODULE_INIT(NSRegister)
diff --git a/modules/nickserv/resetpass.cpp b/modules/nickserv/resetpass.cpp
new file mode 100644
index 000000000..2a70a6ebd
--- /dev/null
+++ b/modules/nickserv/resetpass.cpp
@@ -0,0 +1,150 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+static bool SendResetEmail(User *u, NickServ::Nick *na, ServiceBot *bi);
+
+class CommandNSResetPass : public Command
+{
+ public:
+ CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 2, 2)
+ {
+ this->SetDesc(_("Helps you reset lost passwords"));
+ this->SetSyntax(_("\037account\037 \037email\037"));
+ this->AllowUnregistered(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ NickServ::Nick *na = NickServ::FindNick(params[0]);
+
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+
+ if (!na->GetAccount()->GetEmail().equals_ci(params[1]))
+ {
+ source.Reply(_("Incorrect email address."));
+ return;
+ }
+
+ if (SendResetEmail(source.GetUser(), na, source.service))
+ {
+ Log(LOG_COMMAND, source, this) << "for " << na->GetNick() << " (group: " << na->GetAccount()->GetDisplay() << ")";
+ source.Reply(_("Password reset email for \002{0}\002 has been sent."), na->GetNick());
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sends a passcode to the email address of \037account\037 with instructions on how to reset their password. \037email\037 must be the email address associated to \037account\037."));
+ return true;
+ }
+};
+
+struct ResetInfo
+{
+ Anope::string code;
+ time_t time;
+};
+
+class NSResetPass : public Module
+ , public EventHook<Event::PreCommand>
+{
+ CommandNSResetPass commandnsresetpass;
+ ExtensibleItem<ResetInfo> reset;
+
+ public:
+ NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::PreCommand>(this)
+ , commandnsresetpass(this), reset(this, "reset")
+ {
+ if (!Config->GetBlock("mail")->Get<bool>("usemail"))
+ throw ModuleException("Not using mail.");
+ }
+
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
+ {
+ if (command->GetName() == "nickserv/confirm" && params.size() > 1)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return EVENT_STOP;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(params[0]);
+
+ ResetInfo *ri = na ? reset.Get(na->GetAccount()) : NULL;
+ if (na && ri)
+ {
+ NickServ::Account *nc = na->GetAccount();
+ const Anope::string &passcode = params[1];
+ if (ri->time < Anope::CurTime - 3600)
+ {
+ reset.Unset(nc);
+ source.Reply(_("Your password reset request has expired."));
+ }
+ else if (passcode.equals_cs(ri->code))
+ {
+ reset.Unset(nc);
+ nc->UnsetS<bool>("UNCONFIRMED");
+
+ Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->GetNick();
+
+ if (source.GetUser())
+ {
+ source.GetUser()->Identify(na);
+ source.Reply(_("You are now identified for \002{0}\002. Change your password now."), na->GetAccount()->GetDisplay());
+ }
+ }
+ else
+ return EVENT_CONTINUE;
+
+ return EVENT_STOP;
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+static bool SendResetEmail(User *u, NickServ::Nick *na, ServiceBot *bi)
+{
+ Anope::string subject = Language::Translate(na->GetAccount(), Config->GetBlock("mail")->Get<Anope::string>("reset_subject").c_str()),
+ message = Language::Translate(na->GetAccount(), Config->GetBlock("mail")->Get<Anope::string>("reset_message").c_str()),
+ passcode = Anope::Random(20);
+
+ subject = subject.replace_all_cs("%n", na->GetNick());
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ subject = subject.replace_all_cs("%c", passcode);
+
+ message = message.replace_all_cs("%n", na->GetNick());
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ message = message.replace_all_cs("%c", passcode);
+
+ na->GetAccount()->Extend<ResetInfo>("reset", ResetInfo{passcode, Anope::CurTime});
+
+ return Mail::Send(u, na->GetAccount(), bi, subject, message);
+}
+
+MODULE_INIT(NSResetPass)
diff --git a/modules/nickserv/set.cpp b/modules/nickserv/set.cpp
new file mode 100644
index 000000000..bb6557f4b
--- /dev/null
+++ b/modules/nickserv/set.cpp
@@ -0,0 +1,1261 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv/set.h"
+#include "modules/nickserv.h"
+
+class CommandNSSet : public Command
+{
+ public:
+ CommandNSSet(Module *creator) : Command(creator, "nickserv/set", 1, 3)
+ {
+ this->SetDesc(_("Set options, including kill protection"));
+ this->SetSyntax(_("\037option\037 \037parameters\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets various options on your account\n"
+ "\n"
+ "Available options:"));
+
+ Anope::string this_name = source.command;
+ bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
+ hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
+ for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
+ {
+ const Anope::string &c_name = it->first;
+ const CommandInfo &info = it->second;
+
+ if (c_name.find_ci(this_name + " ") == 0)
+ {
+ ServiceReference<Command> c(info.name);
+ // XXX dup
+ if (!c)
+ continue;
+ else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
+ continue;
+ else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
+ continue;
+
+ source.command = c_name;
+ c->OnServHelp(source);
+ }
+ }
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("Type \002{0}{1} {2} {3} \037option\037\002 for more information on a particular option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, this_name);
+
+ return true;
+ }
+};
+
+class CommandNSSASet : public Command
+{
+ public:
+ CommandNSSASet(Module *creator) : Command(creator, "nickserv/saset", 2, 4)
+ {
+ this->SetDesc(_("Set SET-options on another nickname"));
+ this->SetSyntax(_("\037option\037 \037nickname\037 \037parameters\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Sets various options on other users accounts\n"
+ "\n"
+ "Available options:"));
+
+ Anope::string this_name = source.command;
+ for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
+ {
+ const Anope::string &c_name = it->first;
+ const CommandInfo &info = it->second;
+
+ if (c_name.find_ci(this_name + " ") == 0)
+ {
+ ServiceReference<Command> command(info.name);
+ if (command)
+ {
+ source.command = c_name;
+ command->OnServHelp(source);
+ }
+ }
+ }
+
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ if (help)
+ source.Reply(_("Type \002{0}{1} {2} {3} \037option\037\002 for more information on a particular option."),
+ Config->StrictPrivmsg, source.service->nick, help->cname, this_name);
+
+ return true;
+ }
+};
+
+class CommandNSSetPassword : public Command
+{
+ public:
+ CommandNSSetPassword(Module *creator) : Command(creator, "nickserv/set/password", 1)
+ {
+ this->SetDesc(_("Changes your password"));
+ this->SetSyntax(_("\037new-password\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &param = params[0];
+ unsigned len = param.length();
+
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
+ {
+ source.Reply(_("Please try again with a more obscure password. Passwords should be at least five characters long, should not be something easily guessed (e.g. your real name or your nick), and cannot contain the space or tab characters."));
+ return;
+ }
+
+ if (len > Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"))
+ {
+ source.Reply(_("Your password is too long, it can not contain more than \002{0}\002 characters."), Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"));
+ return;
+ }
+
+ Log(LOG_COMMAND, source, this) << "to change their password";
+
+ Anope::string tmp_pass;
+ Anope::Encrypt(param, tmp_pass);
+ source.nc->SetPassword(tmp_pass);
+
+ source.Reply(_("Password for \002{0}\002 changed."), source.nc->GetDisplay());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes your password to \037new-password\037."));
+ return true;
+ }
+};
+
+class CommandNSSASetPassword : public Command
+{
+ public:
+ CommandNSSASetPassword(Module *creator) : Command(creator, "nickserv/saset/password", 2, 2)
+ {
+ this->SetDesc(_("Changes the password of another user"));
+ this->SetSyntax(_("\037account\037 \037new-password\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *setter_na = NickServ::FindNick(params[0]);
+ if (setter_na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), params[0]);
+ return;
+ }
+ NickServ::Account *nc = setter_na->GetAccount();
+
+ size_t len = params[1].length();
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
+ {
+ source.Reply(_("You may not change the password of other Services Operators."));
+ return;
+ }
+
+ if (nc->GetDisplay().equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
+ {
+ source.Reply(_("Please try again with a more obscure password. Passwords should be at least five characters long, should not be something easily guessed (e.g. your real name or your nick), and cannot contain the space or tab characters."));
+ return;
+ }
+
+ if (len > Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"))
+ {
+ source.Reply(_("Your password is too long, it can not contain more than \002{0}\002 characters."), Config->GetModule("nickserv")->Get<unsigned>("passlen", "32"));
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "to change the password of " << nc->GetDisplay();
+
+ Anope::string tmp_pass;
+ Anope::Encrypt(params[1], tmp_pass);
+ nc->SetPassword(tmp_pass);
+ source.Reply(_("Password for \002{0}\002 changed."), nc->GetDisplay());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the password of \037account\037 to \037new-password\037."));
+ return true;
+ }
+};
+
+class CommandNSSetAutoOp : public Command
+{
+ public:
+ CommandNSSetAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Sets whether services should set channel status modes on you automatically."));
+ this->SetSyntax("{ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autoop for " << na->GetAccount()->GetDisplay();
+ nc->SetS<bool>("AUTOOP", true);
+ source.Reply(_("Services will from now on set status modes on \002{0}\002 in channels."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autoop for " << na->GetAccount()->GetDisplay();
+ nc->UnsetS<bool>("AUTOOP");
+ source.Reply(_("Services will no longer set status modes on \002{0}\002 in channels."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "AUTOOP");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets whether you will be given your channel status modes automatically when you join a channel."
+ " Note that depending on channel settings some modes may not get set automatically."));
+ return true;
+ }
+};
+
+class CommandNSSASetAutoOp : public CommandNSSetAutoOp
+{
+ public:
+ CommandNSSASetAutoOp(Module *creator) : CommandNSSetAutoOp(creator, "nickserv/saset/autoop", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets whether the given nickname will be given their status modes automatically when they join a channel."
+ " Note that depending on channel settings some modes may not get set automatically."));
+ return true;
+ }
+};
+
+class CommandNSSetDisplay : public Command
+{
+ public:
+ CommandNSSetDisplay(Module *creator, const Anope::string &sname = "nickserv/set/display", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Set the display of your group in Services"));
+ this->SetSyntax(_("\037new-display\037"));
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *user_na = NickServ::FindNick(user), *na = NickServ::FindNick(param);
+
+ if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ {
+ source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
+ return;
+ }
+
+ if (user_na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+
+ if (!na || na->GetAccount() != user_na->GetAccount())
+ {
+ source.Reply(_("The new display must be a nickname of the nickname group \002{0}\02."), user_na->GetAccount()->GetDisplay());
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, user_na->GetAccount(), param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ Log(user_na->GetAccount() == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the display of " << user_na->GetAccount()->GetDisplay() << " to " << na->GetNick();
+
+ user_na->GetAccount()->SetDisplay(na);
+
+ for (User *u : user_na->GetAccount()->users)
+ {
+ IRCD->SendLogin(u, user_na);
+ }
+
+ source.Reply(_("The new display is now \002{0}\002."), user_na->GetAccount()->GetDisplay());
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the display used to refer to your nickname group in services. The new display nickname must be a nickname of your group."));
+ return true;
+ }
+};
+
+class CommandNSSASetDisplay : public CommandNSSetDisplay
+{
+ public:
+ CommandNSSASetDisplay(Module *creator) : CommandNSSetDisplay(creator, "nickserv/saset/display", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 \037new-display\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the display used to refer to the nickname group \037account\037 in services. The new display nickname must be a nickname in the group of \037account\037."));
+ return true;
+ }
+};
+
+class CommandNSSetEmail : public Command
+{
+ static bool SendConfirmMail(User *u, ServiceBot *bi, const Anope::string &new_email)
+ {
+ Anope::string code = Anope::Random(9);
+
+ u->Account()->Extend<std::pair<Anope::string, Anope::string> >("ns_set_email", std::make_pair(new_email, code));
+
+ Anope::string subject = Config->GetBlock("mail")->Get<Anope::string>("emailchange_subject"),
+ message = Config->GetBlock("mail")->Get<Anope::string>("emailchange_message");
+
+ subject = subject.replace_all_cs("%e", u->Account()->GetEmail());
+ subject = subject.replace_all_cs("%E", new_email);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ subject = subject.replace_all_cs("%c", code);
+
+ message = message.replace_all_cs("%e", u->Account()->GetEmail());
+ message = message.replace_all_cs("%E", new_email);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
+ message = message.replace_all_cs("%c", code);
+
+ Anope::string old = u->Account()->GetEmail();
+ u->Account()->SetEmail(new_email);
+ bool b = Mail::Send(u, u->Account(), bi, subject, message);
+ u->Account()->SetEmail(old);
+ return b;
+ }
+
+ public:
+ CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1)
+ {
+ this->SetDesc(_("Associate an E-mail address with your nickname"));
+ this->SetSyntax(_("\037address\037"));
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ if (nc->HasFieldS("UNCONFIRMED"))
+ {
+ source.Reply(_("You may not change the email of an unconfirmed account."));
+ return;
+ }
+
+ if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
+ {
+ source.Reply(_("You cannot unset the e-mail on this network."));
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
+ {
+ source.Reply(_("You may not change the e-mail of other Services Operators."));
+ return;
+ }
+
+ if (!param.empty() && !Mail::Validate(param))
+ {
+ source.Reply(_("\002{0}\002 is not a valid e-mail address."), param);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.empty())
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the email of " << nc->GetDisplay();
+ nc->SetEmail("");
+ source.Reply(_("E-mail address for \002{0}\002 unset."), nc->GetDisplay());
+ }
+ else if (Config->GetModule("nickserv")->Get<bool>("confirmemailchanges") && !source.IsServicesOper())
+ {
+ if (SendConfirmMail(source.GetUser(), source.service, param))
+ source.Reply(_("A confirmation e-mail has been sent to \002{0}\002. Follow the instructions in it to change your e-mail address."), param);
+ }
+ else
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the email of " << nc->GetDisplay() << " to " << param;
+ nc->SetEmail(param);
+ source.Reply(_("E-mail address for \002{0}\002 changed to \002{1}\002."), nc->GetDisplay(), param);
+ }
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params.size() ? params[0] : "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes your email address to \037address\037."));
+ return true;
+ }
+};
+
+class CommandNSSASetEmail : public CommandNSSetEmail
+{
+ public:
+ CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 \037address\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params.size() > 1 ? params[1] : "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the email address of \037account\037 to \037address\037."));
+ return true;
+ }
+};
+
+class CommandNSSetKeepModes : public Command
+{
+ public:
+ CommandNSSetKeepModes(Module *creator, const Anope::string &sname = "nickserv/set/keepmodes", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Enable or disable keep modes"));
+ this->SetSyntax("{ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable keepmodes for " << nc->GetDisplay();
+ nc->SetS<bool>("NS_KEEP_MODES", true);
+ source.Reply(_("Keep modes for \002{0}\002 is now \002on\002."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable keepmodes for " << nc->GetDisplay();
+ nc->UnsetS<bool>("NS_KEEP_MODES");
+ source.Reply(_("Keep modes for \002{0}\002 is now \002off\002."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables keepmodes for your account. If keepmodes is enabled, services will remember your usermodes and attempt to re-set them the next time you log on."));
+ return true;
+ }
+};
+
+class CommandNSSASetKeepModes : public CommandNSSetKeepModes
+{
+ public:
+ CommandNSSASetKeepModes(Module *creator) : CommandNSSetKeepModes(creator, "nickserv/saset/keepmodes", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Enables or disables keepmodes for \037account\037. If keep modes is enabled, services will remember users' usermodes and attempt to re-set them the next time they log pn."));
+ return true;
+ }
+};
+
+class CommandNSSetKill : public Command
+{
+ public:
+ CommandNSSetKill(Module *creator, const Anope::string &sname = "nickserv/set/kill", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Turn protection on or off"));
+ this->SetSyntax("{ON | QUICK | IMMED | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
+ {
+ source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ nc->SetS<bool>("KILLPROTECT", true);
+ nc->UnsetS<bool>("KILL_QUICK");
+ nc->UnsetS<bool>("KILL_IMMED");
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill on for " << nc->GetDisplay();
+ source.Reply(_("Protection is now \002on\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("QUICK"))
+ {
+ nc->SetS<bool>("KILLPROTECT", true);
+ nc->SetS<bool>("KILL_QUICK", true);
+ nc->UnsetS<bool>("KILL_IMMED");
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill quick for " << nc->GetDisplay();
+ source.Reply(_("Protection is now \002on\002 for \002{0}\002, with a reduced delay."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("IMMED"))
+ {
+ if (Config->GetModule(this->GetOwner())->Get<bool>("allowkillimmed"))
+ {
+ nc->SetS<bool>("KILLPROTECT",true);
+ nc->UnsetS<bool>("KILL_QUICK");
+ nc->SetS<bool>("KILL_IMMED", true);
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill immed for " << nc->GetDisplay();
+ source.Reply(_("Protection is now \002on\002 for \002{0}\002, with no delay."), nc->GetDisplay());
+ }
+ else
+ source.Reply(_("The \002IMMED\002 option is not available on this network."));
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ nc->UnsetS<bool>("KILLPROTECT");
+ nc->UnsetS<bool>("KILL_QUICK");
+ nc->UnsetS<bool>("KILL_IMMED");
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable kill for " << nc->GetDisplay();
+ source.Reply(_("Protection is now \002off\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "KILL");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the automatic protection option for your account on or off."
+ " With protection on, if another user tries to use one of your nicknames, they will be given {0} to change to another their nickname, after which {1} will forcibly change their nickname.\n"
+ "\n"
+ "If you select \002QUICK\002, the user will be given only {1} to change their nick instead {0}."
+ " If you select \002IMMED\002, the user's nickname will be changed immediately \037without\037 being warned first or given a chance to change their nick."
+ " With this set, the only way to use the nickname is to match an entry on the account's access list."));
+ return true;
+ }
+};
+
+class CommandNSSASetKill : public CommandNSSetKill
+{
+ public:
+ CommandNSSASetKill(Module *creator) : CommandNSSetKill(creator, "nickserv/saset/kill", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 {ON | QUICK | IMMED | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the automatic protection option for \037account\037 on or off."
+ " With protection on, if another user tries to use one of the nicknames in the group, they will be given {0} to change to another their nickname, after which {1} will forcibly change their nickname.\n"
+ "\n"
+ "If you select \002QUICK\002, the user will be given only {1} to change their nick instead {0}."
+ " If you select \002IMMED\002, the user's nickname will be changed immediately \037without\037 being warned first or given a chance to change their nick."
+ " With this set, the only way to use the nickname is to match an entry on the account's access list."));
+ return true;
+ }
+};
+
+class CommandNSSetLanguage : public Command
+{
+ public:
+ CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Set the language Services will use when messaging you"));
+ this->SetSyntax(_("\037language\037"));
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param != "en_US")
+ for (unsigned j = 0; j < Language::Languages.size(); ++j)
+ {
+ if (Language::Languages[j] == param)
+ break;
+ else if (j + 1 == Language::Languages.size())
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+ }
+
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the language of " << nc->GetDisplay() << " to " << param;
+
+ nc->SetLanguage(param);
+
+ if (source.GetAccount() == nc)
+ source.Reply(_("Language changed to \002{0}\002."), Language::Translate(param.c_str(), _("English")));
+ else
+ source.Reply(_("Language for \002{0}\002 changed to \002{1}\002."), nc->GetDisplay(), Language::Translate(param.c_str(), _("English")));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &param) override
+ {
+ this->Run(source, source.nc->GetDisplay(), param[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the language services will use when sending messages to you (for example, when responding to a command you send). \037language\037 should be chosen from the following list of supported languages:"));
+
+ source.Reply(" en_US (English)");
+ for (unsigned j = 0; j < Language::Languages.size(); ++j)
+ {
+ const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
+ if (langname == "English")
+ continue;
+ source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
+ }
+
+ return true;
+ }
+};
+
+class CommandNSSASetLanguage : public CommandNSSetLanguage
+{
+ public:
+ CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 \037language\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Changes the language services will use when sending messages to the given user (for example, when responding to a command they send). \037language\037 should be chosen from the following list of supported languages:"));
+ source.Reply(" en (English)");
+ for (unsigned j = 0; j < Language::Languages.size(); ++j)
+ {
+ const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
+ if (langname == "English")
+ continue;
+ source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
+ }
+ return true;
+ }
+};
+
+class CommandNSSetMessage : public Command
+{
+ public:
+ CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Change the communication method of Services"));
+ this->SetSyntax("{ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
+ {
+ source.Reply(_("You cannot %s on this network."), source.command);
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->GetDisplay();
+ nc->SetS<bool>("MSG", true);
+ source.Reply(_("Services will now reply to \002{0}\002 with \002messages\002."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->GetDisplay();
+ nc->UnsetS<bool>("MSG");
+ source.Reply(_("Services will now reply to \002{0}\002 with \002notices\002."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "MSG");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ Anope::string cmd = source.command;
+ size_t i = cmd.find_last_of(' ');
+ if (i != Anope::string::npos)
+ cmd = cmd.substr(i + 1);
+
+ source.Reply(_("Allows you to choose the way services communicate with you. With \002{0}\002 set, services will use messages instead of notices."), cmd);
+ return true;
+ }
+
+ void OnServHelp(CommandSource &source) override
+ {
+ if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
+ Command::OnServHelp(source);
+ }
+};
+
+class CommandNSSASetMessage : public CommandNSSetMessage
+{
+ public:
+ CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 {ON | OFF}"));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ Anope::string cmd = source.command;
+ size_t i = cmd.find_last_of(' ');
+ if (i != Anope::string::npos)
+ cmd = cmd.substr(i + 1);
+
+ source.Reply(_("Allows you to choose the way services communicate with the given user. With \002{0}\002 set, services will use messages instead of notices."), cmd);
+ return true;
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+};
+
+class CommandNSSetSecure : public Command
+{
+ public:
+ CommandNSSetSecure(Module *creator, const Anope::string &sname = "nickserv/set/secure", size_t min = 1) : Command(creator, sname, min, min + 1)
+ {
+ this->SetDesc(_("Turn nickname security on or off"));
+ this->SetSyntax("{ON | OFF}");
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (param.equals_ci("ON"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable secure for " << nc->GetDisplay();
+ nc->SetS<bool>("NS_SECURE", true);
+ source.Reply(_("Secure option is now \002on\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable secure for " << nc->GetDisplay();
+ nc->UnsetS<bool>("NS_SECURE");
+ source.Reply(_("Secure option is now \002off\002 for \002{0}\002."), nc->GetDisplay());
+ }
+ else
+ this->OnSyntaxError(source, "SECURE");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), params[0]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the security feature on or off for your account."
+ " With \002SECURE\002 set, you must enter your password before you will be recognized as the owner of the account,"
+ " regardless of whether your address is on the access list or not."
+ " However, if you are on the access list, services will not force you to change your nickname, regardless of the setting of the \002kill\002 option."));
+ return true;
+ }
+};
+
+class CommandNSSASetSecure : public CommandNSSetSecure
+{
+ public:
+ CommandNSSASetSecure(Module *creator) : CommandNSSetSecure(creator, "nickserv/saset/secure", 2)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037account\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params[1]);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Turns the security feature on or off for \037account\037."
+ " With \002SECURE\002 set, you the user must enter their password before they will be recognized as the owner of the account,"
+ " regardless of whether their address address is on the access list or not."
+ " However, if they are on the access list, services will not force them to change your nickname, regardless of the setting of the \002kill\002 option."));
+ return true;
+ }
+};
+
+class CommandNSSASetNoexpire : public Command
+{
+ public:
+ CommandNSSASetNoexpire(Module *creator) : Command(creator, "nickserv/saset/noexpire", 1, 2)
+ {
+ this->SetDesc(_("Prevent the nickname from expiring"));
+ this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &user = params[0];
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+
+ Anope::string param = params.size() > 1 ? params[1] : "";
+
+ if (param.equals_ci("ON"))
+ {
+ Log(LOG_ADMIN, source, this) << "to enable noexpire for " << na->GetAccount()->GetDisplay();
+ na->SetS<bool>("NS_NO_EXPIRE", true);
+ source.Reply(_("\002{0}\002 \002will not\002 expire."), na->GetNick());
+ }
+ else if (param.equals_ci("OFF"))
+ {
+ Log(LOG_ADMIN, source, this) << "to disable noexpire for " << na->GetAccount()->GetDisplay();
+ na->UnsetS<bool>("NS_NO_EXPIRE");
+ source.Reply(_("\002{0}\002 \002will\002 expire."), na->GetNick());
+ }
+ else
+ this->OnSyntaxError(source, "NOEXPIRE");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ source.Reply(_("Sets whether the given nickname will expire. Setting this to \002ON\002 prevents the nickname from expiring."));
+ return true;
+ }
+};
+
+class NSSet : public Module
+ , public EventHook<Event::PreCommand>
+ , public EventHook<Event::SetCorrectModes>
+ , public EventHook<NickServ::Event::PreNickExpire>
+ , public EventHook<Event::NickInfo>
+ , public EventHook<Event::UserModeSet>
+ , public EventHook<Event::UserModeUnset>
+ , public EventHook<Event::UserLogin>
+{
+ CommandNSSet commandnsset;
+ CommandNSSASet commandnssaset;
+
+ CommandNSSetAutoOp commandnssetautoop;
+ CommandNSSASetAutoOp commandnssasetautoop;
+
+ CommandNSSetDisplay commandnssetdisplay;
+ CommandNSSASetDisplay commandnssasetdisplay;
+
+ CommandNSSetEmail commandnssetemail;
+ CommandNSSASetEmail commandnssasetemail;
+
+ CommandNSSetKeepModes commandnssetkeepmodes;
+ CommandNSSASetKeepModes commandnssasetkeepmodes;
+
+ CommandNSSetKill commandnssetkill;
+ CommandNSSASetKill commandnssasetkill;
+
+ CommandNSSetLanguage commandnssetlanguage;
+ CommandNSSASetLanguage commandnssasetlanguage;
+
+ CommandNSSetMessage commandnssetmessage;
+ CommandNSSASetMessage commandnssasetmessage;
+
+ CommandNSSetPassword commandnssetpassword;
+ CommandNSSASetPassword commandnssasetpassword;
+
+ CommandNSSetSecure commandnssetsecure;
+ CommandNSSASetSecure commandnssasetsecure;
+
+ CommandNSSASetNoexpire commandnssasetnoexpire;
+
+ Serialize::Field<NickServ::Account, bool> autoop, keep_modes, killprotect, kill_quick, kill_immed, message, secure;
+ Serialize::Field<NickServ::Nick, bool> noexpire;
+
+ /* email, passcode */
+ ExtensibleItem<std::pair<Anope::string, Anope::string > > ns_set_email;
+
+ public:
+ NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::PreCommand>(this)
+ , EventHook<Event::SetCorrectModes>(this)
+ , EventHook<NickServ::Event::PreNickExpire>(this)
+ , EventHook<Event::NickInfo>(this)
+ , EventHook<Event::UserModeSet>(this)
+ , EventHook<Event::UserModeUnset>(this)
+ , EventHook<Event::UserLogin>(this)
+
+ , commandnsset(this)
+ , commandnssaset(this)
+ , commandnssetautoop(this)
+ , commandnssasetautoop(this)
+ , commandnssetdisplay(this)
+ , commandnssasetdisplay(this)
+ , commandnssetemail(this)
+ , commandnssasetemail(this)
+ , commandnssetkeepmodes(this)
+ , commandnssasetkeepmodes(this)
+ , commandnssetkill(this)
+ , commandnssasetkill(this)
+ , commandnssetlanguage(this)
+ , commandnssasetlanguage(this)
+ , commandnssetmessage(this)
+ , commandnssasetmessage(this)
+ , commandnssetpassword(this)
+ , commandnssasetpassword(this)
+ , commandnssetsecure(this)
+ , commandnssasetsecure(this)
+ , commandnssasetnoexpire(this)
+
+ , autoop(this, "AUTOOP")
+ , keep_modes(this, "NS_KEEP_MODES")
+ , killprotect(this, "KILLPROTECT")
+ , kill_quick(this, "KILL_QUICK")
+ , kill_immed(this, "KILL_IMMED")
+ , message(this, "MSG")
+ , secure(this, "NS_SECURE")
+ , noexpire(this, "NS_NO_EXPIRE")
+
+ , ns_set_email(this, "ns_set_email")
+ {
+
+ }
+
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
+ {
+ NickServ::Account *uac = source.nc;
+
+ if (command->GetName() == "nickserv/confirm" && !params.empty() && uac)
+ {
+ std::pair<Anope::string, Anope::string> *n = ns_set_email.Get(uac);
+ if (n)
+ {
+ if (params[0] == n->second)
+ {
+ uac->SetEmail(n->first);
+ Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->GetEmail();
+ source.Reply(_("Your email address has been changed to \002%s\002."), uac->GetEmail().c_str());
+ ns_set_email.Unset(uac);
+ return EVENT_STOP;
+ }
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnSetCorrectModes(User *user, Channel *chan, ChanServ::AccessGroup &access, bool &give_modes, bool &take_modes) override
+ {
+ if (chan->ci)
+ {
+ /* Only give modes if autoop is set */
+ give_modes &= !user->Account() || autoop.HasExt(user->Account());
+ }
+ }
+
+ void OnPreNickExpire(NickServ::Nick *na, bool &expire) override
+ {
+ if (noexpire.HasExt(na))
+ expire = false;
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
+ {
+ if (!show_hidden)
+ return;
+
+ if (kill_immed.HasExt(na->GetAccount()))
+ info.AddOption(_("Immediate protection"));
+ else if (kill_quick.HasExt(na->GetAccount()))
+ info.AddOption(_("Quick protection"));
+ else if (killprotect.HasExt(na->GetAccount()))
+ info.AddOption(_("Protection"));
+ if (secure.HasExt(na->GetAccount()))
+ info.AddOption(_("Security"));
+ if (message.HasExt(na->GetAccount()))
+ info.AddOption(_("Message mode"));
+ if (autoop.HasExt(na->GetAccount()))
+ info.AddOption(_("Auto-op"));
+ if (noexpire.HasExt(na))
+ info.AddOption(_("No expire"));
+ if (keep_modes.HasExt(na->GetAccount()))
+ info.AddOption(_("Keep modes"));
+ }
+
+ void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (u->Account() && setter.GetUser() == u)
+ {
+ NickServ::Mode *m = Serialize::New<NickServ::Mode *>();
+ if (m != nullptr)
+ {
+ m->SetAccount(u->Account());
+ m->SetMode(mname);
+ }
+ }
+ }
+
+ void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (u->Account() && setter.GetUser() == u)
+ {
+ for (NickServ::Mode *m : u->Account()->GetRefs<NickServ::Mode *>())
+ if (m->GetMode() == mname)
+ m->Delete();
+ }
+ }
+
+ void OnUserLogin(User *u) override
+ {
+ if (keep_modes.HasExt(u->Account()))
+ for (NickServ::Mode *mode : u->Account()->GetRefs<NickServ::Mode *>())
+ {
+ UserMode *um = ModeManager::FindUserModeByName(mode->GetMode());
+ /* if the null user can set the mode, then it's probably safe */
+ if (um && um->CanSet(NULL))
+ u->SetMode(NULL, mode->GetMode());
+ }
+ }
+};
+
+MODULE_INIT(NSSet)
diff --git a/modules/nickserv/set_misc.cpp b/modules/nickserv/set_misc.cpp
new file mode 100644
index 000000000..899ddb4ab
--- /dev/null
+++ b/modules/nickserv/set_misc.cpp
@@ -0,0 +1,239 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/set_misc.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv/set.h"
+
+static Anope::map<Anope::string> descriptions;
+
+class NSMiscDataImpl : public NSMiscData
+{
+ friend class NSMiscDataType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string name, data;
+
+ public:
+ NSMiscDataImpl(Serialize::TypeBase *type) : NSMiscData(type) { }
+ NSMiscDataImpl(Serialize::TypeBase *type, Serialize::ID id) : NSMiscData(type, id) { }
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *s) override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &n) override;
+
+ Anope::string GetData() override;
+ void SetData(const Anope::string &d) override;
+};
+
+class NSMiscDataType : public Serialize::Type<NSMiscDataImpl>
+{
+ public:
+ Serialize::ObjectField<NSMiscDataImpl, NickServ::Account *> owner;
+ Serialize::Field<NSMiscDataImpl, Anope::string> name, data;
+
+ NSMiscDataType(Module *me) : Serialize::Type<NSMiscDataImpl>(me)
+ , owner(this, "nc", &NSMiscDataImpl::account, true)
+ , name(this, "name", &NSMiscDataImpl::name)
+ , data(this, "data", &NSMiscDataImpl::data)
+ {
+ }
+};
+
+NickServ::Account *NSMiscDataImpl::GetAccount()
+{
+ return Get(&NSMiscDataType::owner);
+}
+
+void NSMiscDataImpl::SetAccount(NickServ::Account *s)
+{
+ Set(&NSMiscDataType::owner, s);
+}
+
+Anope::string NSMiscDataImpl::GetName()
+{
+ return Get(&NSMiscDataType::name);
+}
+
+void NSMiscDataImpl::SetName(const Anope::string &n)
+{
+ Set(&NSMiscDataType::name, n);
+}
+
+Anope::string NSMiscDataImpl::GetData()
+{
+ return Get(&NSMiscDataType::data);
+}
+
+void NSMiscDataImpl::SetData(const Anope::string &d)
+{
+ Set(&NSMiscDataType::data, d);
+}
+
+class CommandNSSetMisc : public Command
+{
+ Anope::string GetAttribute(const Anope::string &command)
+ {
+ size_t sp = command.rfind(' ');
+ if (sp != Anope::string::npos)
+ return command.substr(sp + 1);
+ return command;
+ }
+
+ public:
+ CommandNSSetMisc(Module *creator, const Anope::string &cname = "nickserv/set/misc", size_t min = 0) : Command(creator, cname, min, min + 1)
+ {
+ this->SetSyntax(_("[\037parameter\037]"));
+ }
+
+ void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(user);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), user);
+ return;
+ }
+ NickServ::Account *nc = na->GetAccount();
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, nc, param);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ Anope::string scommand = GetAttribute(source.command);
+
+ /* remove existing */
+ for (NSMiscData *data : nc->GetRefs<NSMiscData *>())
+ if (data->GetName() == scommand)
+ {
+ data->Delete();
+ break;
+ }
+
+ if (!param.empty())
+ {
+ NSMiscData *data = Serialize::New<NSMiscData *>();
+ data->SetAccount(nc);
+ data->SetName(scommand);
+ data->SetData(param);
+
+ source.Reply(_("\002{0}\002 for \002{1}\002 set to \002{2}\002."), scommand, nc->GetDisplay(), param);
+ }
+ else
+ {
+ source.Reply(_("\002{0}\002 for \002{1}\002 unset."), scommand, nc->GetDisplay());
+ }
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, source.nc->GetDisplay(), !params.empty() ? params[0] : "");
+ }
+
+ void OnServHelp(CommandSource &source) override
+ {
+ if (descriptions.count(source.command))
+ {
+ this->SetDesc(descriptions[source.command]);
+ Command::OnServHelp(source);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (descriptions.count(source.command))
+ {
+ source.Reply(Language::Translate(source.nc, descriptions[source.command].c_str()));
+ return true;
+ }
+ return false;
+ }
+};
+
+class CommandNSSASetMisc : public CommandNSSetMisc
+{
+ public:
+ CommandNSSASetMisc(Module *creator) : CommandNSSetMisc(creator, "nickserv/saset/misc", 1)
+ {
+ this->ClearSyntax();
+ this->SetSyntax(_("\037nickname\037 [\037parameter\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ this->Run(source, params[0], params.size() > 1 ? params[1] : "");
+ }
+};
+
+class NSSetMisc : public Module
+ , public EventHook<Event::NickInfo>
+{
+ CommandNSSetMisc commandnssetmisc;
+ CommandNSSASetMisc commandnssasetmisc;
+ NSMiscDataType type;
+
+ public:
+ NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::NickInfo>(this)
+ , commandnssetmisc(this)
+ , commandnssasetmisc(this)
+ , type(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ descriptions.clear();
+
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
+ {
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ const Anope::string &cmd = block->Get<Anope::string>("command");
+
+ if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc")
+ continue;
+
+ Anope::string cname = block->Get<Anope::string>("name");
+ Anope::string desc = block->Get<Anope::string>("misc_description");
+
+ if (cname.empty() || desc.empty())
+ continue;
+
+ descriptions[cname] = desc;
+ }
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool) override
+ {
+ for (NSMiscData *data : na->GetAccount()->GetRefs<NSMiscData *>())
+ info[data->GetName()] = data->GetData();
+ }
+};
+
+MODULE_INIT(NSSetMisc)
diff --git a/modules/commands/ns_status.cpp b/modules/nickserv/status.cpp
index b06e51ec4..c092a9b46 100644
--- a/modules/commands/ns_status.cpp
+++ b/modules/nickserv/status.cpp
@@ -1,12 +1,20 @@
-/* NickServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -21,34 +29,35 @@ class CommandNSStatus : public Command
this->AllowUnregistered(true);
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &nick = !params.empty() ? params[0] : source.GetNick();
- const NickAlias *na = NickAlias::Find(nick);
+ const NickServ::Nick *na = NickServ::FindNick(nick);
spacesepstream sep(nick);
Anope::string nickbuf;
while (sep.GetToken(nickbuf))
{
+ #if 0
User *u2 = User::Find(nickbuf, true);
if (!u2) /* Nick is not online */
source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, "");
- else if (u2->IsIdentified() && na && na->nc == u2->Account()) /* Nick is identified */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 3, u2->Account()->display.c_str());
+ else if (u2->IsIdentified() && na && na->GetAccount() == u2->Account()) /* Nick is identified */
+ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 3, u2->Account()->GetDisplay().c_str());
else if (u2->IsRecognized()) /* Nick is recognised, but NOT identified */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 2, u2->Account() ? u2->Account()->display.c_str() : "");
+ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 2, u2->Account() ? u2->Account()->GetDisplay().c_str() : "");
else if (!na) /* Nick is online, but NOT a registered */
source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, "");
else
/* Nick is not identified for the nick, but they could be logged into an account,
* so we tell the user about it
*/
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 1, u2->Account() ? u2->Account()->display.c_str() : "");
+ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 1, u2->Account() ? u2->Account()->GetDisplay().c_str() : "");
+ #endif
}
- return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
this->SendSyntax(source);
source.Reply(" ");
@@ -77,10 +86,10 @@ class NSStatus : public Module
CommandNSStatus commandnsstatus;
public:
- NSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsstatus(this)
+ NSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsstatus(this)
{
-
+ throw ModuleException("Remind Adam to fix this");
}
};
diff --git a/modules/nickserv/suspend.cpp b/modules/nickserv/suspend.cpp
new file mode 100644
index 000000000..9bdafa2d8
--- /dev/null
+++ b/modules/nickserv/suspend.cpp
@@ -0,0 +1,348 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/suspend.h"
+#include "modules/nickserv/info.h"
+#include "modules/nickserv.h"
+
+class NSSuspendInfoImpl : public NSSuspendInfo
+{
+ friend class NSSuspendType;
+
+ NickServ::Account *account = nullptr;
+ Anope::string by, reason;
+ time_t when = 0, expires =0;
+
+ public:
+ NSSuspendInfoImpl(Serialize::TypeBase *type) : NSSuspendInfo(type) { }
+ NSSuspendInfoImpl(Serialize::TypeBase *type, Serialize::ID id) : NSSuspendInfo(type, id) { }
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ Anope::string GetBy() override;
+ void SetBy(const Anope::string &by) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &reason) override;
+
+ time_t GetWhen() override;
+ void SetWhen(const time_t &w) override;
+
+ time_t GetExpires() override;
+ void SetExpires(const time_t &e) override;
+};
+
+class NSSuspendType : public Serialize::Type<NSSuspendInfoImpl>
+{
+ public:
+ Serialize::ObjectField<NSSuspendInfoImpl, NickServ::Account *> account;
+ Serialize::Field<NSSuspendInfoImpl, Anope::string> by, reason;
+ Serialize::Field<NSSuspendInfoImpl, time_t> when, expires;
+
+ NSSuspendType(Module *me) : Serialize::Type<NSSuspendInfoImpl>(me)
+ , account(this, "nick", &NSSuspendInfoImpl::account, true)
+ , by(this, "by", &NSSuspendInfoImpl::by)
+ , reason(this, "reason", &NSSuspendInfoImpl::reason)
+ , when(this, "when", &NSSuspendInfoImpl::when)
+ , expires(this, "expires", &NSSuspendInfoImpl::expires)
+ {
+ }
+};
+
+NickServ::Account *NSSuspendInfoImpl::GetAccount()
+{
+ return Get(&NSSuspendType::account);
+}
+
+void NSSuspendInfoImpl::SetAccount(NickServ::Account *s)
+{
+ Set(&NSSuspendType::account, s);
+}
+
+Anope::string NSSuspendInfoImpl::GetBy()
+{
+ return Get(&NSSuspendType::by);
+}
+
+void NSSuspendInfoImpl::SetBy(const Anope::string &by)
+{
+ Set(&NSSuspendType::by, by);
+}
+
+Anope::string NSSuspendInfoImpl::GetReason()
+{
+ return Get(&NSSuspendType::reason);
+}
+
+void NSSuspendInfoImpl::SetReason(const Anope::string &reason)
+{
+ Set(&NSSuspendType::reason, reason);
+}
+
+time_t NSSuspendInfoImpl::GetWhen()
+{
+ return Get(&NSSuspendType::when);
+}
+
+void NSSuspendInfoImpl::SetWhen(const time_t &w)
+{
+ Set(&NSSuspendType::when, w);
+}
+
+time_t NSSuspendInfoImpl::GetExpires()
+{
+ return Get(&NSSuspendType::expires);
+}
+
+void NSSuspendInfoImpl::SetExpires(const time_t &e)
+{
+ Set(&NSSuspendType::expires, e);
+}
+
+class CommandNSSuspend : public Command
+{
+ public:
+ CommandNSSuspend(Module *creator) : Command(creator, "nickserv/suspend", 2, 3)
+ {
+ this->SetDesc(_("Suspend a given nick"));
+ this->SetSyntax(_("\037account\037 [+\037expiry\037] [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+
+ const Anope::string &nick = params[0];
+ Anope::string expiry = params[1];
+ Anope::string reason = params.size() > 2 ? params[2] : "";
+ time_t expiry_secs = Config->GetModule(this->GetOwner())->Get<time_t>("suspendexpire");
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ if (expiry[0] != '+')
+ {
+ reason = expiry + " " + reason;
+ reason.trim();
+ expiry.clear();
+ }
+ else
+ {
+ expiry_secs = Anope::DoTime(expiry);
+ if (expiry_secs == -1)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->GetAccount()->IsServicesOper())
+ {
+ source.Reply(_("You may not suspend other Services Operators' nicknames."));
+ return;
+ }
+
+ NSSuspendInfo *si = na->GetAccount()->GetRef<NSSuspendInfo *>();
+ if (!si)
+ {
+ source.Reply(_("\002%s\002 is already suspended."), na->GetAccount()->GetDisplay().c_str());
+ return;
+ }
+
+ NickServ::Account *nc = na->GetAccount();
+
+ si = Serialize::New<NSSuspendInfo *>();
+ si->SetAccount(nc);
+ si->SetBy(source.GetNick());
+ si->SetReason(reason);
+ si->SetWhen(Anope::CurTime);
+ si->SetExpires(expiry_secs ? expiry_secs + Anope::CurTime : 0);
+
+ for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>())
+ {
+ na2->SetLastQuit(reason);
+
+ User *u2 = User::Find(na2->GetNick(), true);
+ if (u2)
+ {
+ u2->Logout();
+ if (NickServ::service)
+ NickServ::service->Collide(u2, na2);
+ }
+ }
+
+ Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
+ source.Reply(_("\002{0}\002 is now suspended."), na->GetNick());
+
+ EventManager::Get()->Dispatch(&Event::NickSuspend::OnNickSuspend, na);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Suspends \037account\037, which prevents it from being used while keeping all the data for it."
+ " If an expiry is given the account will be unsuspended after that period of time, otherwise the default expiry from the configuration is used.")); // XXX
+ return true;
+ }
+};
+
+class CommandNSUnSuspend : public Command
+{
+ public:
+ CommandNSUnSuspend(Module *creator) : Command(creator, "nickserv/unsuspend", 1, 1)
+ {
+ this->SetDesc(_("Unsuspend a given nick"));
+ this->SetSyntax(_("\037account\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &nick = params[0];
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ NSSuspendInfo *si = na->GetAccount()->GetRef<NSSuspendInfo *>();
+ if (!si)
+ {
+ source.Reply(_("\002{0}\002 is not suspended."), na->GetNick());
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "for " << na->GetNick() << " which was suspended by " << (!si->GetBy().empty() ? si->GetBy() : "(none)") << " for: " << (!si->GetReason().empty() ? si->GetReason() : "No reason");
+
+ si->Delete();
+
+ source.Reply(_("\002{0}\002 is now released."), na->GetNick());
+
+ EventManager::Get()->Dispatch(&Event::NickUnsuspend::OnNickUnsuspend, na);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Unsuspends \037account\037, which allows it to be used again."));
+ return true;
+ }
+};
+
+class NSSuspend : public Module
+ , public EventHook<Event::NickInfo>
+ , public EventHook<NickServ::Event::PreNickExpire>
+ , public EventHook<NickServ::Event::NickValidate>
+{
+ CommandNSSuspend commandnssuspend;
+ CommandNSUnSuspend commandnsunsuspend;
+ std::vector<Anope::string> show;
+ NSSuspendType nst;
+
+ struct trim
+ {
+ Anope::string operator()(Anope::string s) const
+ {
+ return s.trim();
+ }
+ };
+
+ bool Show(CommandSource &source, const Anope::string &what) const
+ {
+ return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
+ }
+
+ public:
+ NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::NickInfo>(this)
+ , EventHook<NickServ::Event::PreNickExpire>(this)
+ , EventHook<NickServ::Event::NickValidate>(this)
+ , commandnssuspend(this)
+ , commandnsunsuspend(this)
+ , nst(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Anope::string s = conf->GetModule(this)->Get<Anope::string>("show");
+ commasepstream(s).GetTokens(show);
+ std::transform(show.begin(), show.end(), show.begin(), trim());
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
+ {
+ NSSuspendInfo *s = na->GetAccount()->GetRef<NSSuspendInfo *>();
+ if (!s)
+ return;
+
+ if (show_hidden || Show(source, "suspended"))
+ info[_("Suspended")] = _("This nickname is \002suspended\002.");
+ if (!s->GetBy().empty() && (show_hidden || Show(source, "by")))
+ info[_("Suspended by")] = s->GetBy();
+ if (!s->GetReason().empty() && (show_hidden || Show(source, "reason")))
+ info[_("Suspend reason")] = s->GetReason();
+ if (s->GetWhen() && (show_hidden || Show(source, "on")))
+ info[_("Suspended on")] = Anope::strftime(s->GetWhen(), source.GetAccount());
+ if (s->GetExpires() && (show_hidden || Show(source, "expires")))
+ info[_("Suspension expires")] = Anope::strftime(s->GetExpires(), source.GetAccount());
+ }
+
+ void OnPreNickExpire(NickServ::Nick *na, bool &expire) override
+ {
+ NSSuspendInfo *s = na->GetAccount()->GetRef<NSSuspendInfo *>();
+ if (!s)
+ return;
+
+ expire = false;
+
+ if (!s->GetExpires())
+ return;
+
+ if (s->GetExpires() < Anope::CurTime)
+ {
+ na->SetLastSeen(Anope::CurTime);
+ s->Delete();
+
+ Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->GetNick();
+ }
+ }
+
+ EventReturn OnNickValidate(User *u, NickServ::Nick *na) override
+ {
+ NSSuspendInfo *s = na->GetAccount()->GetRef<NSSuspendInfo *>();
+ if (!s)
+ return EVENT_CONTINUE;
+
+ u->SendMessage(Config->GetClient("NickServ"), _("\002{0}\002 is suspended."), u->nick);
+ return EVENT_STOP;
+ }
+};
+
+MODULE_INIT(NSSuspend)
diff --git a/modules/nickserv/update.cpp b/modules/nickserv/update.cpp
new file mode 100644
index 000000000..70feabadf
--- /dev/null
+++ b/modules/nickserv/update.cpp
@@ -0,0 +1,71 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/nickserv/update.h"
+
+class CommandNSUpdate : public Command
+{
+ public:
+ CommandNSUpdate(Module *creator) : Command(creator, "nickserv/update", 0, 0)
+ {
+ this->SetDesc(_("Updates your current status, i.e. it checks for new memos"));
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+ NickServ::Nick *na = NickServ::FindNick(u->nick);
+
+ if (na && na->GetAccount() == source.GetAccount())
+ {
+ na->SetLastRealname(u->realname);
+ na->SetLastSeen(Anope::CurTime);
+ }
+
+ EventManager::Get()->Dispatch(&Event::NickUpdate::OnNickUpdate, u);
+
+ source.Reply(_("Status updated (memos, vhost, chmodes, flags)."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Updates your current status, i.e. it checks for new memos,\n"
+ "sets needed channel modes and updates your vhost and\n"
+ "your userflags (lastseentime, etc)."));
+ return true;
+ }
+};
+
+class NSUpdate : public Module
+{
+ CommandNSUpdate commandnsupdate;
+
+ public:
+ NSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandnsupdate(this)
+ {
+
+ }
+};
+
+MODULE_INIT(NSUpdate)
diff --git a/modules/operserv/CMakeLists.txt b/modules/operserv/CMakeLists.txt
new file mode 100644
index 000000000..cd225a94d
--- /dev/null
+++ b/modules/operserv/CMakeLists.txt
@@ -0,0 +1 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/operserv/akill.cpp b/modules/operserv/akill.cpp
new file mode 100644
index 000000000..36d555b79
--- /dev/null
+++ b/modules/operserv/akill.cpp
@@ -0,0 +1,455 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSAKill : public Command
+{
+ ServiceReference<XLineManager> akills;
+
+ void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ Anope::string expiry, mask;
+
+ if (params.size() < 2)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ spacesepstream sep(params[1]);
+ sep.GetToken(mask);
+
+ if (mask[0] == '+')
+ {
+ expiry = mask;
+ sep.GetToken(mask);
+ }
+
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires && expires < 60)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ else if (expires > 0)
+ expires += Anope::CurTime;
+
+ if (sep.StreamEnd())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ Anope::string reason;
+ if (mask.find('#') != Anope::string::npos)
+ {
+ Anope::string remaining = sep.GetRemaining();
+
+ size_t co = remaining[0] == ':' ? 0 : remaining.rfind(" :");
+ if (co == Anope::string::npos)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (co != 0)
+ ++co;
+
+ reason = remaining.substr(co + 1);
+ mask += " " + remaining.substr(0, co);
+ mask.trim();
+ }
+ else
+ reason = sep.GetRemaining();
+
+ if (mask[0] == '/' && mask[mask.length() - 1] == '/')
+ {
+ if (!Config->regex_flags)
+ {
+ source.Reply(_("Regex is disabled."));
+ return;
+ }
+
+ Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
+ try
+ {
+ std::regex(stripped_mask.str(), Config->regex_flags);
+ }
+ catch (const std::regex_error &ex)
+ {
+ source.Reply("%s", ex.what());
+ return;
+ }
+ }
+
+ User *targ = User::Find(mask, true);
+ if (targ)
+ mask = "*@" + targ->host;
+
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
+ if (mask.find_first_not_of("/~@.*?") == Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; Please use a more specific mask."), mask);
+ return;
+ }
+
+ if (mask.find('@') == Anope::string::npos)
+ {
+ source.Reply(_("Mask must be in the form \037user\037@\037host\037."));
+ return;
+ }
+
+ if (!akills->CanAdd(source, mask, expires, reason))
+ return;
+
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(source.GetNick());
+ x->SetExpires(expires);
+ x->SetReason(reason);
+
+ if (Config->GetModule("operserv")->Get<bool>("akillids"))
+ x->SetID(XLineManager::GenerateUID());
+
+ unsigned int affected = 0;
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (akills->Check(it->second, x))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; Please use a more specific mask."), mask);
+ Log(LOG_ADMIN, source, this) << "tried to akill " << percent << "% of the network (" << affected << " users)";
+ delete x;
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::AddXLine::OnAddXLine, source, x, akills);
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return;
+ }
+
+ akills->AddXLine(x);
+ if (Config->GetModule("operserv")->Get<bool>("akillonadd"))
+ akills->Send(NULL, x);
+
+ source.Reply(_("\002{0}\002 added to the akill list."), mask);
+
+ Log(LOG_ADMIN, source, this) << "on " << mask << " (" << x->GetReason() << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (akills->GetXLines().empty())
+ {
+ source.Reply(_("The akill list is empty."));
+ return;
+ }
+
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ unsigned int deleted = 0;
+
+ NumberList(mask, true,
+ [&](unsigned int number)
+ {
+ XLine *x = akills->GetEntry(number - 1);
+
+ if (!x)
+ return;
+
+ Log(LOG_ADMIN, source, this) << "to remove " << x->GetMask() << " from the list";
+
+ ++deleted;
+ x->Delete();
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("No matching entries on the akill list."));
+ else if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from the akill list."));
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from the akill list."), deleted);
+ });
+ }
+ else
+ {
+ XLine *x = akills->HasEntry(mask);
+
+ if (!x)
+ {
+ source.Reply(_("\002{0}\002 was not found on the akill list."), mask);
+ return;
+ }
+
+ do
+ {
+ EventManager::Get()->Dispatch(&Event::DelXLine::OnDelXLine, source, x, akills);
+
+ Log(LOG_ADMIN, source, this) << "to remove " << x->GetMask() << " from the list";
+ source.Reply(_("\002{0}\002 deleted from the akill list."), x->GetMask());
+ x->Delete();
+ }
+ while ((x = akills->HasEntry(mask)));
+
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
+ {
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(mask, false,
+ [&](unsigned int number)
+ {
+ XLine *x = akills->GetEntry(number - 1);
+
+ if (!x)
+ return;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ entry["Mask"] = x->GetMask();
+ entry["Creator"] = x->GetBy();
+ entry["Created"] = Anope::strftime(x->GetCreated(), NULL, true);
+ entry["Expires"] = Anope::Expires(x->GetExpires(), source.nc);
+ entry["ID"] = x->GetID();
+ entry["Reason"] = x->GetReason();
+ list.AddEntry(entry);
+ },
+ [&]{});
+ }
+ else
+ {
+ unsigned int i = 0;
+ for (XLine *x : akills->GetXLines())
+ {
+ if (mask.empty() || mask.equals_ci(x->GetMask()) || mask == x->GetID() || Anope::Match(x->GetMask(), mask, false, true))
+ {
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(++i);
+ entry["Mask"] = x->GetMask();
+ entry["Creator"] = x->GetBy();
+ entry["Created"] = Anope::strftime(x->GetCreated(), NULL, true);
+ entry["Expires"] = Anope::Expires(x->GetExpires(), source.nc);
+ entry["ID"] = x->GetID();
+ entry["Reason"] = x->GetReason();
+ list.AddEntry(entry);
+ }
+ }
+ }
+
+ if (list.IsEmpty())
+ {
+ source.Reply(_("There are no matching entries on the akill list."));
+ return;
+ }
+
+ source.Reply(_("Current akill list:"));
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of akill list."));
+ }
+
+ void DoList(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ if (akills->GetXLines().empty())
+ {
+ source.Reply(_("The akill list is empty."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ void DoView(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ if (akills->GetXLines().empty())
+ {
+ source.Reply(_("The akill list is empty."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Expires"));
+ if (Config->GetModule("operserv")->Get<bool>("akillids"))
+ list.AddColumn(_("ID"));
+ list.AddColumn(_("Reason"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ void DoClear(CommandSource &source)
+ {
+ for (XLine *x : akills->GetXLines())
+ {
+ EventManager::Get()->Dispatch(&Event::DelXLine::OnDelXLine, source, x, akills);
+ x->Delete();
+ }
+
+ Log(LOG_ADMIN, source, this) << "to CLEAR the list";
+ source.Reply(_("The akill list has been cleared."));
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+ public:
+ CommandOSAKill(Module *creator) : Command(creator, "operserv/akill", 1, 2)
+ , akills("xlinemanager/sgline")
+ {
+ this->SetDesc(_("Manipulate the AKILL list"));
+ this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax("CLEAR");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ if (!akills)
+ return;
+
+ if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, params);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, params);
+ else if (cmd.equals_ci("LIST"))
+ return this->DoList(source, params);
+ else if (cmd.equals_ci("VIEW"))
+ return this->DoView(source, params);
+ else if (cmd.equals_ci("CLEAR"))
+ return this->DoClear(source);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("The \002{0} ADD\002 command adds \037mask\037 to the auto kill list with the given \037reason\037."
+ "\037mask\037 can be in the format of nickname!username@hostname#realname."
+ " If a real name is specified, the reason must be prefixed with a :."
+ " \037expiry\037 is optional, and if specified must be an integer followed by one of \037d\037 (days), \037h\037 (hours), or \037m\037 (minutes)."
+ " If a unit specifier is not included, the default is days, so \037+30\037 means 30 days."
+ " To add an auto kill which does not expire, use \037+0\037. "
+ " The default auto kill expiry time is \002{1}\002"),
+ source.command, Anope::Duration(Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"), source.GetAccount()));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the %s engine. Enclose your mask in // if this is desired."), regexengine);
+ }
+ }
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes the given \037mask\037 from the auto kill list, if present."
+ " If a list of entry numbers is given, those entries are deleted."),
+ source.command);
+ else if (subcommand.equals_ci("LIST") || subcommand.equals_ci("VIEW"))
+ source.Reply(_("The \002{0} LIST\002 and \002{0} VIEW\002 commands display the auto kill list."
+ " If a wildcard \037mask\037 is given, only those entries matching the mask are displayed."
+ " If a list of entry numbers is given, only those entries are shown."
+ " \002VIEW\002 is similar to \002LIST\002 but also shows who created the auto kill, when it was created, and when it expires.\n"
+ "\n"
+ "Example:\n"
+ "\n"
+ " {0} LIST 2-5,7-9\n"
+ " Lists auto kill entries numbered 2 through 5 and 7 through 9."),
+ source.command);
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("The \002{0} CLEAR\002 command removes all auto kills from the auto kill list."),
+ source.command);
+ else
+ {
+ CommandInfo *help = source.service->FindCommand("generic/help");
+ source.Reply(_("Allows manipulating the AKILL list."
+ " If a user matching an AKILL mask connects, services will issue a kill the user and prevent them from reconnecting.\n"
+ "\n"
+ "The \002ADD\002 command adds \037mask\037 to the auto kill list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the auto kill list.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002VIEW\002 commands both show the auto kill list, but \002VIEW\002 also shows who created the auto kill entry, when it was created, and when it expires.\n"
+ "\002{msg}{service} {help} {command} [LIST | VIEW]\002 for more information.\n"
+ "\n"
+ "The \002CLEAR\002 command clears th auto kill list."
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information.\n"),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "help"_kw = help->cname, "command"_kw = source.command);
+ }
+ return true;
+ }
+};
+
+class OSAKill : public Module
+{
+ CommandOSAKill commandosakill;
+
+ public:
+ OSAKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosakill(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSAKill)
diff --git a/modules/operserv/chankill.cpp b/modules/operserv/chankill.cpp
new file mode 100644
index 000000000..9ab820821
--- /dev/null
+++ b/modules/operserv/chankill.cpp
@@ -0,0 +1,134 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+
+class CommandOSChanKill : public Command
+{
+ ServiceReference<XLineManager> akills;
+
+ public:
+ CommandOSChanKill(Module *creator) : Command(creator, "operserv/chankill", 2, 3)
+ , akills("xlinemanager/sgline")
+ {
+ this->SetDesc(_("AKILL all users on a specific channel"));
+ this->SetSyntax(_("[+\037expiry\037] \037channel\037 \037reason\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!akills)
+ return;
+
+ Anope::string expiry, channel;
+ unsigned last_param = 1;
+
+ channel = params[0];
+ if (!channel.empty() && channel[0] == '+')
+ {
+ expiry = channel;
+ channel = params[1];
+ last_param = 2;
+ }
+
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
+ if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
+ expires *= 86400;
+
+ if (expires)
+ {
+ if (expires < 60)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+
+ expires += Anope::CurTime;
+ }
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(source, "");
+ return;
+ }
+
+ Anope::string reason = params[last_param];
+ if (params.size() > last_param + 1)
+ reason += params[last_param + 1];
+
+ Anope::string realreason;
+ if (Config->GetModule("operserv")->Get<bool>("addakiller") && !source.GetNick().empty())
+ realreason = "[" + source.GetNick() + "] " + reason;
+ else
+ realreason = reason;
+
+ Channel *c = Channel::Find(channel);
+ if (!c)
+ {
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), channel);
+ return;
+ }
+
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *uc = it->second;
+
+ if (uc->user->server == Me || uc->user->HasMode("OPER"))
+ continue;
+
+ Anope::string akillmask = "*@" + uc->user->host;
+
+ if (akills->HasEntry(akillmask))
+ continue;
+
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(akillmask);
+ x->SetBy(source.GetNick());
+ x->SetExpires(expires);
+ x->SetReason(realreason);
+ x->SetID(XLineManager::GenerateUID());
+
+ akills->AddXLine(x);
+ akills->OnMatch(uc->user, x);
+ }
+
+ Log(LOG_ADMIN, source, this) << "on " << c->name << " (" << realreason << ")";
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Adds an auto kill for every user on \037channel\037, except for IRC operators."));
+ return true;
+ }
+};
+
+class OSChanKill : public Module
+{
+ CommandOSChanKill commandoschankill;
+
+ public:
+ OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandoschankill(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSChanKill)
diff --git a/modules/commands/os_config.cpp b/modules/operserv/config.cpp
index a2e4f3272..3935b4899 100644
--- a/modules/commands/os_config.cpp
+++ b/modules/operserv/config.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSConfig : public Command
this->SetSyntax(_("{\037MODIFY\037|\037VIEW\037} [\037block name\037 \037item name\037 \037item value\037]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &what = params[0];
@@ -28,7 +36,7 @@ class CommandOSConfig : public Command
{
if (!source.HasPriv("operserv/config"))
{
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied. You do not have the operator privilege \002{0}\002."), "operserv/config");
return;
}
@@ -38,14 +46,14 @@ class CommandOSConfig : public Command
if (!block)
{
- source.Reply(_("There is no such configuration block %s."), params[1].c_str());
+ source.Reply(_("There is no such configuration block \002{0}\002."), params[1]);
return;
}
block->Set(params[2], params[3]);
Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3];
- source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str());
+ source.Reply(_("Value of \002{0}:{1}\002 changed to \002{2}\002."), params[1], params[2], params[3]);
}
else if (what.equals_ci("VIEW"))
{
@@ -53,7 +61,7 @@ class CommandOSConfig : public Command
const Anope::string show_blocks[] = { "serverinfo", "networkinfo", "options", "" };
Log(LOG_ADMIN, source, this) << "VIEW";
-
+
for (unsigned i = 0; !show_blocks[i].empty(); ++i)
{
Configuration::Block *block = Config->GetBlock(show_blocks[i]);
@@ -76,7 +84,7 @@ class CommandOSConfig : public Command
std::vector<Anope::string> replies;
lflist.Process(replies);
- source.Reply(_("%s settings:"), block->GetName().c_str());
+ source.Reply(_("%s settings:"), block->GetName());
for (unsigned j = 0; j < replies.size(); ++j)
source.Reply(replies[j]);
@@ -120,17 +128,14 @@ class CommandOSConfig : public Command
this->OnSyntaxError(source, what);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to change and view configuration settings.\n"
- "Settings changed by this command are temporary and will not be reflected\n"
- "back into the configuration file, and will be lost if Anope is shut down,\n"
- "restarted, or the configuration is reloaded.\n"
- " \n"
- "Example:\n"
- " \002MODIFY nickserv forcemail no\002"));
+ source.Reply(_("Allows you to change and view configuration settings. Settings changed by this command are temporary and will not be reflected back into the configuration file, and will be lost if Anope is shut down, restarted, or the configuration is reloaded.\n"
+ "Use of the \002MODIFY\002 command requires the \002{0}\002 operator privilege.\n"
+ "\n"
+ "Example:\n"
+ " {0} MODIFY nickserv forcemail no"
+ " Changes the \"forceemail\" setting of the module configuration for \"nickserv\" to \"no\""));
return true;
}
};
@@ -140,8 +145,8 @@ class OSConfig : public Module
CommandOSConfig commandosconfig;
public:
- OSConfig(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosconfig(this)
+ OSConfig(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosconfig(this)
{
}
diff --git a/modules/commands/os_defcon.cpp b/modules/operserv/defcon.cpp
index fbccf2aae..d7f95d0e7 100644
--- a/modules/commands/os_defcon.cpp
+++ b/modules/operserv/defcon.cpp
@@ -1,16 +1,26 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
-#include "modules/os_session.h"
+#include "modules/operserv/session.h"
+#include "modules/operserv/defcon.h"
+#include "modules/global.h"
enum DefconLevel
{
@@ -79,19 +89,19 @@ struct DefconConfig
{
DefConModesOnParams.erase(name);
}
-
+
bool GetDefConParam(const Anope::string &name, Anope::string &buf)
{
std::map<Anope::string, Anope::string>::iterator it = DefConModesOnParams.find(name);
-
+
buf.clear();
-
+
if (it != DefConModesOnParams.end())
{
buf = it->second;
return true;
}
-
+
return false;
}
};
@@ -101,13 +111,12 @@ static DefconConfig DConfig;
static void runDefCon();
static Anope::string defconReverseModes(const Anope::string &modes);
-static ServiceReference<GlobalService> GlobalService("GlobalService", "Global");
-
static Timer *timeout;
class DefConTimeout : public Timer
{
int level;
+ ServiceReference<Global::GlobalService> global;
public:
DefConTimeout(Module *mod, int newlevel) : Timer(mod, DConfig.timeout), level(newlevel)
@@ -120,23 +129,23 @@ class DefConTimeout : public Timer
timeout = NULL;
}
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
if (DConfig.defaultlevel != level)
{
DConfig.defaultlevel = level;
- FOREACH_MOD(OnDefconLevel, (level));
+ EventManager::Get()->Dispatch(&Event::DefconLevel::OnDefconLevel, level);
Log(Config->GetClient("OperServ"), "operserv/defcon") << "Defcon level timeout, returning to level " << level;
- if (DConfig.globalondefcon)
+ if (DConfig.globalondefcon && global)
{
if (!DConfig.offmessage.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.offmessage);
+ global->SendGlobal(NULL, "", DConfig.offmessage);
else
- GlobalService->SendGlobal(NULL, "", Anope::printf(Language::Translate(_("The Defcon level is now at: \002%d\002")), DConfig.defaultlevel));
+ global->SendGlobal(NULL, "", Anope::printf(Language::Translate(_("The Defcon level is now at: \002%d\002")), DConfig.defaultlevel));
if (!DConfig.message.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.message);
+ global->SendGlobal(NULL, "", DConfig.message);
}
runDefCon();
@@ -146,6 +155,8 @@ class DefConTimeout : public Timer
class CommandOSDefcon : public Command
{
+ ServiceReference<Global::GlobalService> global;
+
void SendLevels(CommandSource &source)
{
if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
@@ -155,9 +166,9 @@ class CommandOSDefcon : public Command
if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
source.Reply(_("* No mode lock changes"));
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
- source.Reply(_("* Force channel modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
+ source.Reply(_("* Force channel modes (\002{0}\002) to be set on all channels"), DConfig.chanmodes);
if (DConfig.Check(DEFCON_REDUCE_SESSION))
- source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
+ source.Reply(_("* Use the reduced session limit of \002{0}\002"), DConfig.sessionlimit);
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
source.Reply(_("* Kill any new clients connecting"));
if (DConfig.Check(DEFCON_OPER_ONLY))
@@ -177,13 +188,13 @@ class CommandOSDefcon : public Command
this->SetSyntax(_("[\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &lvl = params[0];
if (lvl.empty())
{
- source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel);
+ source.Reply(_("Services are now at defcon \002{0}\002."), DConfig.defaultlevel);
this->SendLevels(source);
return;
}
@@ -203,48 +214,50 @@ class CommandOSDefcon : public Command
DConfig.defaultlevel = newLevel;
- FOREACH_MOD(OnDefconLevel, (newLevel));
+ EventManager::Get()->Dispatch(&Event::DefconLevel::OnDefconLevel, newLevel);
delete timeout;
if (DConfig.timeout)
timeout = new DefConTimeout(this->module, 5);
- source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel);
+ source.Reply(_("Services are now at defcon \002{0}\002."), DConfig.defaultlevel);
this->SendLevels(source);
Log(LOG_ADMIN, source, this) << "to change defcon level to " << newLevel;
/* Global notice the user what is happening. Also any Message that
the Admin would like to add. Set in config file. */
- if (DConfig.globalondefcon)
+ if (DConfig.globalondefcon && global)
{
if (DConfig.defaultlevel == 5 && !DConfig.offmessage.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.offmessage);
+ global->SendGlobal(NULL, "", DConfig.offmessage);
else if (DConfig.defaultlevel != 5)
{
- GlobalService->SendGlobal(NULL, "", Anope::printf(_("The Defcon level is now at: \002%d\002"), DConfig.defaultlevel));
+ global->SendGlobal(NULL, "", Anope::printf(_("The defcon level is now at \002%d\002"), DConfig.defaultlevel));
if (!DConfig.message.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.message);
+ global->SendGlobal(NULL, "", DConfig.message);
}
}
/* Run any defcon functions, e.g. FORCE CHAN MODE */
runDefCon();
- return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The defcon system can be used to implement a pre-defined\n"
- "set of restrictions to services useful during an attempted\n"
- "attack on the network."));
+ source.Reply(_("The defcon system can be used to implement a pre-defined set of restrictions to services useful during an attempted attack on the network."));
+ // XXX actually explain what this does
return true;
}
};
class OSDefcon : public Module
+ , public EventHook<Event::ChannelModeSet>
+ , public EventHook<Event::ChannelModeUnset>
+ , public EventHook<Event::PreCommand>
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::ChannelModeAdd>
+ , public EventHook<Event::ChannelSync>
{
ServiceReference<SessionService> session_service;
ServiceReference<XLineManager> akills;
@@ -324,42 +337,55 @@ class OSDefcon : public Module
if ((cm = ModeManager::FindChannelModeByName("REDIRECT")) && DConfig.DefConModesOn.count(cm->name) && !DConfig.DefConModesOn.count("LIMIT"))
{
DConfig.DefConModesOn.erase("REDIRECT");
-
+
Log(this) << "DefConChanModes must lock mode +l as well to lock mode +L";
}
}
public:
- OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), session_service("SessionService", "session"), akills("XLineManager", "xlinemanager/sgline"), commandosdefcon(this)
+ OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ChannelModeSet>(this)
+ , EventHook<Event::ChannelModeUnset>(this)
+ , EventHook<Event::PreCommand>(this)
+ , EventHook<Event::UserConnect>(this)
+ , EventHook<Event::ChannelModeAdd>(this)
+ , EventHook<Event::ChannelSync>(this)
+ , akills("xlinemanager/sgline")
+ , commandosdefcon(this)
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ ~OSDefcon()
+ {
+ delete timeout;
+ }
+
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
DefconConfig dconfig;
dconfig.defaultlevel = block->Get<int>("defaultlevel");
- dconfig.defcons[4] = block->Get<const Anope::string>("level4");
- dconfig.defcons[3] = block->Get<const Anope::string>("level3");
- dconfig.defcons[2] = block->Get<const Anope::string>("level2");
- dconfig.defcons[1] = block->Get<const Anope::string>("level1");
+ dconfig.defcons[4] = block->Get<Anope::string>("level4");
+ dconfig.defcons[3] = block->Get<Anope::string>("level3");
+ dconfig.defcons[2] = block->Get<Anope::string>("level2");
+ dconfig.defcons[1] = block->Get<Anope::string>("level1");
dconfig.sessionlimit = block->Get<int>("sessionlimit");
- dconfig.akillreason = block->Get<const Anope::string>("akillreason");
+ dconfig.akillreason = block->Get<Anope::string>("akillreason");
dconfig.akillexpire = block->Get<time_t>("akillexpire");
- dconfig.chanmodes = block->Get<const Anope::string>("chanmodes");
+ dconfig.chanmodes = block->Get<Anope::string>("chanmodes");
dconfig.timeout = block->Get<time_t>("timeout");
dconfig.globalondefcon = block->Get<bool>("globalondefcon");
- dconfig.message = block->Get<const Anope::string>("message");
- dconfig.offmessage = block->Get<const Anope::string>("offmessage");
+ dconfig.message = block->Get<Anope::string>("message");
+ dconfig.offmessage = block->Get<Anope::string>("offmessage");
block = conf->GetModule("os_session");
dconfig.max_session_kill = block->Get<int>("maxsessionkill");
dconfig.session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
- dconfig.sle_reason = block->Get<const Anope::string>("sessionlimitexceeded");
- dconfig.sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc");
+ dconfig.sle_reason = block->Get<Anope::string>("sessionlimitexceeded");
+ dconfig.sle_detailsloc = block->Get<Anope::string>("sessionlimitdetailsloc");
if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5)
throw ConfigException("The value for <defcon:defaultlevel> must be between 1 and 5");
@@ -406,7 +432,7 @@ class OSDefcon : public Module
this->ParseModeString();
}
- EventReturn OnChannelModeSet(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string &param) anope_override
+ EventReturn OnChannelModeSet(Channel *c, const MessageSource &source, ChannelMode *mode, const Anope::string &param) override
{
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOff.count(mode->name) && source.GetUser() && !source.GetBot())
{
@@ -418,7 +444,7 @@ class OSDefcon : public Module
return EVENT_CONTINUE;
}
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string &) anope_override
+ EventReturn OnChannelModeUnset(Channel *c, const MessageSource &source, ChannelMode *mode, const Anope::string &) override
{
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOn.count(mode->name) && source.GetUser() && !source.GetBot())
{
@@ -436,7 +462,7 @@ class OSDefcon : public Module
return EVENT_CONTINUE;
}
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
{
if (DConfig.Check(DEFCON_OPER_ONLY) && !source.IsOper())
{
@@ -447,35 +473,35 @@ class OSDefcon : public Module
{
return EVENT_STOP;
}
- else if (command->name == "nickserv/register" || command->name == "nickserv/group")
+ else if (command->GetName() == "nickserv/register" || command->GetName() == "nickserv/group")
{
if (DConfig.Check(DEFCON_NO_NEW_NICKS))
{
- source.Reply(_("Services are in DefCon mode, please try again later."));
+ source.Reply(_("Services are in defcon mode, please try again later."));
return EVENT_STOP;
}
}
- else if (command->name == "chanserv/mode" && params.size() > 1 && params[1].equals_ci("LOCK"))
+ else if (command->GetName() == "chanserv/mode" && params.size() > 1 && params[1].equals_ci("LOCK"))
{
if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
{
- source.Reply(_("Services are in DefCon mode, please try again later."));
+ source.Reply(_("Services are in defcon mode, please try again later."));
return EVENT_STOP;
}
}
- else if (command->name == "chanserv/register")
+ else if (command->GetName() == "chanserv/register")
{
if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
{
- source.Reply(_("Services are in DefCon mode, please try again later."));
+ source.Reply(_("Services are in defcon mode, please try again later."));
return EVENT_STOP;
}
}
- else if (command->name == "memoserv/send")
+ else if (command->GetName() == "memoserv/send")
{
if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
{
- source.Reply(_("Services are in DefCon mode, please try again later."));
+ source.Reply(_("Services are in defcon mode, please try again later."));
return EVENT_STOP;
}
}
@@ -483,17 +509,20 @@ class OSDefcon : public Module
return EVENT_CONTINUE;
}
- void OnUserConnect(User *u, bool &exempt) anope_override
+ void OnUserConnect(User *u, bool &exempt) override
{
if (exempt || u->Quitting() || !u->server->IsSynced() || u->server->IsULined())
return;
- BotInfo *OperServ = Config->GetClient("OperServ");
+ ServiceBot *OperServ = Config->GetClient("OperServ");
if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
{
Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+#warning "xline allocated on stack"
+#if 0
XLine x("*@" + u->host, OperServ ? OperServ->nick : "defcon", Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
akills->Send(NULL, &x);
+#endif
}
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
@@ -506,9 +535,9 @@ class OSDefcon : public Module
return;
Session *session = session_service->FindSession(u->ip.addr());
- Exception *exception = session_service->FindException(u);
+ Exception *e = session_service->FindException(u);
- if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception)
+ if (DConfig.Check(DEFCON_REDUCE_SESSION) && !e)
{
if (session && session->count > static_cast<unsigned>(DConfig.sessionlimit))
{
@@ -523,9 +552,12 @@ class OSDefcon : public Module
++session->hits;
if (akills && DConfig.max_session_kill && session->hits >= DConfig.max_session_kill)
{
+#warning "xline allocated on stack"
+#if 0
XLine x("*@" + session->addr.mask(), OperServ ? OperServ->nick : "", Anope::CurTime + DConfig.session_autokill_expiry, "Defcon session limit exceeded", XLineManager::GenerateUID());
akills->Send(NULL, &x);
Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << session->addr.mask() << "\002 due to excessive connections";
+#endif
}
else
{
@@ -535,13 +567,13 @@ class OSDefcon : public Module
}
}
- void OnChannelModeAdd(ChannelMode *cm) anope_override
+ void OnChannelModeAdd(ChannelMode *cm) override
{
if (DConfig.chanmodes.find(cm->mchar) != Anope::string::npos)
this->ParseModeString();
}
- void OnChannelSync(Channel *c) anope_override
+ void OnChannelSync(Channel *c) override
{
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
c->SetModes(Config->GetClient("OperServ"), false, "%s", DConfig.chanmodes.c_str());
@@ -550,7 +582,7 @@ class OSDefcon : public Module
static void runDefCon()
{
- BotInfo *OperServ = Config->GetClient("OperServ");
+ ServiceBot *OperServ = Config->GetClient("OperServ");
if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
{
if (!DConfig.chanmodes.empty() && !DefConModesSet)
diff --git a/modules/operserv/dns.cpp b/modules/operserv/dns.cpp
new file mode 100644
index 000000000..af07a2499
--- /dev/null
+++ b/modules/operserv/dns.cpp
@@ -0,0 +1,1051 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/dns.h"
+#include "modules/operserv/dns.h"
+
+static std::map<Anope::string, std::list<time_t> > server_quit_times;
+
+class DNSZoneImpl : public DNSZone
+{
+ friend class DNSZoneType;
+
+ Anope::string name;
+
+ public:
+ DNSZoneImpl(Serialize::TypeBase *type) : DNSZone(type) { }
+ DNSZoneImpl(Serialize::TypeBase *type, Serialize::ID id) : DNSZone(type, id) { }
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &) override;
+
+ static DNSZone *Find(const Anope::string &name)
+ {
+ for (DNSZone *zone : Serialize::GetObjects<DNSZone *>())
+ if (zone->GetName().equals_ci(name))
+ return zone;
+ return nullptr;
+ }
+};
+
+class DNSZoneType : public Serialize::Type<DNSZoneImpl>
+{
+ public:
+ Serialize::Field<DNSZoneImpl, Anope::string> name;
+
+ DNSZoneType(Module *creator) : Serialize::Type<DNSZoneImpl>(creator)
+ , name(this, "name", &DNSZoneImpl::name)
+ {
+ }
+};
+
+Anope::string DNSZoneImpl::GetName()
+{
+ return Get(&DNSZoneType::name);
+}
+
+void DNSZoneImpl::SetName(const Anope::string &name)
+{
+ Set(&DNSZoneType::name, name);
+}
+
+class DNSServerImpl : public DNSServer
+{
+ friend class DNSServerType;
+
+ ServiceReference<DNS::Manager> manager;
+
+ DNSZone *zone = nullptr;
+ Anope::string name;
+ unsigned int limit = 0;
+ bool pooled = false;
+
+ /* is actually in the pool */
+ bool active = false;
+
+ public:
+ std::set<Anope::string, ci::less> zones;
+ time_t repool = 0;
+
+ DNSServerImpl(Serialize::TypeBase *type) : DNSServer(type) { }
+ DNSServerImpl(Serialize::TypeBase *type, Serialize::ID id) : DNSServer(type, id) { }
+
+ DNSZone *GetZone() override;
+ void SetZone(DNSZone *) override;
+
+ Anope::string GetName() override;
+ void SetName(const Anope::string &) override;
+
+ unsigned int GetLimit() override;
+ void SetLimit(const unsigned int &) override;
+
+ bool GetPooled() override;
+ void SetPool(const bool &) override;
+
+ bool Active()
+ {
+ return GetPooled() && active;
+ }
+
+ void SetActive(bool p)
+ {
+ if (p)
+ this->SetPool(p);
+ active = p;
+
+ if (manager)
+ {
+ manager->UpdateSerial();
+ for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it)
+ manager->Notify(*it);
+ }
+ }
+
+ static DNSServerImpl *Find(const Anope::string &s)
+ {
+ for (DNSServerImpl *server : Serialize::GetObjects<DNSServerImpl *>())
+ if (server->GetName().equals_ci(s))
+ return server;
+ return nullptr;
+ }
+};
+
+class DNSServerType : public Serialize::Type<DNSServerImpl>
+{
+ public:
+ Serialize::ObjectField<DNSServerImpl, DNSZone *> zone;
+ Serialize::Field<DNSServerImpl, Anope::string> name;
+ Serialize::Field<DNSServerImpl, unsigned int> limit;
+ Serialize::Field<DNSServerImpl, bool> pooled;
+
+ DNSServerType(Module *creator) : Serialize::Type<DNSServerImpl>(creator)
+ , zone(this, "zone", &DNSServerImpl::zone)
+ , name(this, "name", &DNSServerImpl::name)
+ , limit(this, "limit", &DNSServerImpl::limit)
+ , pooled(this, "pooled", &DNSServerImpl::pooled)
+ {
+ }
+};
+
+DNSZone *DNSServerImpl::GetZone()
+{
+ return Get(&DNSServerType::zone);
+}
+
+void DNSServerImpl::SetZone(DNSZone *z)
+{
+ Set(&DNSServerType::zone, z);
+}
+
+Anope::string DNSServerImpl::GetName()
+{
+ return Get(&DNSServerType::name);
+}
+
+void DNSServerImpl::SetName(const Anope::string &n)
+{
+ Set(&DNSServerType::name, n);
+}
+
+unsigned int DNSServerImpl::GetLimit()
+{
+ return Get(&DNSServerType::limit);
+}
+
+void DNSServerImpl::SetLimit(const unsigned int &l)
+{
+ Set(&DNSServerType::limit, l);
+}
+
+bool DNSServerImpl::GetPooled()
+{
+ return Get(&DNSServerType::pooled);
+}
+
+void DNSServerImpl::SetPool(const bool &p)
+{
+ Set(&DNSServerType::pooled, p);
+}
+
+class DNSZoneMembershipImpl : public DNSZoneMembership
+{
+ friend class DNSZoneMembershipType;
+
+ DNSServer *server = nullptr;
+ DNSZone *zone = nullptr;
+
+ public:
+ DNSZoneMembershipImpl(Serialize::TypeBase *type) : DNSZoneMembership(type) { }
+ DNSZoneMembershipImpl(Serialize::TypeBase *type, Serialize::ID id) : DNSZoneMembership(type, id) { }
+
+ DNSServer *GetServer() override;
+ void SetServer(DNSServer *) override;
+
+ DNSZone *GetZone() override;
+ void SetZone(DNSZone *) override;
+
+ static DNSZoneMembership *Find(DNSServer *server, DNSZone *zone)
+ {
+ for (DNSZoneMembership *mem : Serialize::GetObjects<DNSZoneMembership *>())
+ if (mem->GetServer() == server && mem->GetZone() == zone)
+ return mem;
+ return nullptr;
+ }
+};
+
+class DNSZoneMembershipType : public Serialize::Type<DNSZoneMembershipImpl>
+{
+ public:
+ Serialize::ObjectField<DNSZoneMembershipImpl, DNSServer *> server;
+ Serialize::ObjectField<DNSZoneMembershipImpl, DNSZone *> zone;
+
+ DNSZoneMembershipType(Module *creator) : Serialize::Type<DNSZoneMembershipImpl>(creator)
+ , server(this, "server", &DNSZoneMembershipImpl::server)
+ , zone(this, "zone", &DNSZoneMembershipImpl::zone)
+ {
+ }
+};
+
+DNSServer *DNSZoneMembershipImpl::GetServer()
+{
+ return Get(&DNSZoneMembershipType::server);
+}
+
+void DNSZoneMembershipImpl::SetServer(DNSServer *s)
+{
+ Set(&DNSZoneMembershipType::server, s);
+}
+
+DNSZone *DNSZoneMembershipImpl::GetZone()
+{
+ return Get(&DNSZoneMembershipType::zone);
+}
+
+void DNSZoneMembershipImpl::SetZone(DNSZone *z)
+{
+ Set(&DNSZoneMembershipType::zone, z);
+}
+
+class DNSIPImpl : public DNSIP
+{
+ friend class DNSIPType;
+
+ DNSServer *server = nullptr;
+ Anope::string ip;
+
+ public:
+ DNSIPImpl(Serialize::TypeBase *type) : DNSIP(type) { }
+ DNSIPImpl(Serialize::TypeBase *type, Serialize::ID id) : DNSIP(type, id) { }
+
+ DNSServer *GetServer() override;
+ void SetServer(DNSServer *) override;
+
+ Anope::string GetIP() override;
+ void SetIP(const Anope::string &) override;
+};
+
+class DNSIPType : public Serialize::Type<DNSIPImpl>
+{
+ public:
+ Serialize::ObjectField<DNSIPImpl, DNSServer *> server;
+ Serialize::Field<DNSIPImpl, Anope::string> ip;
+
+ DNSIPType(Module *creator) : Serialize::Type<DNSIPImpl>(creator)
+ , server(this, "server", &DNSIPImpl::server)
+ , ip(this, "ip", &DNSIPImpl::ip)
+ {
+ }
+};
+
+DNSServer *DNSIPImpl::GetServer()
+{
+ return Get(&DNSIPType::server);
+}
+
+void DNSIPImpl::SetServer(DNSServer *s)
+{
+ Set(&DNSIPType::server, s);
+}
+
+Anope::string DNSIPImpl::GetIP()
+{
+ return Get(&DNSIPType::ip);
+}
+
+void DNSIPImpl::SetIP(const Anope::string &ip)
+{
+ Set(&DNSIPType::ip, ip);
+}
+
+class CommandOSDNS : public Command
+{
+ ServiceReference<DNS::Manager> manager;
+
+ void DisplayPoolState(CommandSource &source)
+ {
+ std::vector<DNSServerImpl *> servers = Serialize::GetObjects<DNSServerImpl *>();
+
+ if (servers.empty())
+ {
+ source.Reply(_("There are no configured servers."));
+ return;
+ }
+
+ ListFormatter lf(source.GetAccount());
+ lf.AddColumn(_("Server")).AddColumn(_("IP")).AddColumn(_("Limit")).AddColumn(_("State"));
+ for (DNSServerImpl *s : servers)
+ {
+ Server *srv = Server::Find(s->GetName(), true);
+
+ ListFormatter::ListEntry entry;
+ entry["Server"] = s->GetName();
+ entry["Limit"] = s->GetLimit() ? stringify(s->GetLimit()) : Language::Translate(source.GetAccount(), _("None"));
+
+ Anope::string ip_str;
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ ip_str += ip->GetIP() + " ";
+ ip_str.trim();
+ if (ip_str.empty())
+ ip_str = "None";
+ entry["IP"] = ip_str;
+
+ if (s->Active())
+ entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Active"));
+ else if (s->GetPooled())
+ entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Not Active"));
+ else
+ entry["State"] = Language::Translate(source.GetAccount(), _("Unpooled"));
+
+ if (!srv)
+ entry["State"] += Anope::string(" ") + Language::Translate(source.GetAccount(), _("(Split)"));
+
+ lf.AddEntry(entry);
+ }
+
+ std::vector<Anope::string> replies;
+ lf.Process(replies);
+
+ std::vector<DNSZone *> zones = Serialize::GetObjects<DNSZone *>();
+ if (!zones.empty())
+ {
+ ListFormatter lf2(source.GetAccount());
+ lf2.AddColumn(_("Zone")).AddColumn(_("Servers"));
+
+ for (DNSZone *z : zones)
+ {
+ ListFormatter::ListEntry entry;
+ entry["Zone"] = z->GetName();
+
+ Anope::string server_str;
+ for (DNSServer *s : z->GetRefs<DNSServer *>())
+ server_str += s->GetName() + " ";
+ server_str.trim();
+
+ if (server_str.empty())
+ server_str = "None";
+
+ entry["Servers"] = server_str;
+
+ lf2.AddEntry(entry);
+ }
+
+ lf2.Process(replies);
+ }
+
+ for (const Anope::string &r : replies)
+ source.Reply(r);
+ }
+
+ void AddZone(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &zone = params[1];
+
+ if (DNSZoneImpl::Find(zone))
+ {
+ source.Reply(_("Zone \002{0}\002 already exists."), zone);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to add zone " << zone;
+
+ DNSZone *z = Serialize::New<DNSZone *>();
+ z->SetName(zone);
+ source.Reply(_("Added zone \002{0}\002."), zone);
+ }
+
+ void DelZone(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &zone = params[1];
+
+ DNSZone *z = DNSZoneImpl::Find(zone);
+ if (!z)
+ {
+ source.Reply(_("Zone \002{0}\002 does not exist."), zone);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to delete zone " << z->GetName();
+
+ for (DNSZoneMembership *mem : z->GetRefs<DNSZoneMembership *>())
+ mem->Delete();
+
+ if (manager)
+ {
+ manager->UpdateSerial();
+ manager->Notify(z->GetName());
+ }
+
+ source.Reply(_("Zone \002{0}\002 removed."), z->GetName());
+ z->Delete();
+ }
+
+ void AddServer(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServer *s = DNSServerImpl::Find(params[1]);
+ const Anope::string &zone = params.size() > 2 ? params[2] : "";
+
+ if (s)
+ {
+ if (zone.empty())
+ {
+ source.Reply(_("Server \002{0}\002 already exists."), s->GetName());
+ }
+ else
+ {
+ DNSZone *z = DNSZoneImpl::Find(zone);
+ if (!z)
+ {
+ source.Reply(_("Zone \002{0}\002 does not exist."), zone);
+ return;
+ }
+
+ DNSZoneMembership *mem = DNSZoneMembershipImpl::Find(s, z);
+ if (mem)
+ {
+ source.Reply(_("Server \002{0}\002 is already in zone \002{1}\002."), s->GetName(), z->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ mem = Serialize::New<DNSZoneMembership *>();
+ mem->SetZone(z);
+ mem->SetServer(s);
+
+ if (manager)
+ {
+ manager->UpdateSerial();
+ manager->Notify(zone);
+ }
+
+ Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << z->GetName();
+
+ source.Reply(_("Server \002{0}\002 added to zone \002{1}\002."), s->GetName(), z->GetName());
+ }
+
+ return;
+ }
+
+ Server *serv = Server::Find(params[1], true);
+ if (!serv || serv == Me || serv->IsJuped())
+ {
+ source.Reply(_("Server \002{0}\002 is not linked to the network."), params[1]);
+ return;
+ }
+
+ s = Serialize::New<DNSServer *>();
+ s->SetName(params[1]);
+ if (zone.empty())
+ {
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to add server " << s->GetName();
+ source.Reply(_("Added server \002{0}\002."), s->GetName());
+ }
+ else
+ {
+ DNSZone *z = DNSZoneImpl::Find(zone);
+ if (!z)
+ {
+ source.Reply(_("Zone \002{0}\002 does not exist."), zone);
+ s->Delete();
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << zone;
+
+ DNSZoneMembership *mem = Serialize::New<DNSZoneMembership *>();
+ mem->SetServer(s);
+ mem->SetZone(z);
+
+ if (manager)
+ {
+ manager->UpdateSerial();
+ manager->Notify(z->GetName());
+ }
+ }
+ }
+
+ void DelServer(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServer *s = DNSServerImpl::Find(params[1]);
+ const Anope::string &zone = params.size() > 2 ? params[2] : "";
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ if (!zone.empty())
+ {
+ DNSZone *z = DNSZoneImpl::Find(zone);
+ if (!z)
+ {
+ source.Reply(_("Zone \002{0}\002 does not exist."), zone);
+ return;
+ }
+
+ DNSZoneMembership *mem = DNSZoneMembershipImpl::Find(s, z);
+ if (!mem)
+ {
+ source.Reply(_("Server \002{0}\002 is not in zone \002{1}\002."), s->GetName(), z->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to remove server " << s->GetName() << " from zone " << z->GetName();
+
+ if (manager)
+ {
+ manager->UpdateSerial();
+ manager->Notify(z->GetName());
+ }
+
+ mem->Delete();
+ source.Reply(_("Removed server \002{0}\002 from zone \002{1}\002."), s->GetName(), z->GetName());
+ return;
+ }
+
+ if (Server::Find(s->GetName(), true))
+ {
+ source.Reply(_("Server \002{0}\002 must be quit before it can be deleted."), s->GetName());
+ return;
+ }
+
+ for (DNSZoneMembership *mem : s->GetRefs<DNSZoneMembership *>())
+ mem->Delete();
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ if (manager)
+ manager->UpdateSerial();
+
+ Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName();
+ source.Reply(_("Removed server \002{0}\002."), s->GetName());
+ s->Delete();
+ }
+
+ void AddIP(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServerImpl *s = DNSServerImpl::Find(params[1]);
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ if (params[2].equals_ci(ip->GetIP()))
+ {
+ source.Reply(_("IP \002{0}\002 already exists for \002{1}\002."), ip->GetIP(), s->GetName());
+ return;
+ }
+
+ sockaddrs addr(params[2]);
+ if (!addr.valid())
+ {
+ source.Reply(_("\002{0}\002 is not a valid IP address."), params[2]);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ DNSIP *ip = Serialize::New<DNSIP *>();
+ ip->SetServer(s);
+ ip->SetIP(params[2]);
+
+ source.Reply(_("Added IP \002{0}\002 to \002{1}\002."), params[2], s->GetName());
+ Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName();
+
+ if (s->Active() && manager)
+ {
+ manager->UpdateSerial();
+ for (DNSZone *zone : s->GetRefs<DNSZone *>())
+ manager->Notify(zone->GetName());
+ }
+ }
+
+ void DelIP(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServerImpl *s = DNSServerImpl::Find(params[1]);
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ if (params[2].equals_ci(ip->GetIP()))
+ {
+ ip->Delete();
+
+ source.Reply(_("Removed IP \002{0}\002 from \002{1}\002."), params[2], s->GetName());
+ Log(LOG_ADMIN, source, this) << "to remove IP " << params[2] << " from " << s->GetName();
+
+ if (s->GetRefs<DNSIP *>().empty())
+ {
+ s->repool = 0;
+ s->SetPool(false);
+ }
+
+ if (s->Active() && manager)
+ {
+ manager->UpdateSerial();
+ for (DNSZone *zone : s->GetRefs<DNSZone *>())
+ manager->Notify(zone->GetName());
+ }
+
+ return;
+ }
+
+ source.Reply(_("IP \002{0}\002 does not exist for \002{1}\002."), params[2], s->GetName());
+ }
+
+ void OnSet(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServer *s = DNSServerImpl::Find(params[1]);
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ if (params[2].equals_ci("LIMIT"))
+ {
+ try
+ {
+ unsigned l = convertTo<unsigned>(params[3]);
+ s->SetLimit(l);
+ if (l)
+ source.Reply(_("User limit for \002{0}\002 set to \002{1}\002."), s->GetName(), l);
+ else
+ source.Reply(_("User limit for \002{0}\002 removed."), s->GetName());
+ }
+ catch (const ConvertException &ex)
+ {
+ source.Reply(_("Invalid value for limit. Must be numerical."));
+ }
+ }
+ else
+ source.Reply(_("Unknown SET option."));
+ }
+
+ void OnPool(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServerImpl *s = DNSServerImpl::Find(params[1]);
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ if (!Server::Find(s->GetName(), true))
+ {
+ source.Reply(_("Server \002{0}\002 is not currently linked."), s->GetName());
+ return;
+ }
+
+ if (s->GetPooled())
+ {
+ source.Reply(_("Server \002{0}\002 is already pooled."), s->GetName());
+ return;
+ }
+
+ if (s->GetRefs<DNSIP *>().empty())
+ {
+ source.Reply(_("Server \002{0}\002 has no configured IPs."), s->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ s->SetActive(true);
+
+ source.Reply(_("Pooled \002{0}\002."), s->GetName());
+ Log(LOG_ADMIN, source, this) << "to pool " << s->GetName();
+ }
+
+
+ void OnDepool(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ DNSServer *s = DNSServerImpl::Find(params[1]);
+
+ if (!s)
+ {
+ source.Reply(_("Server \002{0}\002 does not exist."), params[1]);
+ return;
+ }
+
+ if (!s->GetPooled())
+ {
+ source.Reply(_("Server \002{0}\002 is not pooled."), s->GetName());
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ s->SetPool(false);
+
+ source.Reply(_("Depooled \002{0}\002."), s->GetName());
+ Log(LOG_ADMIN, source, this) << "to depool " << s->GetName();
+ }
+
+ public:
+ CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 4)
+ {
+ this->SetDesc(_("Manage DNS zones for this network"));
+ this->SetSyntax(_("ADDZONE \037zone.name\037"));
+ this->SetSyntax(_("DELZONE \037zone.name\037"));
+ this->SetSyntax(_("ADDSERVER \037server.name\037 [\037zone.name\037]"));
+ this->SetSyntax(_("DELSERVER \037server.name\037 [\037zone.name\037]"));
+ this->SetSyntax(_("ADDIP \037server.name\037 \037ip\037"));
+ this->SetSyntax(_("DELIP \037server.name\037 \037ip\037"));
+ this->SetSyntax(_("SET \037server.name\037 \037option\037 \037value\037"));
+ this->SetSyntax(_("POOL \037server.name\037"));
+ this->SetSyntax(_("DEPOOL \037server.name\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (params.empty())
+ this->DisplayPoolState(source);
+ else if (params[0].equals_ci("ADDZONE") && params.size() > 1)
+ this->AddZone(source, params);
+ else if (params[0].equals_ci("DELZONE") && params.size() > 1)
+ this->DelZone(source, params);
+ else if (params[0].equals_ci("ADDSERVER") && params.size() > 1)
+ this->AddServer(source, params);
+ else if (params[0].equals_ci("DELSERVER") && params.size() > 1)
+ this->DelServer(source, params);
+ else if (params[0].equals_ci("ADDIP") && params.size() > 2)
+ this->AddIP(source, params);
+ else if (params[0].equals_ci("DELIP") && params.size() > 2)
+ this->DelIP(source, params);
+ else if (params[0].equals_ci("SET") && params.size() > 3)
+ this->OnSet(source, params);
+ else if (params[0].equals_ci("POOL") && params.size() > 1)
+ this->OnPool(source, params);
+ else if (params[0].equals_ci("DEPOOL") && params.size() > 1)
+ this->OnDepool(source, params);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("This command allows managing DNS zones used for controlling what servers users are directed to when connecting."
+ " Omitting all parameters prints out the status of the DNS zone.\n"
+ "\n"
+ "\002{0} ADDZONE\002 adds a zone, eg. us.example.com. Servers can then be added to this zone with the \002ADDSERVER\002 command.\n"
+ "\n"
+ "The \002{0} ADDSERVER\002 command adds a server to the given zone."
+ " When a DNS query is done, the zone in question is served if it exists, otherwise all servers in all zones are served."
+ " A server may be in more than one zone.\n"
+ "\n"
+ "The \002{0} ADDIP\002 command associates an IP with a server.\n"
+ " \n"
+ "The \002{0} POOL\002 and \002{0} DEPOOL\002 commands actually add and remove servers to their given zones."),
+ source.command);
+ return true;
+ }
+};
+
+class ModuleDNS : public Module
+ , public EventHook<Event::NewServer>
+ , public EventHook<Event::ServerQuit>
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::PreUserLogoff>
+ , public EventHook<Event::DnsRequest>
+{
+ DNSZoneType zonetype;
+ DNSServerType servertype;
+ DNSZoneMembershipType zonemembtype;
+ DNSIPType iptype;
+ CommandOSDNS commandosdns;
+
+ time_t ttl = 0;
+ int user_drop_mark = 0;
+ time_t user_drop_time = 0;
+ time_t user_drop_readd_time = 0;
+ bool remove_split_servers = 0;
+ bool readd_connected_servers = 0;
+
+ time_t last_warn = 0;
+
+ public:
+ ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::NewServer>(this)
+ , EventHook<Event::ServerQuit>(this)
+ , EventHook<Event::UserConnect>(this)
+ , EventHook<Event::PreUserLogoff>(this)
+ , EventHook<Event::DnsRequest>(this)
+ , zonetype(this)
+ , servertype(this)
+ , zonemembtype(this)
+ , iptype(this)
+ , commandosdns(this)
+ {
+ /* enable active flag for linked servers */
+ std::vector<DNSServerImpl *> servers = Serialize::GetObjects<DNSServerImpl *>();
+
+ for (DNSServerImpl *s : servers)
+ if (s->GetPooled() && Server::Find(s->GetName(), true))
+ s->SetActive(true);
+ }
+
+ ~ModuleDNS()
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ this->ttl = block->Get<time_t>("ttl");
+ this->user_drop_mark = block->Get<int>("user_drop_mark");
+ this->user_drop_time = block->Get<time_t>("user_drop_time");
+ this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time");
+ this->remove_split_servers = block->Get<bool>("remove_split_servers");
+ this->readd_connected_servers = block->Get<bool>("readd_connected_servers");
+ }
+
+ void OnNewServer(Server *s) override
+ {
+ if (s == Me || s->IsJuped())
+ return;
+ if (!Me->IsSynced() || this->readd_connected_servers)
+ {
+ DNSServerImpl *dns = DNSServerImpl::Find(s->GetName());
+ if (dns && dns->GetPooled() && !dns->Active() && !dns->GetRefs<DNSIP *>().empty())
+ {
+ dns->SetActive(true);
+ Log(this) << "Pooling server " << s->GetName();
+ }
+ }
+ }
+
+ void OnServerQuit(Server *s) override
+ {
+ DNSServerImpl *dns = DNSServerImpl::Find(s->GetName());
+ if (remove_split_servers && dns && dns->GetPooled() && dns->Active())
+ {
+ if (readd_connected_servers)
+ dns->SetActive(false); // Will be reactivated when it comes back
+ else
+ dns->SetPool(false); // Otherwise permanently pull this
+ Log(this) << "Depooling delinked server " << s->GetName();
+ }
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ if (!u->Quitting() && u->server)
+ {
+ DNSServerImpl *s = DNSServerImpl::Find(u->server->GetName());
+ /* Check for user limit reached */
+ if (s && s->GetPooled() && s->Active() && s->GetLimit() && u->server->users >= s->GetLimit())
+ {
+ Log(this) << "Depooling full server " << s->GetName() << ": " << u->server->users << " users";
+ s->SetActive(false);
+ }
+ }
+ }
+
+ void OnPreUserLogoff(User *u) override
+ {
+ if (u && u->server)
+ {
+ DNSServerImpl *s = DNSServerImpl::Find(u->server->GetName());
+ if (!s || !s->GetPooled())
+ return;
+
+ /* Check for dropping under userlimit */
+ if (s->GetLimit() && !s->Active() && s->GetLimit() > u->server->users)
+ {
+ Log(this) << "Pooling server " << s->GetName();
+ s->SetActive(true);
+ }
+
+ if (this->user_drop_mark > 0)
+ {
+ std::list<time_t>& times = server_quit_times[u->server->GetName()];
+ times.push_back(Anope::CurTime);
+ if (times.size() > static_cast<unsigned>(this->user_drop_mark))
+ times.pop_front();
+
+ if (times.size() == static_cast<unsigned>(this->user_drop_mark))
+ {
+ time_t diff = Anope::CurTime - *times.begin();
+
+ /* Check for very fast user drops */
+ if (s->Active() && diff <= this->user_drop_time)
+ {
+ Log(this) << "Depooling server " << s->GetName() << ": dropped " << this->user_drop_mark << " users in " << diff << " seconds";
+ s->repool = Anope::CurTime + this->user_drop_readd_time;
+ s->SetActive(false);
+ }
+ /* Check for needing to re-pool a server that dropped users */
+ else if (!s->Active() && s->repool && s->repool <= Anope::CurTime)
+ {
+ s->SetActive(true);
+ s->repool = 0;
+ Log(this) << "Pooling server " << s->GetName();
+ }
+ }
+ }
+ }
+ }
+
+ void OnDnsRequest(DNS::Query &req, DNS::Query *packet) override
+ {
+ if (req.questions.empty())
+ return;
+ /* Currently we reply to any QR for A/AAAA */
+ const DNS::Question& q = req.questions[0];
+ if (q.type != DNS::QUERY_A && q.type != DNS::QUERY_AAAA && q.type != DNS::QUERY_AXFR && q.type != DNS::QUERY_ANY)
+ return;
+
+ DNSZone *zone = DNSZoneImpl::Find(q.name);
+ size_t answer_size = packet->answers.size();
+ if (zone)
+ {
+ for (DNSServerImpl *s : zone->GetRefs<DNSServerImpl *>())
+ {
+ if (!s->Active())
+ continue;
+
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ {
+ DNS::QueryType q_type = ip->GetIP().find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
+
+ if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
+ {
+ DNS::ResourceRecord rr(q.name, q_type);
+ rr.ttl = this->ttl;
+ rr.rdata = ip->GetIP();
+ packet->answers.push_back(rr);
+ }
+ }
+ }
+ }
+
+ if (packet->answers.size() == answer_size)
+ {
+ /* Default zone */
+ for (DNSServerImpl *s : Serialize::GetObjects<DNSServerImpl *>())
+ {
+ if (!s->Active())
+ continue;
+
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ {
+ DNS::QueryType q_type = ip->GetIP().find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
+
+ if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
+ {
+ DNS::ResourceRecord rr(q.name, q_type);
+ rr.ttl = this->ttl;
+ rr.rdata = ip->GetIP();
+ packet->answers.push_back(rr);
+ }
+ }
+ }
+ }
+
+ if (packet->answers.size() == answer_size)
+ {
+ if (last_warn + 60 < Anope::CurTime)
+ {
+ last_warn = Anope::CurTime;
+ Log(this) << "Warning! There are no pooled servers!";
+ }
+
+ /* Something messed up, just return them all and hope one is available */
+ for (DNSServer *s : Serialize::GetObjects<DNSServer *>())
+ for (DNSIP *ip : s->GetRefs<DNSIP *>())
+ {
+ DNS::QueryType q_type = ip->GetIP().find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
+
+ if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
+ {
+ DNS::ResourceRecord rr(q.name, q_type);
+ rr.ttl = this->ttl;
+ rr.rdata = ip->GetIP();
+ packet->answers.push_back(rr);
+ }
+ }
+
+ if (packet->answers.size() == answer_size)
+ {
+ Log(this) << "Error! There are no servers with any IPs of type " << q.type;
+ /* Send back an empty answer anyway */
+ }
+ }
+ }
+};
+
+MODULE_INIT(ModuleDNS)
diff --git a/modules/operserv/forbid.cpp b/modules/operserv/forbid.cpp
new file mode 100644
index 000000000..a4234fbbf
--- /dev/null
+++ b/modules/operserv/forbid.cpp
@@ -0,0 +1,602 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/operserv/forbid.h"
+#include "modules/nickserv.h"
+#include "modules/chanserv.h"
+
+class ForbidDataImpl : public ForbidData
+{
+ friend class ForbidDataType;
+
+ Anope::string mask, creator, reason;
+ time_t created = 0, expires = 0;
+ ForbidType type = static_cast<ForbidType>(0);
+
+ public:
+ ForbidDataImpl(Serialize::TypeBase *type) : ForbidData(type) { }
+ ForbidDataImpl(Serialize::TypeBase *type, Serialize::ID id) : ForbidData(type, id) { }
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &) override;
+
+ time_t GetExpires() override;
+ void SetExpires(const time_t &) override;
+
+ ForbidType GetType() override;
+ void SetType(const ForbidType &) override;
+};
+
+class ForbidDataType : public Serialize::Type<ForbidDataImpl>
+{
+ public:
+ Serialize::Field<ForbidDataImpl, Anope::string> mask, creator, reason;
+ Serialize::Field<ForbidDataImpl, time_t> created, expires;
+ Serialize::Field<ForbidDataImpl, ForbidType> type;
+
+ ForbidDataType(Module *me) : Serialize::Type<ForbidDataImpl>(me)
+ , mask(this, "mask", &ForbidDataImpl::mask)
+ , creator(this, "creator", &ForbidDataImpl::creator)
+ , reason(this, "reason", &ForbidDataImpl::reason)
+ , created(this, "created", &ForbidDataImpl::created)
+ , expires(this, "expires", &ForbidDataImpl::expires)
+ , type(this, "type", &ForbidDataImpl::type)
+ {
+ }
+};
+
+Anope::string ForbidDataImpl::GetMask()
+{
+ return Get(&ForbidDataType::mask);
+}
+
+void ForbidDataImpl::SetMask(const Anope::string &m)
+{
+ Set(&ForbidDataType::mask, m);
+}
+
+Anope::string ForbidDataImpl::GetCreator()
+{
+ return Get(&ForbidDataType::creator);
+}
+
+void ForbidDataImpl::SetCreator(const Anope::string &c)
+{
+ Set(&ForbidDataType::creator, c);
+}
+
+Anope::string ForbidDataImpl::GetReason()
+{
+ return Get(&ForbidDataType::reason);
+}
+
+void ForbidDataImpl::SetReason(const Anope::string &r)
+{
+ Set(&ForbidDataType::reason, r);
+}
+
+time_t ForbidDataImpl::GetCreated()
+{
+ return Get(&ForbidDataType::created);
+}
+
+void ForbidDataImpl::SetCreated(const time_t &t)
+{
+ Set(&ForbidDataType::created, t);
+}
+
+time_t ForbidDataImpl::GetExpires()
+{
+ return Get(&ForbidDataType::expires);
+}
+
+void ForbidDataImpl::SetExpires(const time_t &t)
+{
+ Set(&ForbidDataType::expires, t);
+}
+
+ForbidType ForbidDataImpl::GetType()
+{
+ return Get(&ForbidDataType::type);
+}
+
+void ForbidDataImpl::SetType(const ForbidType &t)
+{
+ Set(&ForbidDataType::type, t);
+}
+
+class MyForbidService : public ForbidService
+{
+ public:
+ MyForbidService(Module *m) : ForbidService(m)
+ {
+ }
+
+ ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) override
+ {
+ for (ForbidData *d : GetForbids())
+ if (d->GetType() == ftype && Anope::Match(mask, d->GetMask(), false, true))
+ return d;
+ return NULL;
+ }
+
+ std::vector<ForbidData *> GetForbids() override
+ {
+ for (ForbidData *d : Serialize::GetObjects<ForbidData *>())
+ if (d->GetExpires() && !Anope::NoExpire && Anope::CurTime >= d->GetExpires())
+ {
+ Anope::string ftype = "none";
+ if (d->GetType() == FT_NICK)
+ ftype = "nick";
+ else if (d->GetType() == FT_CHAN)
+ ftype = "chan";
+ else if (d->GetType() == FT_EMAIL)
+ ftype = "email";
+
+ Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << d->GetMask() << " type " << ftype;
+ d->Delete();
+ }
+ return Serialize::GetObjects<ForbidData *>();
+ }
+};
+
+class CommandOSForbid : public Command
+{
+ ServiceReference<ForbidService> fs;
+
+ public:
+ CommandOSForbid(Module *creator) : Command(creator, "operserv/forbid", 1, 5)
+ {
+ this->SetDesc(_("Forbid usage of nicknames, channels, and emails"));
+ this->SetSyntax(_("ADD {NICK|CHAN|EMAIL|REGISTER} [+\037expiry\037] \037entry\037 \037reason\037"));
+ this->SetSyntax(_("DEL {NICK|CHAN|EMAIL|REGISTER} \037entry\037"));
+ this->SetSyntax("LIST [NICK|CHAN|EMAIL|REGISTER]");
+ }
+
+ void OnUserNickChange(User *u)
+ {
+ if (u->HasMode("OPER"))
+ return;
+
+ ForbidData *d = fs->FindForbid(u->nick, FT_NICK);
+ if (d != NULL)
+ {
+ ServiceBot *bi = Config->GetClient("NickServ");
+ if (!bi)
+ bi = Config->GetClient("OperServ");
+ if (bi)
+ u->SendMessage(bi, _("This nickname has been forbidden: \002{0}\002"), d->GetReason());
+ if (NickServ::service)
+ NickServ::service->Collide(u, NULL);
+ }
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!this->fs)
+ return;
+
+ const Anope::string &command = params[0];
+ const Anope::string &subcommand = params.size() > 1 ? params[1] : "";
+
+ ForbidType ftype = FT_SIZE;
+ if (subcommand.equals_ci("NICK"))
+ ftype = FT_NICK;
+ else if (subcommand.equals_ci("CHAN"))
+ ftype = FT_CHAN;
+ else if (subcommand.equals_ci("EMAIL"))
+ ftype = FT_EMAIL;
+ else if (subcommand.equals_ci("REGISTER"))
+ ftype = FT_REGISTER;
+
+ if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE)
+ {
+ const Anope::string &expiry = params[2][0] == '+' ? params[2] : "";
+ const Anope::string &entry = !expiry.empty() ? params[3] : params[2];
+ Anope::string reason;
+ if (expiry.empty())
+ reason = params[3] + " ";
+ if (params.size() > 4)
+ reason += params[4];
+ reason.trim();
+
+ if (entry.replace_all_cs("?*", "").empty())
+ {
+ source.Reply(_("The mask must contain at least one non wildcard character."));
+ return;
+ }
+
+ time_t expiryt = 0;
+
+ if (!expiry.empty())
+ {
+ expiryt = Anope::DoTime(expiry);
+ if (expiryt == -1)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ else if (expiryt)
+ expiryt += Anope::CurTime;
+ }
+
+ NickServ::Nick *target = NickServ::FindNick(entry);
+ if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->GetAccount()->IsServicesOper())
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ ForbidData *d = this->fs->FindForbid(entry, ftype);
+ bool created = false;
+ if (d == NULL)
+ {
+ d = Serialize::New<ForbidData *>();
+ created = true;
+ }
+
+ d->SetMask(entry);
+ d->SetCreator(source.GetNick());
+ d->SetReason(reason);
+ d->SetCreated(Anope::CurTime);
+ d->SetExpires(expiryt);
+ d->SetType(ftype);
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand;
+ source.Reply(_("Added a forbid on \002{0}\002 of type \002{1}\002 to expire on \002{2}\002."), entry, subcommand.lower(), expiryt ? Anope::strftime(expiryt, source.GetAccount()) : "never");
+
+ /* apply forbid */
+ switch (ftype)
+ {
+ case FT_NICK:
+ {
+ int na_matches = 0;
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ this->OnUserNickChange(it->second);
+
+ for (auto it = NickServ::service->GetNickList().begin(); it != NickServ::service->GetNickList().end();)
+ {
+ NickServ::Nick *na = *it;
+ ++it;
+
+ d = this->fs->FindForbid(na->GetNick(), FT_NICK);
+ if (d == NULL)
+ continue;
+
+ ++na_matches;
+
+ delete na;
+ }
+
+ source.Reply(_("\002{0}\002 nickname(s) dropped."), na_matches);
+ break;
+ }
+ case FT_CHAN:
+ {
+ int chan_matches = 0, ci_matches = 0;
+
+ for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
+ {
+ Channel *c = it->second;
+ ++it;
+
+ d = this->fs->FindForbid(c->name, FT_CHAN);
+ if (d == NULL)
+ continue;
+
+ ServiceBot *OperServ = Config->GetClient("OperServ");
+ if (IRCD->CanSQLineChannel && OperServ)
+ {
+ time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
+#warning "xline allocated on stack"
+#if 0
+ XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->GetReason());
+ IRCD->SendSQLine(NULL, &x);
+#endif
+ }
+ else if (ChanServ::service)
+ {
+ ChanServ::service->Hold(c);
+ }
+
+ ++chan_matches;
+
+ for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
+ {
+ User *u = cit->first;
+ ++cit;
+
+ if (u->server == Me || u->HasMode("OPER"))
+ continue;
+
+ reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: \002%s\002")), d->GetReason().c_str());
+
+ c->Kick(source.service, u, "%s", reason.c_str());
+ }
+ }
+
+ for (auto it = ChanServ::service->GetChannels().begin(); it != ChanServ::service->GetChannels().end();)
+ {
+ ChanServ::Channel *ci = it->second;
+ ++it;
+
+ d = this->fs->FindForbid(ci->GetName(), FT_CHAN);
+ if (d == NULL)
+ continue;
+
+ ++ci_matches;
+
+ delete ci;
+ }
+
+ source.Reply(_("\002{0}\002 channel(s) cleared, and \002{1}\002 channel(s) dropped."), chan_matches, ci_matches);
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+ else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE)
+ {
+ const Anope::string &entry = params[2];
+
+ ForbidData *d = this->fs->FindForbid(entry, ftype);
+ if (d == nullptr)
+ {
+ source.Reply(_("Forbid on \002{0}\002 was not found."), entry);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to remove forbid on " << d->GetMask() << " of type " << subcommand;
+ source.Reply(_("\002{0}\002 deleted from the \002{1}\002 forbid list."), d->GetMask(), subcommand);
+ d->Delete();
+ }
+ else if (command.equals_ci("LIST"))
+ {
+ const std::vector<ForbidData *> &forbids = this->fs->GetForbids();
+ if (forbids.empty())
+ {
+ source.Reply(_("Forbid list is empty."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Mask")).AddColumn(_("Type")).AddColumn(_("Creator")).AddColumn(_("Expires")).AddColumn(_("Reason"));
+
+ unsigned shown = 0;
+ for (unsigned i = 0; i < forbids.size(); ++i)
+ {
+ ForbidData *d = forbids[i];
+
+ if (ftype != FT_SIZE && ftype != d->GetType())
+ continue;
+
+ Anope::string stype;
+ if (d->GetType() == FT_NICK)
+ stype = "NICK";
+ else if (d->GetType() == FT_CHAN)
+ stype = "CHAN";
+ else if (d->GetType() == FT_EMAIL)
+ stype = "EMAIL";
+ else if (d->GetType() == FT_REGISTER)
+ stype = "REGISTER";
+ else
+ continue;
+
+ ListFormatter::ListEntry entry;
+ entry["Mask"] = d->GetMask();
+ entry["Type"] = stype;
+ entry["Creator"] = d->GetCreator();
+ entry["Expires"] = d->GetExpires() ? Anope::strftime(d->GetExpires(), NULL, true).c_str() : Language::Translate(source.GetAccount(), _("Never"));
+ entry["Reason"] = d->GetReason();
+ list.AddEntry(entry);
+ ++shown;
+ }
+
+ if (!shown)
+ {
+ source.Reply(_("There are no forbids of type \002{0}\002."), subcommand.upper());
+ return;
+ }
+
+ source.Reply(_("Forbid list:"));
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ if (shown >= forbids.size())
+ source.Reply(_("End of forbid list."));
+ else
+ source.Reply(_("End of forbid list - \002{0}\002/\002{1}\002 entries shown."), shown, forbids.size());
+ }
+ else
+ this->OnSyntaxError(source, command);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels, and email addresses. Wildcards are accepted for all entries."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the %s engine. Enclose your pattern in // if this is desired."), regexengine);
+ }
+
+ return true;
+ }
+};
+
+class OSForbid : public Module
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::CheckKick>
+ , public EventHook<Event::PreCommand>
+{
+ MyForbidService forbid_service;
+ ForbidDataType type;
+ CommandOSForbid commandosforbid;
+
+ public:
+ OSForbid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserConnect>(this)
+ , EventHook<Event::UserNickChange>(this)
+ , EventHook<Event::CheckKick>(this)
+ , EventHook<Event::PreCommand>(this)
+ , forbid_service(this)
+ , type(this)
+ , commandosforbid(this)
+ {
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ if (u->Quitting() || exempt)
+ return;
+
+ commandosforbid.OnUserNickChange(u);
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &) override
+ {
+ commandosforbid.OnUserNickChange(u);
+ }
+
+ EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
+ {
+ ServiceBot *OperServ = Config->GetClient("OperServ");
+ if (u->HasMode("OPER") || !OperServ)
+ return EVENT_CONTINUE;
+
+ ForbidData *d = this->forbid_service.FindForbid(c->name, FT_CHAN);
+ if (d != NULL)
+ {
+ if (IRCD->CanSQLineChannel)
+ {
+ time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
+#warning "xline allocated on stack"
+#if 0
+ XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->GetReason());
+ IRCD->SendSQLine(NULL, &x);
+#endif
+ }
+ else if (ChanServ::service)
+ {
+ ChanServ::service->Hold(c);
+ }
+
+ reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: %s")), d->GetReason().c_str());
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
+ {
+ if (command->GetName() == "nickserv/info" && params.size() > 0)
+ {
+ ForbidData *d = this->forbid_service.FindForbid(params[0], FT_NICK);
+ if (d != NULL)
+ {
+ if (source.IsOper())
+ source.Reply(_("Nick \002%s\002 is forbidden by %s: %s"), params[0], d->GetCreator(), d->GetReason());
+ else
+ source.Reply(_("Nick \002%s\002 is forbidden."), params[0]);
+ return EVENT_STOP;
+ }
+ }
+ else if (command->GetName() == "chanserv/info" && params.size() > 0)
+ {
+ ForbidData *d = this->forbid_service.FindForbid(params[0], FT_CHAN);
+ if (d != NULL)
+ {
+ if (source.IsOper())
+ source.Reply(_("Channel \002%s\002 is forbidden by %s: %s"), params[0], d->GetCreator(), d->GetReason());
+ else
+ source.Reply(_("Channel \002%s\002 is forbidden."), params[0]);
+ return EVENT_STOP;
+ }
+ }
+ else if (source.IsOper())
+ return EVENT_CONTINUE;
+ else if (command->GetName() == "nickserv/register" && params.size() > 1)
+ {
+ ForbidData *d = this->forbid_service.FindForbid(source.GetNick(), FT_REGISTER);
+ if (d != NULL)
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), source.GetNick());
+ return EVENT_STOP;
+ }
+
+ d = this->forbid_service.FindForbid(params[1], FT_EMAIL);
+ if (d != NULL)
+ {
+ source.Reply(_("Your email address is not allowed, choose a different one."));
+ return EVENT_STOP;
+ }
+ }
+ else if (command->GetName() == "nickserv/set/email" && params.size() > 0)
+ {
+ ForbidData *d = this->forbid_service.FindForbid(params[0], FT_EMAIL);
+ if (d != NULL)
+ {
+ source.Reply(_("Your email address is not allowed, choose a different one."));
+ return EVENT_STOP;
+ }
+ }
+ else if (command->GetName() == "chanserv/register" && !params.empty())
+ {
+ ForbidData *d = this->forbid_service.FindForbid(params[0], FT_REGISTER);
+ if (d != NULL)
+ {
+ source.Reply(_("Channel \002{0}\002 is currently suspended."), params[0]);
+ return EVENT_STOP;
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(OSForbid)
diff --git a/modules/operserv/ignore.cpp b/modules/operserv/ignore.cpp
new file mode 100644
index 000000000..607163fb9
--- /dev/null
+++ b/modules/operserv/ignore.cpp
@@ -0,0 +1,410 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/operserv/ignore.h"
+
+class IgnoreImpl : public Ignore
+{
+ friend class IgnoreType;
+
+ Anope::string mask, creator, reason;
+ time_t time = 0;
+
+ public:
+ IgnoreImpl(Serialize::TypeBase *type) : Ignore(type) { }
+ IgnoreImpl(Serialize::TypeBase *type, Serialize::ID id) : Ignore(type, id) { }
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &) override;
+
+ time_t GetTime() override;
+ void SetTime(const time_t &) override;
+};
+
+class IgnoreType : public Serialize::Type<IgnoreImpl>
+{
+ public:
+ Serialize::Field<IgnoreImpl, Anope::string> mask, creator, reason;
+ Serialize::Field<IgnoreImpl, time_t> time;
+
+ IgnoreType(Module *me) : Serialize::Type<IgnoreImpl>(me)
+ , mask(this, "mask", &IgnoreImpl::mask)
+ , creator(this, "creator", &IgnoreImpl::creator)
+ , reason(this, "reason", &IgnoreImpl::reason)
+ , time(this, "time", &IgnoreImpl::time)
+ {
+ }
+};
+
+Anope::string IgnoreImpl::GetMask()
+{
+ return Get(&IgnoreType::mask);
+}
+
+void IgnoreImpl::SetMask(const Anope::string &m)
+{
+ Set(&IgnoreType::mask, m);
+}
+
+Anope::string IgnoreImpl::GetCreator()
+{
+ return Get(&IgnoreType::creator);
+}
+
+void IgnoreImpl::SetCreator(const Anope::string &c)
+{
+ Set(&IgnoreType::creator, c);
+}
+
+Anope::string IgnoreImpl::GetReason()
+{
+ return Get(&IgnoreType::reason);
+}
+
+void IgnoreImpl::SetReason(const Anope::string &r)
+{
+ Set(&IgnoreType::reason, r);
+}
+
+time_t IgnoreImpl::GetTime()
+{
+ return Get(&IgnoreType::time);
+}
+
+void IgnoreImpl::SetTime(const time_t &t)
+{
+ Set(&IgnoreType::time, t);
+}
+
+class OSIgnoreService : public IgnoreService
+{
+ public:
+ OSIgnoreService(Module *o) : IgnoreService(o)
+ {
+ }
+
+ Ignore *Find(const Anope::string &mask) override
+ {
+ User *u = User::Find(mask, true);
+ std::vector<Ignore *> ignores = Serialize::GetObjects<Ignore *>();
+ std::vector<Ignore *>::iterator ign = ignores.begin(), ign_end = ignores.end();
+
+ if (u)
+ {
+ for (; ign != ign_end; ++ign)
+ {
+ Entry ignore_mask("", (*ign)->GetMask());
+ if (ignore_mask.Matches(u, true))
+ break;
+ }
+ }
+ else
+ {
+ size_t user, host;
+ Anope::string tmp;
+ /* We didn't get a user.. generate a valid mask. */
+ if ((host = mask.find('@')) != Anope::string::npos)
+ {
+ if ((user = mask.find('!')) != Anope::string::npos)
+ {
+ /* this should never happen */
+ if (user > host)
+ return NULL;
+ tmp = mask;
+ }
+ else
+ /* We have user@host. Add nick wildcard. */
+ tmp = "*!" + mask;
+ }
+ /* We only got a nick.. */
+ else
+ tmp = mask + "!*@*";
+
+ for (; ign != ign_end; ++ign)
+ if (Anope::Match(tmp, (*ign)->GetMask(), false, true))
+ break;
+ }
+
+ /* Check whether the entry has timed out */
+ if (ign != ign_end)
+ {
+ Ignore *id = *ign;
+
+ if (id->GetTime() && !Anope::NoExpire && id->GetTime() <= Anope::CurTime)
+ {
+ Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->GetMask();
+ id->Delete();
+ }
+ else
+ return id;
+ }
+
+ return NULL;
+ }
+};
+
+class CommandOSIgnore : public Command
+{
+ ServiceReference<IgnoreService> ignore_service;
+
+ private:
+ Anope::string RealMask(const Anope::string &mask)
+ {
+ /* If it s an existing user, we ignore the hostmask. */
+ User *u = User::Find(mask, true);
+ if (u)
+ return "*!*@" + u->host;
+
+ size_t host = mask.find('@');
+ /* Determine whether we get a nick or a mask. */
+ if (host != Anope::string::npos)
+ {
+ size_t user = mask.find('!');
+ /* Check whether we have a nick too.. */
+ if (user != Anope::string::npos)
+ {
+ if (user > host)
+ /* this should never happen */
+ return "";
+ else
+ return mask;
+ }
+ else
+ /* We have user@host. Add nick wildcard. */
+ return "*!" + mask;
+ }
+
+ /* We only got a nick.. */
+ return mask + "!*@*";
+ }
+
+ void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &time = params.size() > 1 ? params[1] : "";
+ const Anope::string &nick = params.size() > 2 ? params[2] : "";
+ const Anope::string &reason = params.size() > 3 ? params[3] : "";
+
+ if (time.empty() || nick.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ time_t t = Anope::DoTime(time);
+
+ if (t <= -1)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), time);
+ return;
+ }
+
+ Anope::string mask = RealMask(nick);
+ if (mask.empty())
+ {
+ source.Reply(_("Mask must be in the form \037user\037@\037host\037."));
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Ignore *ign = Serialize::New<Ignore *>();
+ ign->SetMask(mask);
+ ign->SetCreator(source.GetNick());
+ ign->SetReason(reason);
+ ign->SetTime(t ? Anope::CurTime + t : 0);
+
+ if (!t)
+ {
+ source.Reply(_("\002{0}\002 will now permanently be ignored."), mask);
+ Log(LOG_ADMIN, source, this) << "to add a permanent ignore for " << mask;
+ }
+ else
+ {
+ source.Reply(_("\002{0}\002 will now be ignored for \002{1}\002."), mask, Anope::Duration(t, source.GetAccount()));
+ Log(LOG_ADMIN, source, this) << "to add an ignore on " << mask << " for " << Anope::Duration(t);
+ }
+ }
+
+ void DoList(CommandSource &source)
+ {
+ std::vector<Ignore *> ignores = Serialize::GetObjects<Ignore *>();
+
+ for (Ignore *id : ignores)
+ {
+ if (id->GetTime() && !Anope::NoExpire && id->GetTime() <= Anope::CurTime)
+ {
+ Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->GetMask();
+ id->Delete();
+ }
+ }
+
+ ignores = Serialize::GetObjects<Ignore *>();
+ if (ignores.empty())
+ {
+ source.Reply(_("Ignore list is empty."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Reason")).AddColumn(_("Expires"));
+
+ for (Ignore *ignore : ignores)
+ {
+ ListFormatter::ListEntry entry;
+ entry["Mask"] = ignore->GetMask();
+ entry["Creator"] = ignore->GetCreator();
+ entry["Reason"] = ignore->GetReason();
+ entry["Expires"] = Anope::Expires(ignore->GetTime(), source.GetAccount());
+ list.AddEntry(entry);
+ }
+
+ source.Reply(_("Services ignore list:"));
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (const Anope::string &r : replies)
+ source.Reply(r);
+ }
+
+ void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string nick = params.size() > 1 ? params[1] : "";
+ if (nick.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ Anope::string mask = RealMask(nick);
+ if (mask.empty())
+ {
+ source.Reply(_("Mask must be in the form \037user\037@\037host\037."));
+ return;
+ }
+
+ Ignore *ign = ignore_service->Find(mask);
+ if (!ign)
+ {
+ source.Reply(_("\002{0}\002 not found on ignore list."), mask);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "to remove an ignore on " << mask;
+ source.Reply(_("\002{0}\002 will no longer be ignored."), mask);
+ ign->Delete();
+ }
+
+ void DoClear(CommandSource &source)
+ {
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ for (Ignore *ign : Serialize::GetObjects<Ignore *>())
+ ign->Delete();
+
+ Log(LOG_ADMIN, source, this) << "to CLEAR the list";
+ source.Reply(_("Ignore list has been cleared."));
+ }
+
+ public:
+ CommandOSIgnore(Module *creator) : Command(creator, "operserv/ignore", 1, 4)
+ {
+ this->SetDesc(_("Modify the Services ignore list"));
+ this->SetSyntax(_("ADD \037expiry\037 {\037nick\037|\037mask\037} [\037reason\037]"));
+ this->SetSyntax(_("DEL {\037nick\037|\037mask\037}"));
+ this->SetSyntax("LIST");
+ this->SetSyntax("CLEAR");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, params);
+ else if (cmd.equals_ci("LIST"))
+ return this->DoList(source);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, params);
+ else if (cmd.equals_ci("CLEAR"))
+ return this->DoClear(source);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("The \002{0}\002 command allows you to make services ignore a user or hostmask."
+ " \037expiry\037 must be an integer and can be followed by one of \037d\037 (days), \037h\037 (hours), or \037m\037 (minutes)."
+ " If a unit specifier is not included, the default is seconds."
+ " To make services permanently ignore the user, use 0 as the expiry time."
+ " When adding a \037mask\037, it should be in the format nick!user@host, everything else will be considered a nicknames. Wildcards are permitted."),
+ source.command);
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the \002{0}\002 engine. Enclose your pattern in // if this is desired."), regexengine);
+ }
+
+ return true;
+ }
+};
+
+class OSIgnore : public Module
+ , public EventHook<Event::BotPrivmsg>
+{
+ IgnoreType ignoretype;
+ OSIgnoreService osignoreservice;
+ CommandOSIgnore commandosignore;
+
+ public:
+ OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::BotPrivmsg>(this)
+ , ignoretype(this)
+ , osignoreservice(this)
+ , commandosignore(this)
+ {
+
+ }
+
+ EventReturn OnBotPrivmsg(User *u, ServiceBot *bi, Anope::string &message) override
+ {
+ if (!u->HasMode("OPER") && this->osignoreservice.Find(u->nick))
+ return EVENT_STOP;
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(OSIgnore)
diff --git a/modules/operserv/info.cpp b/modules/operserv/info.cpp
new file mode 100644
index 000000000..ab97b9b14
--- /dev/null
+++ b/modules/operserv/info.cpp
@@ -0,0 +1,280 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "module.h"
+#include "modules/nickserv/info.h"
+#include "modules/chanserv/info.h"
+#include "modules/operserv/info.h"
+
+class OperInfoImpl : public OperInfo
+{
+ friend class OperInfoType;
+
+ Serialize::Object *target = nullptr;
+ Anope::string info, creator;
+ time_t created = 0;
+
+ public:
+ OperInfoImpl(Serialize::TypeBase *type) : OperInfo(type) { }
+ OperInfoImpl(Serialize::TypeBase *type, Serialize::ID id) : OperInfo(type, id) { }
+
+ Serialize::Object *GetTarget() override;
+ void SetTarget(Serialize::Object *) override;
+
+ Anope::string GetInfo() override;
+ void SetInfo(const Anope::string &) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &) override;
+};
+
+class OperInfoType : public Serialize::Type<OperInfoImpl>
+{
+ public:
+ Serialize::ObjectField<OperInfoImpl, Serialize::Object *> target;
+ Serialize::Field<OperInfoImpl, Anope::string> info, creator;
+ Serialize::Field<OperInfoImpl, time_t> created;
+
+ OperInfoType(Module *c) : Serialize::Type<OperInfoImpl>(c)
+ , target(this, "target", &OperInfoImpl::target, true)
+ , info(this, "info", &OperInfoImpl::info)
+ , creator(this, "adder", &OperInfoImpl::creator)
+ , created(this, "created", &OperInfoImpl::created)
+ {
+ }
+};
+
+Serialize::Object *OperInfoImpl::GetTarget()
+{
+ return Get(&OperInfoType::target);
+}
+
+void OperInfoImpl::SetTarget(Serialize::Object *t)
+{
+ Set(&OperInfoType::target, t);
+}
+
+Anope::string OperInfoImpl::GetInfo()
+{
+ return Get(&OperInfoType::info);
+}
+
+void OperInfoImpl::SetInfo(const Anope::string &i)
+{
+ Set(&OperInfoType::info, i);
+}
+
+Anope::string OperInfoImpl::GetCreator()
+{
+ return Get(&OperInfoType::creator);
+}
+
+void OperInfoImpl::SetCreator(const Anope::string &c)
+{
+ Set(&OperInfoType::creator, c);
+}
+
+time_t OperInfoImpl::GetCreated()
+{
+ return Get(&OperInfoType::created);
+}
+
+void OperInfoImpl::SetCreated(const time_t &t)
+{
+ Set(&OperInfoType::created, t);
+}
+
+class CommandOSInfo : public Command
+{
+ public:
+ CommandOSInfo(Module *creator) : Command(creator, "operserv/info", 2, 3)
+ {
+ this->SetDesc(_("Associate oper info with a nick or channel"));
+ this->SetSyntax(_("ADD \037target\037 \037info\037"));
+ this->SetSyntax(_("DEL \037target\037 \037info\037"));
+ this->SetSyntax(_("CLEAR \037target\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0], target = params[1], info = params.size() > 2 ? params[2] : "";
+
+ Serialize::Object *e;
+ if (IRCD->IsChannelValid(target))
+ {
+ ChanServ::Channel *ci = ChanServ::Find(target);
+ if (!ci)
+ {
+ source.Reply(_("Channel \002{0}\002 isn't registered."), target);
+ return;
+ }
+
+ e = ci;
+ }
+ else
+ {
+ NickServ::Nick *na = NickServ::FindNick(target);
+ if (!na)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), target);
+ return;
+ }
+
+ e = na->GetAccount();
+ }
+
+ if (cmd.equals_ci("ADD"))
+ {
+ if (info.empty())
+ {
+ this->OnSyntaxError(source, cmd);
+ return;
+ }
+
+ std::vector<OperInfo *> oinfos = e->GetRefs<OperInfo *>();
+ if (oinfos.size() >= Config->GetModule(this->module)->Get<unsigned int>("max", "10"))
+ {
+ source.Reply(_("The oper info list for \002{0}\002 is full."), target);
+ return;
+ }
+
+ for (OperInfo *o : oinfos)
+ if (o->GetInfo().equals_ci(info))
+ {
+ source.Reply(_("The oper info already exists on \002{0}\002."), target);
+ return;
+ }
+
+ OperInfo *o = Serialize::New<OperInfo *>();
+ o->SetTarget(e);
+ o->SetInfo(info);
+ o->SetCreator(source.GetNick());
+ o->SetCreated(Anope::CurTime);
+
+ source.Reply(_("Added info to \002{0}\002."), target);
+ Log(LOG_ADMIN, source, this) << "to add information to " << target;
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+ else if (cmd.equals_ci("DEL"))
+ {
+ if (info.empty())
+ {
+ this->OnSyntaxError(source, cmd);
+ return;
+ }
+
+ std::vector<OperInfo *> oinfos = e->GetRefs<OperInfo *>();
+ if (oinfos.empty())
+ {
+ source.Reply(_("Oper info list for \002{0}\002 is empty."), target);
+ return;
+ }
+
+ for (OperInfo *o : oinfos)
+ {
+ if (o->GetInfo().equals_ci(info))
+ {
+ o->Delete();
+
+ source.Reply(_("Deleted info from \002{0}\002."), target);
+ Log(LOG_ADMIN, source, this) << "to remove information from " << target;
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ return;
+ }
+ }
+
+ source.Reply(_("No such info \002{0}\002 on \002{1}\002."), info, target);
+ }
+ else if (cmd.equals_ci("CLEAR"))
+ {
+ std::vector<OperInfo *> oinfos = e->GetRefs<OperInfo *>();
+
+ if (oinfos.empty())
+ {
+ source.Reply(_("Oper info list for \002{0}\002 is empty."), target);
+ return;
+ }
+
+ for (OperInfo *o : oinfos)
+ o->Delete();
+
+ source.Reply(_("Cleared info from \002{0}\002."), target);
+ Log(LOG_ADMIN, source, this) << "to clear information for " << target;
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+ else
+ {
+ this->OnSyntaxError(source, cmd);
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Add or delete oper information for a given accpint or channel. This informaition will show to opers in the respective info command for the account or channel."));
+ return true;
+ }
+};
+
+class OSInfo : public Module
+ , public EventHook<Event::NickInfo>
+ , public EventHook<Event::ChanInfo>
+{
+ CommandOSInfo commandosinfo;
+ OperInfoType oinfotype;
+
+ void OnInfo(CommandSource &source, Serialize::Object *e, InfoFormatter &info)
+ {
+ if (!source.IsOper())
+ return;
+
+ for (OperInfo *o : e->GetRefs<OperInfo *>())
+ info[_("Oper Info")] = Anope::printf(_("(by %s on %s) %s"), o->GetCreator().c_str(), Anope::strftime(o->GetCreated(), source.GetAccount(), true).c_str(), o->GetInfo().c_str());
+ }
+
+ public:
+ OSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::NickInfo>(this)
+ , EventHook<Event::ChanInfo>(this)
+ , commandosinfo(this)
+ , oinfotype(this)
+ {
+ }
+
+ void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override
+ {
+ OnInfo(source, na->GetAccount(), info);
+ }
+
+ void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_hidden) override
+ {
+ OnInfo(source, ci, info);
+ }
+};
+
+MODULE_INIT(OSInfo)
diff --git a/modules/operserv/jupe.cpp b/modules/operserv/jupe.cpp
new file mode 100644
index 000000000..ccffcaf2a
--- /dev/null
+++ b/modules/operserv/jupe.cpp
@@ -0,0 +1,80 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSJupe : public Command
+{
+ public:
+ CommandOSJupe(Module *creator) : Command(creator, "operserv/jupe", 1, 2)
+ {
+ this->SetDesc(_("\"Jupiter\" a server"));
+ this->SetSyntax(_("\037server\037 [\037reason\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &jserver = params[0];
+ const Anope::string &reason = params.size() > 1 ? params[1] : "";
+ Server *server = Server::Find(jserver, true);
+
+ if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos)
+ source.Reply(_("\002{0}\002 is not a valid server name."), jserver);
+ else if (server == Me || server == Servers::GetUplink() || server->IsULined())
+ source.Reply(_("You can not jupe Servoces or its uplink server."));
+ else if (server && server->IsJuped())
+ source.Reply(_("You can not jupe an already juped server."));
+ else
+ {
+ Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : "");
+ /* Generate the new sid before quitting the old server, so they can't collide */
+ Anope::string sid = IRCD->SID_Retrieve();
+ if (server)
+ {
+ IRCD->SendSquit(server, rbuf);
+ server->Delete(rbuf);
+ }
+ Server *juped_server = new Server(Me, jserver, 1, rbuf, sid, true);
+ IRCD->SendServer(juped_server);
+
+ Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")";
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Tells services to jupiter a server -- that is, to create a fake \"server\" connected to Services which prevents the real server of that name from connecting."
+ " The jupe may be removed using a standard \002SQUIT\002. If a reason is given, it is placed in the server information field; otherwise, the server information field will contain the text \"Juped by <nick>\", showing the nickname of the person who jupitered the server."));
+ return true;
+ }
+};
+
+class OSJupe : public Module
+{
+ CommandOSJupe commandosjupe;
+
+ public:
+ OSJupe(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosjupe(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSJupe)
diff --git a/modules/operserv/kick.cpp b/modules/operserv/kick.cpp
new file mode 100644
index 000000000..7f1c20670
--- /dev/null
+++ b/modules/operserv/kick.cpp
@@ -0,0 +1,89 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSKick : public Command
+{
+ public:
+ CommandOSKick(Module *creator) : Command(creator, "operserv/kick", 3, 3)
+ {
+ this->SetDesc(_("Kick a user from a channel"));
+ this->SetSyntax(_("\037channel\037 \037user\037 \037reason\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &chan = params[0];
+ const Anope::string &nick = params[1];
+ const Anope::string &s = params[2];
+ Channel *c;
+ User *u2;
+
+ if (!(c = Channel::Find(chan)))
+ {
+ source.Reply(_("Channel \002%s\002 doesn't exist."), chan);
+ return;
+ }
+
+ if (c->bouncy_modes)
+ {
+ source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
+ return;
+ }
+
+ if (!(u2 = User::Find(nick, true)))
+ {
+ source.Reply(_("\002{0}\002 isn't currently online."), nick);
+ return;
+ }
+
+ if (!c->Kick(source.service, u2, "%s (%s)", source.GetNick().c_str(), s.c_str()))
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "on " << u2->nick << " in " << c->name << " (" << s << ")";
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows you to kick a user from any channel. Parameters are the same as for the standard /KICK command."
+ " The kick message will have the nickname of the IRCop sending the KICK command prepended; for example:\n"
+ "\n"
+ "*** SpamMan has been kicked off channel #my_channel by {0} (Alcan (Flood))"),
+ source.service->nick);
+ return true;
+ }
+};
+
+class OSKick : public Module
+{
+ CommandOSKick commandoskick;
+
+ public:
+ OSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandoskick(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSKick)
diff --git a/modules/commands/os_kill.cpp b/modules/operserv/kill.cpp
index 12fcda99e..b2745272e 100644
--- a/modules/commands/os_kill.cpp
+++ b/modules/operserv/kill.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,16 +28,16 @@ class CommandOSKill : public Command
this->SetSyntax(_("\037user\037 [\037reason\037]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &nick = params[0];
Anope::string reason = params.size() > 1 ? params[1] : "";
User *u2 = User::Find(nick, true);
if (u2 == NULL)
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), nick);
else if (u2->IsProtected() || u2->server == Me)
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("\002{0}\002 is protected and cannot be killed."), u2->nick);
else
{
if (reason.empty())
@@ -41,13 +49,9 @@ class CommandOSKill : public Command
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to kill a user from the network.\n"
- "Parameters are the same as for the standard /KILL\n"
- "command."));
+ source.Reply(_("Allows you to kill a user from the network. Parameters are the same as for the standard /KILL command."));
return true;
}
};
@@ -57,8 +61,8 @@ class OSKill : public Module
CommandOSKill commandoskill;
public:
- OSKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoskill(this)
+ OSKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandoskill(this)
{
}
diff --git a/modules/commands/os_list.cpp b/modules/operserv/list.cpp
index 27e02cb0a..00b7bf746 100644
--- a/modules/commands/os_list.cpp
+++ b/modules/operserv/list.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSChanList : public Command
this->SetSyntax(_("[{\037pattern\037 | \037nick\037} [\037SECRET\037]]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &pattern = !params.empty() ? params[0] : "";
const Anope::string &opt = params.size() > 1 ? params[1] : "";
@@ -43,7 +51,7 @@ class CommandOSChanList : public Command
if (!pattern.empty() && (u2 = User::Find(pattern, true)))
{
- source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str());
+ source.Reply(_("Channel list for \002{0}\002:"), u2->nick);
for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit)
{
@@ -95,24 +103,18 @@ class CommandOSChanList : public Command
source.Reply(_("End of channel list."));
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all channels currently in use on the IRC network, whether they\n"
- "are registered or not.\n"
- " \n"
- "If \002pattern\002 is given, lists only channels that match it. If a nickname\n"
- "is given, lists only the channels the user using it is on. If SECRET is\n"
- "specified, lists only channels matching \002pattern\002 that have the +s or\n"
- "+p mode."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
+ source.Reply(_("Lists all channels currently in use on the IRC network, whether they are registered or not.\n"
+ "\n"
+ "If \002pattern\002 is given, lists only channels that match it. If a nicknam is given, lists only the channels the user using it is on."
+ " If SECRET is specified, lists only channels matching \002pattern\002 that have the +s or +p mode."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
if (!regexengine.empty())
{
source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your pattern in // if this is desired."), regexengine);
}
return true;
@@ -128,7 +130,7 @@ class CommandOSUserList : public Command
this->SetSyntax(_("[{\037pattern\037 | \037channel\037} [\037INVISIBLE\037]]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &pattern = !params.empty() ? params[0] : "";
const Anope::string &opt = params.size() > 1 ? params[1] : "";
@@ -148,7 +150,7 @@ class CommandOSUserList : public Command
if (!pattern.empty() && (c = Channel::Find(pattern)))
{
- source.Reply(_("\002%s\002 users list:"), pattern.c_str());
+ source.Reply(_("User list for \002{0}\002:"), pattern);
for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit)
{
@@ -206,19 +208,16 @@ class CommandOSUserList : public Command
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
this->SendSyntax(source);
source.Reply(" ");
- source.Reply(_("Lists all users currently online on the IRC network, whether their\n"
- "nick is registered or not.\n"
- " \n"
- "If \002pattern\002 is given, lists only users that match it (it must be in\n"
- "the format nick!user@host). If \002channel\002 is given, lists only users\n"
- "that are on the given channel. If INVISIBLE is specified, only users\n"
- "with the +i flag will be listed."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
+ source.Reply(_("Lists all users currently online on the IRC network, whether their nickname is registered or not.\n"
+ "\n"
+ "If \002pattern\002 is given, lists only users that match it (it must be in the format nick!user@host)."
+ " If \002channel\002 is given, lists only users that are on the given channel. If INVISIBLE is specified, only users with the +i flag will be listed."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
if (!regexengine.empty())
{
source.Reply(" ");
@@ -236,8 +235,9 @@ class OSList : public Module
CommandOSUserList commandosuserlist;
public:
- OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoschanlist(this), commandosuserlist(this)
+ OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandoschanlist(this)
+ , commandosuserlist(this)
{
}
diff --git a/modules/operserv/login.cpp b/modules/operserv/login.cpp
new file mode 100644
index 000000000..180024eac
--- /dev/null
+++ b/modules/operserv/login.cpp
@@ -0,0 +1,156 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSLogin : public Command
+{
+ public:
+ CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1)
+ {
+ this->SetSyntax(_("\037password\037"));
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &password = params[0];
+
+ User *u = source.GetUser();
+ Oper *o = source.nc->o;
+ if (o == NULL)
+ {
+ source.Reply(_("No oper block for your nickname."));
+ return;
+ }
+
+ if (o->GetPassword().empty())
+ {
+ source.Reply(_("Your oper block doesn't require logging in."));
+ return;
+ }
+
+ if (u->HasExtOK("os_login"))
+ {
+ source.Reply(_("You are already logged in."));
+ return;
+ }
+
+ if (o->GetPassword() != password)
+ {
+ source.Reply(_("Password incorrect."));
+ u->BadPassword();
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this) << "and successfully identified to " << source.service->nick;
+ u->Extend<bool>("os_login", true);
+ source.Reply(_("Password accepted."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Logs you in to {0} so you gain Services Operator privileges. This command is unnecessary if your oper block is configured without a password."), source.service->nick);
+ return true;
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Login to %s")), source.service->nick.c_str());
+ }
+};
+
+class CommandOSLogout : public Command
+{
+ public:
+ CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0)
+ {
+ this->RequireUser(true);
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ User *u = source.GetUser();
+ Oper *o = source.nc->o;
+ if (o == NULL)
+ {
+ source.Reply(_("No oper block for your nick."));
+ return;
+ }
+
+ if (o->GetPassword().empty())
+ {
+ source.Reply(_("Your oper block doesn't require logging in."));
+ return;
+ }
+
+ if (!u->HasExtOK("os_login"))
+ {
+ source.Reply(_("You are not identified."));
+ return;
+ }
+
+ Log(LOG_ADMIN, source, this);
+ u->Shrink<bool>("os_login");
+ source.Reply(_("You have been logged out."));
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Logs you out from %s so you lose Services Operator privileges. This command is only useful if your oper block is configured with a password."), source.service->nick);
+ return true;
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Logout from %s")), source.service->nick.c_str());
+ }
+};
+
+class OSLogin : public Module
+ , public EventHook<Event::IsServicesOperEvent>
+{
+ CommandOSLogin commandoslogin;
+ CommandOSLogout commandoslogout;
+ ExtensibleItem<bool> os_login;
+
+ public:
+ OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::IsServicesOperEvent>(this)
+ , commandoslogin(this)
+ , commandoslogout(this)
+ , os_login(this, "os_login")
+ {
+
+ }
+
+ EventReturn IsServicesOper(User *u) override
+ {
+ if (!u->Account()->o->GetPassword().empty())
+ {
+ if (os_login.HasExt(u))
+ return EVENT_ALLOW;
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(OSLogin)
diff --git a/modules/commands/os_logsearch.cpp b/modules/operserv/logsearch.cpp
index f8ee99d4e..85a5834a7 100644
--- a/modules/commands/os_logsearch.cpp
+++ b/modules/operserv/logsearch.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -18,7 +26,7 @@ class CommandOSLogSearch : public Command
char timestamp[32];
tm *tm = localtime(&t);
-
+
strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
return Anope::LogDir + "/" + file + "." + timestamp;
@@ -31,7 +39,7 @@ class CommandOSLogSearch : public Command
this->SetSyntax(_("[+\037days\037d] [+\037limit\037l] \037pattern\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
int days = 7, replies = 50;
@@ -52,7 +60,7 @@ class CommandOSLogSearch : public Command
}
catch (const ConvertException &)
{
- source.Reply(_("Invalid duration %s, using %d days."), dur.c_str(), days);
+ source.Reply(_("Invalid duration \002{0}\002, using \002{1}\002 days."), dur, days);
}
}
break;
@@ -68,12 +76,12 @@ class CommandOSLogSearch : public Command
}
catch (const ConvertException &)
{
- source.Reply(_("Invalid limit %s, using %d."), dur.c_str(), replies);
+ source.Reply(_("Invalid limit \002{0}\002, using \002{1}\002."), dur, replies);
}
}
break;
default:
- source.Reply(_("Unknown parameter: %s"), params[i].c_str());
+ source.Reply(_("Unknown parameter: {0}"), params[i]);
}
}
@@ -89,7 +97,7 @@ class CommandOSLogSearch : public Command
Log(LOG_ADMIN, source, this) << "for " << search_string;
- const Anope::string &logfile_name = Config->GetModule(this->owner)->Get<const Anope::string>("logname");
+ const Anope::string &logfile_name = Config->GetModule(this->GetOwner())->Get<Anope::string>("logname");
std::list<Anope::string> matches;
for (int d = days - 1; d >= 0; --d)
{
@@ -109,35 +117,30 @@ class CommandOSLogSearch : public Command
unsigned found = matches.size();
if (!found)
{
- source.Reply(_("No matches for \002%s\002 found."), search_string.c_str());
+ source.Reply(_("No matches for \002{0}\002 found."), search_string);
return;
}
while (matches.size() > static_cast<unsigned>(replies))
matches.pop_front();
- source.Reply(_("Matches for \002%s\002:"), search_string.c_str());
+ source.Reply(_("Matches for \002{0}\002:"), search_string);
unsigned count = 0;
for (std::list<Anope::string>::iterator it = matches.begin(), it_end = matches.end(); it != it_end; ++it)
source.Reply("#%d: %s", ++count, it->c_str());
- source.Reply(_("Showed %d/%d matches for \002%s\002."), matches.size(), found, search_string.c_str());
+ source.Reply(_("Showed \002{0}/{1}\002 matches for \002{2}\002."), matches.size(), found, search_string);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command searches the Services logfiles for messages\n"
- "that match the given pattern. The day and limit argument\n"
- "may be used to specify how many days of logs to search\n"
- "and the number of replies to limit to. By default this\n"
- "command searches one week of logs, and limits replies\n"
- "to 50.\n"
- " \n"
- "For example:\n"
- " \002LOGSEARCH +21d +500l Anope\002\n"
- " Searches the last 21 days worth of logs for messages\n"
- " containing Anope and lists the most recent 500 of them."));
+ source.Reply(_("This command searches the Services logfiles for messages that match the given pattern."
+ " The day and limit argument may be used to specify how many days of logs to search and the number of replies to limit to."
+ " By default this command searches one week of logs, and limits replies to 50.\n"
+ "\n"
+ "Example:\n"
+ " {0} +21d +500l Anope\n"
+ " Searches the last 21 days worth of logs for messages containing \"Anope\" and lists the most recent 500 of them."),
+ source.command);
return true;
}
};
@@ -147,8 +150,8 @@ class OSLogSearch : public Module
CommandOSLogSearch commandoslogsearch;
public:
- OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoslogsearch(this)
+ OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandoslogsearch(this)
{
}
};
diff --git a/modules/operserv/main/CMakeLists.txt b/modules/operserv/main/CMakeLists.txt
new file mode 100644
index 000000000..781f0ef1f
--- /dev/null
+++ b/modules/operserv/main/CMakeLists.txt
@@ -0,0 +1 @@
+build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/operserv/main/operserv.cpp b/modules/operserv/main/operserv.cpp
new file mode 100644
index 000000000..09dc3bbac
--- /dev/null
+++ b/modules/operserv/main/operserv.cpp
@@ -0,0 +1,329 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/help.h"
+#include "modules/nickserv.h"
+
+class SGLineManager : public XLineManager
+{
+ public:
+ SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { }
+
+ void OnMatch(User *u, XLine *x) override
+ {
+ this->Send(u, x);
+ }
+
+ void OnExpire(XLine *x) override
+ {
+ ::Log(Config->GetClient("OperServ"), "expire/akill") << "AKILL on \002" << x->GetMask() << "\002 has expired";
+ }
+
+ void Send(User *u, XLine *x) override
+ {
+ IRCD->SendAkill(u, x);
+ }
+
+ void SendDel(XLine *x) override
+ {
+ IRCD->SendAkillDel(x);
+ }
+
+ bool Check(User *u, XLine *x) override
+ {
+ if (x->regex)
+ {
+ Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname;
+ return std::regex_match(uh.str(), *x->regex) || std::regex_match(nuhr.str(), *x->regex);
+ }
+
+ if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick()))
+ return false;
+
+ if (!x->GetUser().empty() && !Anope::Match(u->GetIdent(), x->GetUser()))
+ return false;
+
+ if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal()))
+ return false;
+
+ if (x->c && x->c->match(u->ip))
+ return true;
+
+ if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip.addr(), x->GetHost()))
+ return true;
+
+ return false;
+ }
+};
+
+class SQLineManager : public XLineManager
+{
+ public:
+ SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q') { }
+
+ void OnMatch(User *u, XLine *x) override
+ {
+ this->Send(u, x);
+ }
+
+ void OnExpire(XLine *x) override
+ {
+ ::Log(Config->GetClient("OperServ"), "expire/sqline") << "SQLINE on \002" << x->GetMask() << "\002 has expired";
+ }
+
+ void Send(User *u, XLine *x) override
+ {
+ if (!IRCD->CanSQLine)
+ {
+ if (!u)
+ ;
+ else if (NickServ::service)
+ NickServ::service->Collide(u, NULL);
+ else
+ u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->GetReason());
+ }
+ else if (x->IsRegex())
+ {
+ if (u)
+ u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->GetReason());
+ }
+ else if (x->GetMask()[0] != '#' || IRCD->CanSQLineChannel)
+ {
+ IRCD->SendSQLine(u, x);
+ /* If it is an oper, assume they're walking it, otherwise kill for good measure */
+ if (u && !u->HasMode("OPER"))
+ u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->GetReason());
+ }
+ }
+
+ void SendDel(XLine *x) override
+ {
+ if (!IRCD->CanSQLine || x->IsRegex())
+ ;
+ else if (x->GetMask()[0] != '#' || IRCD->CanSQLineChannel)
+ IRCD->SendSQLineDel(x);
+ }
+
+ bool Check(User *u, XLine *x) override
+ {
+ if (x->regex)
+ return std::regex_match(u->nick.c_str(), *x->regex);
+ return Anope::Match(u->nick, x->GetMask());
+ }
+
+ XLine *CheckChannel(Channel *c)
+ {
+ for (XLine *x : this->GetXLines())
+ {
+ if (x->regex)
+ {
+ if (std::regex_match(c->name.str(), *x->regex))
+ return x;
+ }
+ else
+ {
+ if (x->GetMask().empty() || x->GetMask()[0] != '#')
+ continue;
+
+ if (Anope::Match(c->name, x->GetMask(), false, true))
+ return x;
+ }
+ }
+ return nullptr;
+ }
+};
+
+class SNLineManager : public XLineManager
+{
+ public:
+ SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { }
+
+ void OnMatch(User *u, XLine *x) override
+ {
+ this->Send(u, x);
+ }
+
+ void OnExpire(XLine *x) override
+ {
+ ::Log(Config->GetClient("OperServ"), "expire/snline") << "SNLINE on \002" << x->GetMask() << "\002 has expired";
+ }
+
+ void Send(User *u, XLine *x) override
+ {
+ if (IRCD->CanSNLine && !x->IsRegex())
+ IRCD->SendSGLine(u, x);
+
+ if (u)
+ u->Kill(Config->GetClient("OperServ"), "SNLined: " + x->GetReason());
+ }
+
+ void SendDel(XLine *x) override
+ {
+ if (IRCD->CanSNLine && !x->IsRegex())
+ IRCD->SendSGLineDel(x);
+ }
+
+ bool Check(User *u, XLine *x) override
+ {
+ if (x->regex)
+ return std::regex_match(u->realname.str(), *x->regex);
+ return Anope::Match(u->realname, x->GetMask(), false, true);
+ }
+};
+
+class OperServCore : public Module
+ , public EventHook<Event::BotPrivmsg>
+ , public EventHook<Event::ServerQuit>
+ , public EventHook<Event::UserModeSet>
+ , public EventHook<Event::UserModeUnset>
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::CheckKick>
+ , public EventHook<Event::Help>
+ , public EventHook<Event::Log>
+{
+ Reference<ServiceBot> OperServ;
+ SGLineManager sglines;
+ SQLineManager sqlines;
+ SNLineManager snlines;
+
+ public:
+ OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
+ , EventHook<Event::BotPrivmsg>(this)
+ , EventHook<Event::ServerQuit>(this)
+ , EventHook<Event::UserModeSet>(this)
+ , EventHook<Event::UserModeUnset>(this)
+ , EventHook<Event::UserConnect>(this)
+ , EventHook<Event::UserNickChange>(this)
+ , EventHook<Event::CheckKick>(this)
+ , EventHook<Event::Help>(this)
+ , EventHook<Event::Log>(this)
+ , sglines(this)
+ , sqlines(this)
+ , snlines(this)
+ {
+
+ /* Yes, these are in this order for a reason. Most violent->least violent. */
+ XLineManager::RegisterXLineManager(&sglines);
+ XLineManager::RegisterXLineManager(&sqlines);
+ XLineManager::RegisterXLineManager(&snlines);
+ }
+
+ ~OperServCore()
+ {
+ this->sglines.Clear();
+ this->sqlines.Clear();
+ this->snlines.Clear();
+
+ XLineManager::UnregisterXLineManager(&sglines);
+ XLineManager::UnregisterXLineManager(&sqlines);
+ XLineManager::UnregisterXLineManager(&snlines);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ const Anope::string &osnick = conf->GetModule(this)->Get<Anope::string>("client");
+
+ if (osnick.empty())
+ throw ConfigException(Module::name + ": <client> must be defined");
+
+ ServiceBot *bi = ServiceBot::Find(osnick, true);
+ if (!bi)
+ throw ConfigException(Module::name + ": no bot named " + osnick);
+
+ OperServ = bi;
+ }
+
+ EventReturn OnBotPrivmsg(User *u, ServiceBot *bi, Anope::string &message) override
+ {
+ if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly"))
+ {
+ u->SendMessage(bi, "Access denied.");
+ ::Log(bi, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)";
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnServerQuit(Server *server) override
+ {
+ if (server->IsJuped())
+ ::Log(server, "squit", OperServ) << "Received SQUIT for juped server " << server->GetName();
+ }
+
+ void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (mname == "OPER")
+ ::Log(u, "oper", OperServ) << "is now an IRC operator.";
+ }
+
+ void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (mname == "OPER")
+ ::Log(u, "oper", OperServ) << "is no longer an IRC operator";
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ if (!u->Quitting() && !exempt)
+ XLineManager::CheckAll(u);
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &oldnick) override
+ {
+ if (!u->HasMode("OPER"))
+ this->sqlines.CheckAllXLines(u);
+ }
+
+ EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
+ {
+ XLine *x = this->sqlines.CheckChannel(c);
+ if (x)
+ {
+ this->sqlines.OnMatch(u, x);
+ reason = x->GetReason();
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!params.empty() || source.c || source.service != *OperServ)
+ return EVENT_CONTINUE;
+ source.Reply(_("%s commands:"), OperServ->nick.c_str());
+ return EVENT_CONTINUE;
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ }
+
+ void OnLog(::Log *l) override
+ {
+ if (l->type == LOG_SERVER)
+ l->bi = OperServ;
+ }
+};
+
+MODULE_INIT(OperServCore)
+
diff --git a/modules/commands/os_mode.cpp b/modules/operserv/mode.cpp
index 378f6b082..a159dc3e3 100644
--- a/modules/commands/os_mode.cpp
+++ b/modules/operserv/mode.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -21,14 +29,14 @@ class CommandOSMode : public Command
this->SetSyntax(_("\037channel\037 CLEAR [ALL]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &target = params[0];
const Anope::string &modes = params[1];
Reference<Channel> c = Channel::Find(target);
if (!c)
- source.Reply(CHAN_X_NOT_IN_USE, target.c_str());
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), target);
else if (c->bouncy_modes)
source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
else if (modes.equals_ci("CLEAR"))
@@ -58,10 +66,10 @@ class CommandOSMode : public Command
c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i - 1]), uc->user->GetUID(), false);
}
- source.Reply(_("All modes cleared on %s."), c->name.c_str());
+ source.Reply(_("All modes cleared on \002{0}\002."), c->name);
}
else
- source.Reply(_("Non-status modes cleared on %s."), c->name.c_str());
+ source.Reply(_("Non-status modes cleared on \002{0}\002."), c->name);
}
else
{
@@ -126,12 +134,9 @@ class CommandOSMode : public Command
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to change modes for any channel.\n"
- "Parameters are the same as for the standard /MODE command.\n"
+ source.Reply(_("Allows Services Operators to change modes for any channel. Parameters are the same as for the standard /MODE command.\n"
"Alternatively, CLEAR may be given to clear all modes on the channel.\n"
"If CLEAR ALL is given then all modes, including user status, is removed."));
return true;
@@ -147,31 +152,28 @@ class CommandOSUMode : public Command
this->SetSyntax(_("\037user\037 \037modes\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &target = params[0];
const Anope::string &modes = params[1];
User *u2 = User::Find(target, true);
if (!u2)
- source.Reply(NICK_X_NOT_IN_USE, target.c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), target);
else
{
u2->SetModes(source.service, "%s", modes.c_str());
- source.Reply(_("Changed usermodes of \002%s\002 to %s."), u2->nick.c_str(), modes.c_str());
+ source.Reply(_("Changed usermodes of \002{0}\002 to \002{1}\002."), u2->nick.c_str(), modes.c_str());
- u2->SendMessage(source.service, _("\002%s\002 changed your usermodes to %s."), source.GetNick().c_str(), modes.c_str());
+ u2->SendMessage(*source.service, _("\002{0}\002 changed your usermodes to \002{1}\002."), source.GetNick(), modes);
Log(LOG_ADMIN, source, this) << modes << " on " << target;
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to change modes for any user.\n"
- "Parameters are the same as for the standard /MODE command."));
+ source.Reply(_("Allows Services Operators to change modes for any user. Parameters are the same as for the standard /MODE command."));
return true;
}
};
@@ -182,8 +184,9 @@ class OSMode : public Module
CommandOSUMode commandosumode;
public:
- OSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmode(this), commandosumode(this)
+ OSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosmode(this)
+ , commandosumode(this)
{
}
diff --git a/modules/commands/os_modinfo.cpp b/modules/operserv/modinfo.cpp
index b1f0c7470..57edc5c40 100644
--- a/modules/commands/os_modinfo.cpp
+++ b/modules/operserv/modinfo.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSModInfo : public Command
this->SetSyntax(_("\037modname\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &file = params[0];
@@ -29,44 +37,44 @@ class CommandOSModInfo : public Command
Module *m = ModuleManager::FindModule(file);
if (m)
{
- source.Reply(_("Module: \002%s\002 Version: \002%s\002 Author: \002%s\002 Loaded: \002%s\002"), m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "Unknown", Anope::strftime(m->created, source.GetAccount()).c_str());
+ source.Reply(_("Module: \002{0}\002 Version: \002{1}\002 Author: \002{2}\002 Loaded: \002{3}\002"), m->name, !m->version.empty() ? m->version : "?", !m->author.empty() ? m->author : "Unknown", Anope::strftime(m->created, source.GetAccount()));
if (Anope::Debug)
- source.Reply(_(" Loaded at: %p"), m->handle);
+ source.Reply(_(" Loaded at: {0}"), Anope::printf("0x%x", m->handle));
- std::vector<Anope::string> servicekeys = Service::GetServiceKeys("Command");
- for (unsigned i = 0; i < servicekeys.size(); ++i)
+ std::vector<Command *> commands = ServiceManager::Get()->FindServices<Command *>();
+ for (Command *c : commands)
{
- ServiceReference<Command> c("Command", servicekeys[i]);
- if (!c || c->owner != m)
+ if (c->GetOwner() != m)
continue;
- source.Reply(_(" Providing service: \002%s\002"), c->name.c_str());
+ source.Reply(_(" Providing service: \002{0}\002"), c->GetName());
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
{
- const BotInfo *bi = it->second;
+ User *u = it->second;
+
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
for (CommandInfo::map::const_iterator cit = bi->commands.begin(), cit_end = bi->commands.end(); cit != cit_end; ++cit)
{
const Anope::string &c_name = cit->first;
const CommandInfo &info = cit->second;
- if (info.name != c->name)
+ if (info.name != c->GetName())
continue;
- source.Reply(_(" Command \002%s\002 on \002%s\002 is linked to \002%s\002"), c_name.c_str(), bi->nick.c_str(), c->name.c_str());
+ source.Reply(_(" Command \002{0}\002 on \002{1}\002 is linked to \002{2}\002"), c_name, bi->nick, c->GetName());
}
}
}
}
else
- source.Reply(_("No information about module \002%s\002 is available."), file.c_str());
-
- return;
+ source.Reply(_("No information about module \002{0}\002 is available."), file);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("This command lists information about the specified loaded module."));
return true;
}
@@ -81,7 +89,7 @@ class CommandOSModList : public Command
this->SetSyntax("[all|third|vendor|extra|database|encryption|pseudoclient|protocol]");
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &param = !params.empty() ? params[0] : "";
@@ -180,19 +188,17 @@ class CommandOSModList : public Command
++count;
- source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), mtype.c_str());
+ source.Reply(_("Module: \002{0}\002 [{1}] [{2}]"), m->name, m->version, mtype);
}
if (!count)
source.Reply(_("No modules currently loaded matching that criteria."));
else
- source.Reply(_("%d modules loaded."), count);
+ source.Reply(_("\002{0}\002 modules loaded."), count);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("Lists currently loaded modules."));
return true;
}
@@ -204,8 +210,9 @@ class OSModInfo : public Module
CommandOSModList commandosmodlist;
public:
- OSModInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmodinfo(this), commandosmodlist(this)
+ OSModInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosmodinfo(this)
+ , commandosmodlist(this)
{
}
diff --git a/modules/commands/os_module.cpp b/modules/operserv/module.cpp
index f271ed2c9..88d1def03 100644
--- a/modules/commands/os_module.cpp
+++ b/modules/operserv/module.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSModLoad : public Command
this->SetSyntax(_("\037modname\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &mname = params[0];
@@ -28,22 +36,17 @@ class CommandOSModLoad : public Command
if (status == MOD_ERR_OK)
{
Log(LOG_ADMIN, source, this) << "to load module " << mname;
- source.Reply(_("Module \002%s\002 loaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 loaded."), mname);
}
else if (status == MOD_ERR_EXISTS)
- source.Reply(_("Module \002%s\002 is already loaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 is already loaded."), mname);
else
- source.Reply(_("Unable to load module \002%s\002."), mname.c_str());
-
- return;
+ source.Reply(_("Unable to load module \002{0}\002."), mname);
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command loads the module named \037modname\037 from the modules\n"
- "directory."));
+ source.Reply(_("This command loads the module named \037modname\037."));
return true;
}
};
@@ -57,27 +60,27 @@ class CommandOSModReLoad : public Command
this->SetSyntax(_("\037modname\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &mname = params[0];
Module *m = ModuleManager::FindModule(mname);
if (!m)
{
- source.Reply(_("Module \002%s\002 isn't loaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 isn't loaded."), mname);
return;
}
if (!m->handle || m->GetPermanent())
{
- source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str());
+ source.Reply(_("Unable to remove module \002{0}\002."), m->name);
return;
}
Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
if (m->type == PROTOCOL && m != protocol)
{
- source.Reply(_("You can not reload this module directly, instead reload %s."), protocol ? protocol->name.c_str() : "(unknown)");
+ source.Reply(_("You can not reload this module directly, instead reload {0}."), protocol ? protocol->name : "(unknown)");
return;
}
@@ -87,7 +90,7 @@ class CommandOSModReLoad : public Command
if (status != MOD_ERR_OK)
{
- source.Reply(_("Unable to remove module \002%s\002."), mname.c_str());
+ source.Reply(_("Unable to remove module \002{0}\002."), mname);
return;
}
@@ -95,7 +98,7 @@ class CommandOSModReLoad : public Command
if (status == MOD_ERR_OK)
{
Log(LOG_ADMIN, source, this) << "to reload module " << mname;
- source.Reply(_("Module \002%s\002 reloaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 reloaded."), mname);
}
else
{
@@ -105,16 +108,12 @@ class CommandOSModReLoad : public Command
Anope::Quitting = true;
}
else
- source.Reply(_("Unable to load module \002%s\002."), mname.c_str());
+ source.Reply(_("Unable to load module \002{0}\002."), mname);
}
-
- return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("This command reloads the module named \037modname\037."));
return true;
}
@@ -129,42 +128,40 @@ class CommandOSModUnLoad : public Command
this->SetSyntax(_("\037modname\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &mname = params[0];
Module *m = ModuleManager::FindModule(mname);
if (!m)
{
- source.Reply(_("Module \002%s\002 isn't loaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 isn't loaded."), mname);
return;
}
-
+
if (!m->handle || m->GetPermanent() || m->type == PROTOCOL)
{
- source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str());
+ source.Reply(_("Unable to remove module \002{0}\002."), m->name);
return;
}
- Log(this->owner) << "Trying to unload module [" << mname << "]";
+ Log(this->GetOwner()) << "Trying to unload module [" << mname << "]";
ModuleReturn status = ModuleManager::UnloadModule(m, source.GetUser());
if (status == MOD_ERR_OK)
{
Log(LOG_ADMIN, source, this) << "to unload module " << mname;
- source.Reply(_("Module \002%s\002 unloaded."), mname.c_str());
+ source.Reply(_("Module \002{0}\002 unloaded."), mname);
}
else
- source.Reply(_("Unable to remove module \002%s\002."), mname.c_str());
+ source.Reply(_("Unable to remove module \002{0}\002."), mname);
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("This command unloads the module named \037modname\037."));
return true;
}
@@ -177,8 +174,10 @@ class OSModule : public Module
CommandOSModUnLoad commandosmodunload;
public:
- OSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmodload(this), commandosmodreload(this), commandosmodunload(this)
+ OSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosmodload(this)
+ , commandosmodreload(this)
+ , commandosmodunload(this)
{
this->SetPermanent(true);
diff --git a/modules/operserv/news.cpp b/modules/operserv/news.cpp
new file mode 100644
index 000000000..91e5a175a
--- /dev/null
+++ b/modules/operserv/news.cpp
@@ -0,0 +1,478 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/operserv/news.h"
+
+/* List of messages for each news type. This simplifies message sending. */
+
+enum
+{
+ MSG_SYNTAX,
+ MSG_LIST_HEADER,
+ MSG_LIST_NONE,
+ MSG_ADDED,
+ MSG_DEL_NOT_FOUND,
+ MSG_DELETED,
+ MSG_DEL_NONE,
+ MSG_DELETED_ALL,
+ MSG_SIZE
+};
+
+static struct NewsMessages
+{
+ NewsType type;
+ Anope::string name;
+ const char *msgs[MSG_SIZE];
+} msgarray[] = {
+ {NEWS_LOGON, "LOGON",
+ {_("LOGONNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
+ _("Logon news items:"),
+ _("There is no logon news."),
+ _("Added new logon news item."),
+ _("Logon news item #{0} not found!"),
+ _("Logon news item #{0} deleted."),
+ _("No logon news items to delete!"),
+ _("All logon news items deleted.")}
+ },
+ {NEWS_OPER, "OPER",
+ {_("OPERNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
+ _("Oper news items:"),
+ _("There is no oper news."),
+ _("Added new oper news item."),
+ _("Oper news item #{0} not found!"),
+ _("Oper news item #{0} deleted."),
+ _("No oper news items to delete!"),
+ _("All oper news items deleted.")}
+ },
+ {NEWS_RANDOM, "RANDOM",
+ {_("RANDOMNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
+ _("Random news items:"),
+ _("There is no random news."),
+ _("Added new random news item."),
+ _("Random news item #{0} not found!"),
+ _("Random news item #{0} deleted."),
+ _("No random news items to delete!"),
+ _("All random news items deleted.")}
+ }
+};
+
+class NewsItemImpl : public NewsItem
+{
+ friend class NewsItemType;
+
+ NewsType type;
+ Anope::string text, who;
+ time_t time = 0;
+
+ public:
+ NewsItemImpl(Serialize::TypeBase *type) : NewsItem(type) { }
+ NewsItemImpl(Serialize::TypeBase *type, Serialize::ID id) : NewsItem(type, id) { }
+
+ NewsType GetNewsType() override;
+ void SetNewsType(const NewsType &) override;
+
+ Anope::string GetText() override;
+ void SetText(const Anope::string &) override;
+
+ Anope::string GetWho() override;
+ void SetWho(const Anope::string &) override;
+
+ time_t GetTime() override;
+ void SetTime(const time_t &) override;
+};
+
+class NewsItemType : public Serialize::Type<NewsItemImpl>
+{
+ public:
+ Serialize::Field<NewsItemImpl, NewsType> type;
+ Serialize::Field<NewsItemImpl, Anope::string> text;
+ Serialize::Field<NewsItemImpl, Anope::string> who;
+ Serialize::Field<NewsItemImpl, time_t> time;
+
+ NewsItemType(Module *me) : Serialize::Type<NewsItemImpl>(me)
+ , type(this, "type", &NewsItemImpl::type)
+ , text(this, "text", &NewsItemImpl::text)
+ , who(this, "who", &NewsItemImpl::who)
+ , time(this, "time", &NewsItemImpl::time)
+ {
+ }
+};
+
+NewsType NewsItemImpl::GetNewsType()
+{
+ return Get(&NewsItemType::type);
+}
+
+void NewsItemImpl::SetNewsType(const NewsType &t)
+{
+ Set(&NewsItemType::type, t);
+}
+
+Anope::string NewsItemImpl::GetText()
+{
+ return Get(&NewsItemType::text);
+}
+
+void NewsItemImpl::SetText(const Anope::string &t)
+{
+ Set(&NewsItemType::text, t);
+}
+
+Anope::string NewsItemImpl::GetWho()
+{
+ return Get(&NewsItemType::who);
+}
+
+void NewsItemImpl::SetWho(const Anope::string &w)
+{
+ Set(&NewsItemType::who, w);
+}
+
+time_t NewsItemImpl::GetTime()
+{
+ return Get(&NewsItemType::time);
+}
+
+void NewsItemImpl::SetTime(const time_t &t)
+{
+ Set(&NewsItemType::time, t);
+}
+
+static const char **findmsgs(NewsType type)
+{
+ for (unsigned i = 0; i < sizeof(msgarray) / sizeof(*msgarray); ++i)
+ if (msgarray[i].type == type)
+ return msgarray[i].msgs;
+ return NULL;
+}
+
+class NewsBase : public Command
+{
+ protected:
+ void DoList(CommandSource &source, NewsType ntype, const char **msgs)
+ {
+ std::vector<NewsItem *> list = Serialize::GetObjects<NewsItem *>();
+
+ if (list.empty())
+ {
+ source.Reply(msgs[MSG_LIST_NONE]);
+ return;
+ }
+
+ ListFormatter lflist(source.GetAccount());
+ lflist.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Text"));
+
+ unsigned int i = 1;
+ for (NewsItem *n : list)
+ {
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i++ + 1);
+ entry["Creator"] = n->GetWho();
+ entry["Created"] = Anope::strftime(n->GetTime(), NULL, true);
+ entry["Text"] = n->GetText();
+ lflist.AddEntry(entry);
+ }
+
+ source.Reply(msgs[MSG_LIST_HEADER]);
+
+ std::vector<Anope::string> replies;
+ lflist.Process(replies);
+
+ for (i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+
+ source.Reply(_("End of news list."));
+ }
+
+ void DoAdd(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
+ {
+ const Anope::string text = params.size() > 1 ? params[1] : "";
+
+ if (text.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ NewsItem *ni = Serialize::New<NewsItem *>();
+ ni->SetNewsType(ntype);
+ ni->SetText(text);
+ ni->SetTime(Anope::CurTime);
+ ni->SetWho(source.GetNick());
+
+ source.Reply(msgs[MSG_ADDED]);
+ Log(LOG_ADMIN, source, this) << "to add a news item";
+ }
+
+ void DoDel(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
+ {
+ const Anope::string &text = params.size() > 1 ? params[1] : "";
+ std::vector<NewsItem *> list = Serialize::GetObjects<NewsItem *>();
+
+ if (text.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (list.empty())
+ {
+ source.Reply(msgs[MSG_LIST_NONE]);
+ return;
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ if (!text.equals_ci("ALL"))
+ {
+ try
+ {
+ unsigned num = convertTo<unsigned>(text);
+ if (num > 0 && num <= list.size())
+ {
+ list[num - 1]->Delete();
+ source.Reply(msgs[MSG_DELETED], num);
+ Log(LOG_ADMIN, source, this) << "to delete a news item";
+ return;
+ }
+ }
+ catch (const ConvertException &) { }
+
+ source.Reply(msgs[MSG_DEL_NOT_FOUND], text.c_str());
+ }
+ else
+ {
+ for (NewsItem *n : list)
+ n->Delete();
+ source.Reply(msgs[MSG_DELETED_ALL]);
+ Log(LOG_ADMIN, source, this) << "to delete all news items";
+ }
+ }
+
+ void DoNews(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype)
+ {
+ const Anope::string &cmd = params[0];
+
+ const char **msgs = findmsgs(ntype);
+ if (!msgs)
+ throw CoreException("news: Invalid type to do_news()");
+
+ if (cmd.equals_ci("LIST"))
+ return this->DoList(source, ntype, msgs);
+ else if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, params, ntype, msgs);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, params, ntype, msgs);
+ else
+ this->OnSyntaxError(source, "");
+ }
+ public:
+ NewsBase(Module *creator, const Anope::string &newstype) : Command(creator, newstype, 1, 2)
+ {
+ this->SetSyntax(_("ADD \037text\037"));
+ this->SetSyntax(_("DEL {\037num\037 | ALL}"));
+ this->SetSyntax("LIST");
+ }
+
+ virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_abstract;
+
+ virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_abstract;
+};
+
+class CommandOSLogonNews : public NewsBase
+{
+ public:
+ CommandOSLogonNews(Module *creator) : NewsBase(creator, "operserv/logonnews")
+ {
+ this->SetDesc(_("Define messages to be shown to users at logon"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ return this->DoNews(source, params, NEWS_LOGON);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Edits or displays the list of logon news messages. When a user connects to the network, these messages will be sent to them."
+ " However, no more than \002{0}\002 messages will be sent in order to avoid flooding the user."
+ " If there are more news messages, only the most recent will be sent."),
+ Config->GetModule(this->GetOwner())->Get<unsigned>("newscount", "3"));
+ return true;
+ }
+};
+
+class CommandOSOperNews : public NewsBase
+{
+ public:
+ CommandOSOperNews(Module *creator) : NewsBase(creator, "operserv/opernews")
+ {
+ this->SetDesc(_("Define messages to be shown to users who oper"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ return this->DoNews(source, params, NEWS_OPER);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Edits or displays the list of oper news messages."
+ " When a user opers up (with the /OPER command), these messages will be sent to them."
+ " However, no more than \002{0}\002 messages will be sent in order to avoid flooding the user."
+ " If there are more news messages, only the most recent will be sent."),
+ Config->GetModule(this->GetOwner())->Get<unsigned>("newscount", "3"));
+ return true;
+ }
+};
+
+class CommandOSRandomNews : public NewsBase
+{
+ public:
+ CommandOSRandomNews(Module *creator) : NewsBase(creator, "operserv/randomnews")
+ {
+ this->SetDesc(_("Define messages to be randomly shown to users at logon"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ return this->DoNews(source, params, NEWS_RANDOM);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Edits or displays the list of random news messages. When a user connects to the network, one (and only one) of the random news will be randomly chosen and sent to them."));
+ return true;
+ }
+};
+
+class OSNews : public Module
+ , public EventHook<Event::UserModeSet>
+ , public EventHook<Event::UserConnect>
+{
+ NewsItemType newsitemtype;
+
+ CommandOSLogonNews commandoslogonnews;
+ CommandOSOperNews commandosopernews;
+ CommandOSRandomNews commandosrandomnews;
+
+ Anope::string oper_announcer, announcer;
+ unsigned int news_count;
+ unsigned int cur_rand_news = 0;
+
+ void DisplayNews(User *u, NewsType Type)
+ {
+ std::vector<NewsItem *> list = Serialize::GetObjects<NewsItem *>();
+ if (list.empty())
+ return;
+
+ ServiceBot *bi = NULL;
+ if (Type == NEWS_OPER)
+ bi = ServiceBot::Find(Config->GetModule(this)->Get<Anope::string>("oper_announcer", "OperServ"), true);
+ else
+ bi = ServiceBot::Find(Config->GetModule(this)->Get<Anope::string>("announcer", "Global"), true);
+ if (bi == NULL)
+ return;
+
+ Anope::string msg;
+ if (Type == NEWS_LOGON)
+ msg = _("[\002Logon News\002 - {0}] {1}");
+ else if (Type == NEWS_OPER)
+ msg = _("[\002Oper News\002 - {0}] {1}");
+ else if (Type == NEWS_RANDOM)
+ msg = _("[\002Random News\002 - {0}] {1}");
+ else
+ return;
+
+ unsigned int start;
+ unsigned int end;
+
+ if (Type == NEWS_RANDOM)
+ {
+ /* Reset to head of list to get first random news value */
+ if (cur_rand_news >= list.size())
+ cur_rand_news = 0;
+
+ /* only show one news entry */
+ start = cur_rand_news;
+ end = cur_rand_news + 1;
+
+ ++cur_rand_news;
+ }
+ else
+ {
+ if (list.size() < news_count)
+ start = 0;
+ else
+ start = list.size() - news_count;
+
+ end = start + news_count;
+
+ if (end > list.size())
+ end = list.size();
+ }
+
+ for (unsigned int i = start; i < end; ++i)
+ {
+ NewsItem *n = list[i];
+
+ u->SendMessage(bi, msg.c_str(), Anope::strftime(n->GetTime(), u->Account(), true), n->GetText());
+ }
+ }
+
+ public:
+ OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserModeSet>(this)
+ , EventHook<Event::UserConnect>(this)
+ , newsitemtype(this)
+ , commandoslogonnews(this)
+ , commandosopernews(this)
+ , commandosrandomnews(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ oper_announcer = conf->GetModule(this)->Get<Anope::string>("oper_announcer", "OperServ");
+ announcer = conf->GetModule(this)->Get<Anope::string>("announcer", "Global");
+ news_count = conf->GetModule(this)->Get<unsigned>("newscount", "3");
+ }
+
+ void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override
+ {
+ if (mname == "OPER")
+ DisplayNews(u, NEWS_OPER);
+ }
+
+ void OnUserConnect(User *user, bool &) override
+ {
+ if (user->Quitting() || !user->server->IsSynced())
+ return;
+
+ DisplayNews(user, NEWS_LOGON);
+ DisplayNews(user, NEWS_RANDOM);
+ }
+};
+
+MODULE_INIT(OSNews)
diff --git a/modules/commands/os_noop.cpp b/modules/operserv/noop.cpp
index c0beb678a..7c4a178b4 100644
--- a/modules/commands/os_noop.cpp
+++ b/modules/operserv/noop.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -21,15 +29,15 @@ class CommandOSNOOP : public Command
this->SetSyntax(_("REVOKE \037server\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &cmd = params[0];
const Anope::string &server = params[1];
Server *s = Server::Find(server, true);
if (s == NULL)
- source.Reply(_("Server %s does not exist."), server.c_str());
- else if (s == Me || s->IsJuped())
+ source.Reply(_("Server \002{0}\002 does not exist."), server);
+ else if (s == Me || s->IsJuped() || s->IsULined())
source.Reply(_("You can not NOOP Services."));
else if (cmd.equals_ci("SET"))
{
@@ -38,7 +46,7 @@ class CommandOSNOOP : public Command
s->Extend<Anope::string>("noop", source.GetNick());
Log(LOG_ADMIN, source, this) << "SET on " << s->GetName();
- source.Reply(_("All operators from \002%s\002 have been removed."), s->GetName().c_str());
+ source.Reply(_("All operators from \002{0}\002 have been removed."), s->GetName());
Anope::string reason = "NOOP command used by " + source.GetNick();
/* Kill all the IRCops of the server */
@@ -55,43 +63,42 @@ class CommandOSNOOP : public Command
s->Shrink<Anope::string>("noop");
IRCD->SendSVSNOOP(s, false);
Log(LOG_ADMIN, source, this) << "REVOKE on " << s->GetName();
- source.Reply(_("All O:lines of \002%s\002 have been reset."), s->GetName().c_str());
+ source.Reply(_("All O:lines of \002{0}\002 have been reset."), s->GetName());
}
else
this->OnSyntaxError(source, "");
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("\002SET\002 kills all operators from the given\n"
- "\002server\002 and prevents operators from opering\n"
- "up on the given server. \002REVOKE\002 removes this\n"
- "restriction."));
+ source.Reply(_("\002{0} SET\002 kills all operators from the given \002server\002 and prevents operators from opering up on the given server."
+ " \002{0} REVOKE\002 removes this restriction."));
return true;
}
};
class OSNOOP : public Module
+ , public EventHook<Event::UserModeSet>
{
CommandOSNOOP commandosnoop;
- PrimitiveExtensibleItem<Anope::string> noop;
+ ExtensibleItem<Anope::string> noop;
public:
- OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosnoop(this), noop(this, "noop")
+ OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserModeSet>(this)
+ , commandosnoop(this)
+ , noop(this, "noop")
{
}
- void OnUserModeSet(const MessageSource &, User *u, const Anope::string &mname) anope_override
+ void OnUserModeSet(const MessageSource &, User *u, const Anope::string &mname) override
{
Anope::string *setter;
if (mname == "OPER" && (setter = noop.Get(u->server)))
{
Anope::string reason = "NOOP command used by " + *setter;
- BotInfo *OperServ = Config->GetClient("OperServ");
+ ServiceBot *OperServ = Config->GetClient("OperServ");
u->Kill(OperServ, reason);
}
}
diff --git a/modules/commands/os_oline.cpp b/modules/operserv/oline.cpp
index 5270d3f78..a0b968325 100644
--- a/modules/commands/os_oline.cpp
+++ b/modules/operserv/oline.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSOLine : public Command
this->SetSyntax(_("\037nick\037 \037flags\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &nick = params[0];
const Anope::string &flag = params[1];
@@ -28,19 +36,19 @@ class CommandOSOLine : public Command
/* let's check whether the user is online */
if (!(u2 = User::Find(nick, true)))
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), nick);
else if (u2 && flag[0] == '+')
{
IRCD->SendSVSO(source.service, nick, flag);
u2->SetMode(source.service, "OPER");
- u2->SendMessage(source.service, _("You are now an IRC Operator."));
- source.Reply(_("Operflags \002%s\002 have been added for \002%s\002."), flag.c_str(), nick.c_str());
+ u2->SendMessage(*source.service, _("You are now an IRC Operator."));
+ source.Reply(_("Operflags \002{0}\002 have been added for \002{1}\002."), flag, nick);
Log(LOG_ADMIN, source, this) << "for " << nick;
}
else if (u2 && flag[0] == '-')
{
IRCD->SendSVSO(source.service, nick, flag);
- source.Reply(_("Operflags \002%s\002 have been removed from \002%s\002."), flag.c_str(), nick.c_str());
+ source.Reply(_("Operflags \002{0}\002 have been removed from \002{1}\002."), flag, nick);
Log(LOG_ADMIN, source, this) << "for " << nick;
}
else
@@ -49,13 +57,9 @@ class CommandOSOLine : public Command
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to give Operflags to any user.\n"
- "Flags have to be prefixed with a \"+\" or a \"-\". To\n"
- "remove all flags simply type a \"-\" instead of any flags."));
+ source.Reply(_("Allows Services Operators to give Operflags to any user. Flags have to be prefixed with a \"+\" or a \"-\". To remove all flags simply type a \"-\" instead of any flags."));
return true;
}
};
@@ -65,8 +69,8 @@ class OSOLine : public Module
CommandOSOLine commandosoline;
public:
- OSOLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosoline(this)
+ OSOLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosoline(this)
{
if (!IRCD || !IRCD->CanSVSO)
diff --git a/modules/operserv/oper.cpp b/modules/operserv/oper.cpp
new file mode 100644
index 000000000..40880d8fc
--- /dev/null
+++ b/modules/operserv/oper.cpp
@@ -0,0 +1,257 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSOper : public Command
+{
+ bool HasPrivs(CommandSource &source, OperType *ot) const
+ {
+ std::list<Anope::string> commands = ot->GetCommands(), privs = ot->GetPrivs();
+
+ for (std::list<Anope::string>::iterator it = commands.begin(); it != commands.end(); ++it)
+ if (!source.HasCommand(*it))
+ return false;
+
+ for (std::list<Anope::string>::iterator it = privs.begin(); it != privs.end(); ++it)
+ if (!source.HasPriv(*it))
+ return false;
+
+ return true;
+ }
+
+ public:
+ CommandOSOper(Module *creator) : Command(creator, "operserv/oper", 1, 3)
+ {
+ this->SetDesc(_("View and change Services Operators"));
+ this->SetSyntax(_("ADD \037oper\037 \037type\037"));
+ this->SetSyntax(_("DEL \037oper\037"));
+ this->SetSyntax(_("INFO [\037type\037]"));
+ this->SetSyntax("LIST");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &subcommand = params[0];
+
+ if (subcommand.equals_ci("ADD") && params.size() > 2)
+ {
+ const Anope::string &oper = params[1];
+ const Anope::string &otype = params[2];
+
+ if (!source.HasPriv("operserv/oper/modify"))
+ {
+ source.Reply(_("Access denied. You do not have the operator privilege \002{0}\002."), "operserv/oper/modify");
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(oper);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't currently online."), oper);
+ return;
+ }
+
+ OperType *ot = OperType::Find(otype);
+ if (ot == NULL)
+ {
+ source.Reply(_("Oper type \002{0}\002 has not been configured."), otype);
+ return;
+ }
+
+ if (!HasPrivs(source, ot))
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ if (na->GetAccount()->o)
+ {
+ na->GetAccount()->o->Delete();
+ na->GetAccount()->o = nullptr;
+ }
+
+ Oper *o = Serialize::New<Oper *>();
+ o->SetName(na->GetAccount()->GetDisplay());
+ o->SetType(ot);
+ o->SetRequireOper(true);
+
+ na->GetAccount()->o = o;
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "ADD " << na->GetNick() << " as type " << ot->GetName();
+ source.Reply("\002{0}\002 (\002{1}\002) added to the \002{2}\002 list.", na->GetNick(), na->GetAccount()->GetDisplay(), ot->GetName());
+ }
+ else if (subcommand.equals_ci("DEL") && params.size() > 1)
+ {
+ const Anope::string &oper = params[1];
+
+ if (!source.HasPriv("operserv/oper/modify"))
+ {
+ source.Reply(_("Access denied. You do not have the operator privilege \002{0}\002."), "operserv/oper/modify");
+ return;
+ }
+
+ NickServ::Nick *na = NickServ::FindNick(oper);
+ if (na == nullptr || na->GetAccount() == nullptr)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), oper);
+ return;
+ }
+
+ Oper *o = na->GetAccount()->o;
+
+ if (o == nullptr)
+ {
+ source.Reply(_("Nick \002{0}\002 is not a Services Operator."), oper);
+ return;
+ }
+
+ if (!HasPrivs(source, o->GetType()))
+ {
+ source.Reply(_("Access denied."));
+ return;
+ }
+
+ if (o->conf != nullptr)
+ {
+ source.Reply(_("Oper \002{0}\002 is configured in the configuration file(s) and can not be removed by this command."), na->GetNick());
+ return;
+ }
+
+ na->GetAccount()->o->Delete();
+ na->GetAccount()->o = NULL;
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+
+ Log(LOG_ADMIN, source, this) << "DEL " << na->GetNick();
+ source.Reply(_("Oper privileges removed from \002{0}\002 (\002{1}\002)."), na->GetNick(), na->GetAccount()->GetDisplay());
+ }
+ else if (subcommand.equals_ci("LIST"))
+ {
+ source.Reply(_("Name Type"));
+ for (NickServ::Account *nc : NickServ::service->GetAccountList())
+ {
+ if (!nc->o)
+ continue;
+
+ source.Reply(Anope::printf("%-8s %s", nc->o->GetName().c_str(), nc->o->GetType()->GetName().c_str()));
+ if (nc->o->conf)
+ source.Reply(_(" This oper is configured in the configuration file."));
+ for (User *u : nc->users)
+ source.Reply(_(" \002{0}\002 is online using this oper block."), u->nick);
+ }
+ }
+ else if (subcommand.equals_ci("INFO"))
+ {
+ if (params.size() < 2)
+ {
+ source.Reply(_("Available opertypes:"));
+ for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
+ {
+ OperType *ot = Config->MyOperTypes[i];
+ source.Reply("%s", ot->GetName().c_str());
+ }
+ return;
+ }
+
+ Anope::string fulltype = params[1];
+ if (params.size() > 2)
+ fulltype += " " + params[2];
+ OperType *ot = OperType::Find(fulltype);
+ if (ot == NULL)
+ {
+ source.Reply(_("Oper type \002{0}\002 has not been configured."), fulltype);
+ return;
+ }
+
+ if (ot->GetCommands().empty())
+ source.Reply(_("Opertype \002{0}\002 has no allowed commands."), ot->GetName());
+ else
+ {
+ source.Reply(_("Available commands for \002{0}\002:"), ot->GetName());
+ Anope::string buf;
+ std::list<Anope::string> cmds = ot->GetCommands();
+ for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it)
+ {
+ buf += *it + " ";
+ if (buf.length() > 400)
+ {
+ source.Reply("%s", buf.c_str());
+ buf.clear();
+ }
+ }
+ if (!buf.empty())
+ {
+ source.Reply("%s", buf.c_str());
+ buf.clear();
+ }
+ }
+ if (ot->GetPrivs().empty())
+ source.Reply(_("Opertype \002{0}\002 has no allowed privileges."), ot->GetName());
+ else
+ {
+ source.Reply(_("Available privileges for \002{0}\002:"), ot->GetName());
+ Anope::string buf;
+ std::list<Anope::string> privs = ot->GetPrivs();
+ for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it)
+ {
+ buf += *it + " ";
+ if (buf.length() > 400)
+ {
+ source.Reply("%s", buf.c_str());
+ buf.clear();
+ }
+ }
+ if (!buf.empty())
+ {
+ source.Reply("%s", buf.c_str());
+ buf.clear();
+ }
+ }
+ if (!ot->modes.empty())
+ source.Reply(_("Opertype \002{0}\002 receives modes \002{1}\002 once identified."), ot->GetName(), ot->modes);
+ }
+ else
+ this->OnSyntaxError(source, subcommand);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows you to change and view Services Operators.\n"
+ " Note that operators removed by this command but are still set in the configuration file are not permanently affected by this."));
+ return true;
+ }
+};
+
+class OSOper : public Module
+{
+ CommandOSOper commandosoper;
+
+ public:
+ OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosoper(this)
+ {
+ }
+};
+
+MODULE_INIT(OSOper)
diff --git a/modules/operserv/reload.cpp b/modules/operserv/reload.cpp
new file mode 100644
index 000000000..ecff66ac2
--- /dev/null
+++ b/modules/operserv/reload.cpp
@@ -0,0 +1,70 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSReload : public Command
+{
+ public:
+ CommandOSReload(Module *creator) : Command(creator, "operserv/reload", 0, 0)
+ {
+ this->SetDesc(_("Reload services' configuration file"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ try
+ {
+ Log(LOG_ADMIN, source, this);
+
+ Configuration::Conf *new_config = new Configuration::Conf();
+ Configuration::Conf *old = Config;
+ Config = new_config;
+ Config->Post(old);
+ delete old;
+
+ source.Reply(_("Services' configuration has been reloaded."));
+ }
+ catch (const ConfigException &ex)
+ {
+ Log(this->GetOwner()) << "Error reloading configuration file: " << ex.GetReason();
+ source.Reply(_("Error reloading configuration file: {0}"), ex.GetReason());
+ }
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Causes Services to reload the configuration file."));
+ return true;
+ }
+};
+
+class OSReload : public Module
+{
+ CommandOSReload commandosreload;
+
+ public:
+ OSReload(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosreload(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSReload)
diff --git a/modules/operserv/session.cpp b/modules/operserv/session.cpp
new file mode 100644
index 000000000..158d3c342
--- /dev/null
+++ b/modules/operserv/session.cpp
@@ -0,0 +1,785 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/operserv/session.h"
+
+namespace
+{
+ /* The default session limit */
+ unsigned session_limit;
+ /* How many times to kill before adding an AKILL */
+ unsigned max_session_kill;
+ /* How long session akills should last */
+ time_t session_autokill_expiry;
+ /* Reason to use for session kills */
+ Anope::string sle_reason;
+ /* Optional second reason */
+ Anope::string sle_detailsloc;
+
+ /* Max limit that can be used for exceptions */
+ unsigned max_exception_limit;
+ /* How long before exceptions expire by default */
+ time_t exception_expiry;
+
+ /* Number of bits to use when comparing session IPs */
+ unsigned ipv4_cidr;
+ unsigned ipv6_cidr;
+}
+
+class ExceptionImpl : public Exception
+{
+ friend class ExceptionType;
+
+ Anope::string mask, who, reason;
+ unsigned int limit = 0;
+ time_t time = 0, expires = 0;
+
+ public:
+ ExceptionImpl(Serialize::TypeBase *type) : Exception(type) { }
+ ExceptionImpl(Serialize::TypeBase *type, Serialize::ID id) : Exception(type, id) { }
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+
+ unsigned int GetLimit() override;
+ void SetLimit(unsigned int) override;
+
+ Anope::string GetWho() override;
+ void SetWho(const Anope::string &) override;
+
+ Anope::string GetReason() override;
+ void SetReason(const Anope::string &) override;
+
+ time_t GetTime() override;
+ void SetTime(const time_t &) override;
+
+ time_t GetExpires() override;
+ void SetExpires(const time_t &) override;
+};
+
+class ExceptionType : public Serialize::Type<ExceptionImpl>
+{
+ public:
+ Serialize::Field<ExceptionImpl, Anope::string> mask, who, reason;
+ Serialize::Field<ExceptionImpl, unsigned int> limit;
+ Serialize::Field<ExceptionImpl, time_t> time, expires;
+
+ ExceptionType(Module *me) : Serialize::Type<ExceptionImpl>(me)
+ , mask(this, "mask", &ExceptionImpl::mask)
+ , who(this, "who", &ExceptionImpl::who)
+ , reason(this, "reason", &ExceptionImpl::reason)
+ , limit(this, "limit", &ExceptionImpl::limit)
+ , time(this, "time", &ExceptionImpl::time)
+ , expires(this, "expires", &ExceptionImpl::expires)
+ {
+ }
+};
+
+Anope::string ExceptionImpl::GetMask()
+{
+ return Get(&ExceptionType::mask);
+}
+
+void ExceptionImpl::SetMask(const Anope::string &m)
+{
+ Set(&ExceptionType::mask, m);
+}
+
+unsigned int ExceptionImpl::GetLimit()
+{
+ return Get(&ExceptionType::limit);
+}
+
+void ExceptionImpl::SetLimit(unsigned int l)
+{
+ Set(&ExceptionType::limit, l);
+}
+
+Anope::string ExceptionImpl::GetWho()
+{
+ return Get(&ExceptionType::who);
+}
+
+void ExceptionImpl::SetWho(const Anope::string &w)
+{
+ Set(&ExceptionType::who, w);
+}
+
+Anope::string ExceptionImpl::GetReason()
+{
+ return Get(&ExceptionType::reason);
+}
+
+void ExceptionImpl::SetReason(const Anope::string &r)
+{
+ Set(&ExceptionType::reason, r);
+}
+
+time_t ExceptionImpl::GetTime()
+{
+ return Get(&ExceptionType::time);
+}
+
+void ExceptionImpl::SetTime(const time_t &t)
+{
+ Set(&ExceptionType::time, t);
+}
+
+time_t ExceptionImpl::GetExpires()
+{
+ return Get(&ExceptionType::expires);
+}
+
+void ExceptionImpl::SetExpires(const time_t &e)
+{
+ Set(&ExceptionType::expires, e);
+}
+
+class MySessionService : public SessionService
+{
+ SessionMap Sessions;
+
+ public:
+ MySessionService(Module *m) : SessionService(m) { }
+
+ Exception *FindException(User *u) override
+ {
+ for (Exception *e : Serialize::GetObjects<Exception *>())
+ {
+ if (Anope::Match(u->host, e->GetMask()) || Anope::Match(u->ip.addr(), e->GetMask()))
+ return e;
+
+ if (cidr(e->GetMask()).match(u->ip))
+ return e;
+ }
+ return nullptr;
+ }
+
+ Exception *FindException(const Anope::string &host) override
+ {
+ for (Exception *e : Serialize::GetObjects<Exception *>())
+ {
+ if (Anope::Match(host, e->GetMask()))
+ return e;
+
+ if (cidr(e->GetMask()).match(sockaddrs(host)))
+ return e;
+ }
+
+ return nullptr;
+ }
+
+ void DelSession(Session *s)
+ {
+ this->Sessions.erase(s->addr);
+ }
+
+ Session *FindSession(const Anope::string &ip) override
+ {
+ cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
+ if (!c.valid())
+ return NULL;
+ SessionMap::iterator it = this->Sessions.find(c);
+ if (it != this->Sessions.end())
+ return it->second;
+ return NULL;
+ }
+
+ SessionMap::iterator FindSessionIterator(const sockaddrs &ip)
+ {
+ cidr c(ip, ip.ipv6() ? ipv6_cidr : ipv4_cidr);
+ if (!c.valid())
+ return this->Sessions.end();
+ return this->Sessions.find(c);
+ }
+
+ Session* &FindOrCreateSession(const cidr &ip)
+ {
+ return this->Sessions[ip];
+ }
+
+ SessionMap &GetSessions() override
+ {
+ return this->Sessions;
+ }
+};
+
+class CommandOSSession : public Command
+{
+ ServiceReference<SessionService> session_service;
+
+ private:
+ void DoList(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ Anope::string param = params[1];
+
+ unsigned mincount = 0;
+ try
+ {
+ mincount = convertTo<unsigned>(param);
+ }
+ catch (const ConvertException &) { }
+
+ if (mincount <= 1)
+ {
+ source.Reply(_("Invalid threshold value. It must be a valid integer greater than 1."));
+ return;
+ }
+
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Session")).AddColumn(_("Host"));
+
+ for (SessionService::SessionMap::iterator it = session_service->GetSessions().begin(), it_end = session_service->GetSessions().end(); it != it_end; ++it)
+ {
+ Session *session = it->second;
+
+ if (session->count >= mincount)
+ {
+ ListFormatter::ListEntry entry;
+ entry["Session"] = stringify(session->count);
+ entry["Host"] = session->addr.mask();
+ list.AddEntry(entry);
+ }
+ }
+
+ source.Reply(_("Hosts with at least \002{0}\002 sessions:"), mincount);
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+
+ void DoView(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ Anope::string param = params[1];
+ Session *session = session_service->FindSession(param);
+
+ Exception *e = session_service->FindException(param);
+ Anope::string entry = "no entry";
+ unsigned limit = session_limit;
+ if (e)
+ {
+ if (!e->GetLimit())
+ limit = 0;
+ else if (e->GetLimit() > limit)
+ limit = e->GetLimit();
+ entry = e->GetMask();
+ }
+
+ if (!session)
+ source.Reply(_("\002{0}\002 not found on the session list, but has a limit of \002{1}\002 because it matches entry: \002{2}\002."), param, limit, entry);
+ else
+ source.Reply(_("The host \002{0}\002 currently has \002{1}\002 sessions with a limit of \002{2}\002 because it matches entry: \002{3}\002."), session->addr.mask(), session->count, limit, entry);
+ }
+
+ public:
+ CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2)
+ {
+ this->SetDesc(_("View the list of host sessions"));
+ this->SetSyntax(_("LIST \037threshold\037"));
+ this->SetSyntax(_("VIEW \037host\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ Log(LOG_ADMIN, source, this) << cmd << " " << params[1];
+
+ if (!session_limit)
+ source.Reply(_("Session limiting is disabled."));
+ else if (cmd.equals_ci("LIST"))
+ this->DoList(source, params);
+ else if (cmd.equals_ci("VIEW"))
+ this->DoView(source, params);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Allows Services Operators to view the session list.\n"
+ "\n"
+ "\002{0} LIST\002 lists hosts with at least \037threshold\037 sessions. The threshold must be a number greater than 1.\n"
+ "\n"
+ "\002{0} VIEW\002 displays detailed information about a specific host - including the current session count and session limit.\n"
+ "\n"
+ "See the \002EXCEPTION\002 help for more information about session limiting and how to set session limits specific to certain hosts and groups thereof."), // XXX
+ source.command);
+ return true;
+ }
+};
+
+class CommandOSException : public Command
+{
+ static void DoDel(CommandSource &source, Exception *e)
+ {
+ EventManager::Get()->Dispatch(&Event::Exception::OnExceptionDel, source, e);
+ e->Delete();
+ }
+
+ void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ Anope::string mask, expiry, limitstr;
+ unsigned last_param = 3;
+
+ mask = params.size() > 1 ? params[1] : "";
+ if (!mask.empty() && mask[0] == '+')
+ {
+ expiry = mask;
+ mask = params.size() > 2 ? params[2] : "";
+ last_param = 4;
+ }
+
+ limitstr = params.size() > last_param - 1 ? params[last_param - 1] : "";
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ Anope::string reason = params[last_param];
+ if (last_param == 3 && params.size() > 4)
+ reason += " " + params[4];
+ if (reason.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry;
+ if (expires < 0)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ else if (expires > 0)
+ expires += Anope::CurTime;
+
+ unsigned limit = -1;
+ try
+ {
+ limit = convertTo<unsigned>(limitstr);
+ }
+ catch (const ConvertException &) { }
+
+ if (limit > max_exception_limit)
+ {
+ source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002{0}\002."), max_exception_limit);
+ return;
+ }
+ else
+ {
+ if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
+ {
+ source.Reply(_("Invalid hostmask. Only real hostmasks are valid, as exceptions are not matched against nicks or usernames."));
+ return;
+ }
+
+ for (Exception *e : Serialize::GetObjects<Exception *>())
+ if (e->GetMask().equals_ci(mask))
+ {
+ if (e->GetLimit() != limit)
+ {
+ e->SetLimit(limit);
+ source.Reply(_("Exception for \002{0}\002 has been updated to \002{1}\002."), mask, e->GetLimit());
+ }
+ else
+ source.Reply(_("\002{0}\002 already exists on the session-limit exception list."), mask);
+ return;
+ }
+
+ Exception *e = Serialize::New<Exception *>();
+ e->SetMask(mask);
+ e->SetLimit(limit);
+ e->SetReason(reason);
+ e->SetTime(Anope::CurTime);
+ e->SetWho(source.GetNick());
+ e->SetExpires(expires);
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::Exception::OnExceptionAdd, e);
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ Log(LOG_ADMIN, source, this) << "to set the session limit for " << mask << " to " << limit;
+ source.Reply(_("Session limit for \002{0}\002 set to \002{1}\002."), mask, limit);
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+ }
+
+ void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ unsigned int deleted = 0;
+
+ NumberList(mask, true,
+ [&](unsigned int number)
+ {
+ std::vector<Exception *> exceptions = Serialize::GetObjects<Exception *>();
+ if (!number || number > exceptions.size())
+ return;
+
+ Exception *e = exceptions[number - 1];
+
+ Log(LOG_ADMIN, source, this) << "to remove the session limit exception for " << e->GetMask();
+
+ ++deleted;
+ DoDel(source, e);
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("No matching entries on session-limit exception list."));
+ else if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from session-limit exception list."));
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from session-limit exception list."), deleted);
+ });
+ }
+ else
+ {
+ bool found = false;
+ for (Exception *e : Serialize::GetObjects<Exception *>())
+ if (mask.equals_ci(e->GetMask()))
+ {
+ Log(LOG_ADMIN, source, this) << "to remove the session limit exception for " << mask;
+ DoDel(source, e);
+ source.Reply(_("\002{0}\002 deleted from session-limit exception list."), mask);
+ found = true;
+ break;
+ }
+ if (!found)
+ source.Reply(_("\002{0}\002 not found on session-limit exception list."), mask);
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
+ {
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+ std::vector<Exception *> exceptions = Serialize::GetObjects<Exception *>();
+
+ if (exceptions.empty())
+ {
+ source.Reply(_("The session exception list is empty."));
+ return;
+ }
+
+ if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(mask, false,
+ [&](unsigned int number)
+ {
+ if (!number || number > exceptions.size())
+ return;
+
+ Exception *e = exceptions[number - 1];
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ entry["Mask"] = e->GetMask();
+ entry["By"] = e->GetWho();
+ entry["Created"] = Anope::strftime(e->GetTime(), NULL, true);
+ entry["Expires"] = Anope::Expires(e->GetExpires(), source.GetAccount());
+ entry["Limit"] = stringify(e->GetLimit());
+ entry["Reason"] = e->GetReason();
+ list.AddEntry(entry);
+ },
+ []{});
+ }
+ else
+ {
+ unsigned int i = 0;
+ for (Exception *e : exceptions)
+ {
+ if (mask.empty() || Anope::Match(e->GetMask(), mask))
+ {
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(++i);
+ entry["Mask"] = e->GetMask();
+ entry["By"] = e->GetWho();
+ entry["Created"] = Anope::strftime(e->GetTime(), NULL, true);
+ entry["Expires"] = Anope::Expires(e->GetExpires(), source.GetAccount());
+ entry["Limit"] = stringify(e->GetLimit());
+ entry["Reason"] = e->GetReason();
+ list.AddEntry(entry);
+ }
+ }
+ }
+
+ if (list.IsEmpty())
+ {
+ source.Reply(_("No matching entries on session-limit exception list."));
+ return;
+ }
+
+ source.Reply(_("Session-limit exception list:"));
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (const Anope::string &r : replies)
+ source.Reply(r);
+ }
+
+ void DoList(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Limit")).AddColumn(_("Mask"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ void DoView(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires")).AddColumn(_("Limit")).AddColumn(_("Reason"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ public:
+ CommandOSException(Module *creator) : Command(creator, "operserv/exception", 1, 5)
+ {
+ this->SetDesc(_("Modify the session-limit exception list"));
+ this->SetSyntax(_("ADD [\037+expiry\037] \037mask\037 \037limit\037 \037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ if (!session_limit)
+ source.Reply(_("Session limiting is disabled."));
+ else if (cmd.equals_ci("ADD"))
+ return this->DoAdd(source, params);
+ else if (cmd.equals_ci("DEL"))
+ return this->DoDel(source, params);
+ else if (cmd.equals_ci("LIST"))
+ return this->DoList(source, params);
+ else if (cmd.equals_ci("VIEW"))
+ return this->DoView(source, params);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ source.Reply(_("\002{0} ADD\002 adds the given hostmask to the exception list."
+ " Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n"
+ " Only real host masks, such as \002box.host.dom\002 and \002*.host.dom\002, are allowed because sessions limiting does not take nickname or user names into account."
+ " \037limit\037 must be a number greater than or equal to zero."
+ " This determines how many sessions this host may carry at a time."
+ " A value of zero means the host has an unlimited session limit."
+ " If more than one entry matches a client, the first matching enty will be used."),
+ source.command);
+ else
+ source.Reply(_("Allows you to manipulate the list of hosts that have specific session limits - allowing certain machines, such as shell servers, to carry more than the default number of clients at a time."
+ " Once a host reaches its session limit, all clients attempting to connect from that host will be killed."
+ " Before the user is killed, they are notified, of a source of help regarding session limiting. The content of this notice is a config setting.\n"
+ "\n"
+ "\002{0} ADD\002 adds the given host mask to the exception list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "\002{0} DEL\002 removes the given mask from the exception list.\n"
+ "\n"
+ "\002{0} LIST\002 and \002{0} VIEW\002 show all current sessions if the optional mask is given, the list is limited to those sessions matching the mask."
+ " The difference is that \002{0} VIEW\002 is more verbose, displaying the name of the person who added the exception, its session limit, reason, host mask and the expiry date and time.\n"));
+ return true;
+ }
+};
+
+class OSSession : public Module
+ , public EventHook<Event::UserConnect>
+ , public EventHook<Event::UserQuit>
+ , public EventHook<Event::ExpireTick>
+{
+ MySessionService ss;
+ CommandOSSession commandossession;
+ CommandOSException commandosexception;
+ ServiceReference<XLineManager> akills;
+ ExceptionType etype;
+
+ public:
+ OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserConnect>(this, EventHook<Event::UserConnect>::Priority::FIRST)
+ , EventHook<Event::UserQuit>(this, EventHook<Event::UserQuit>::Priority::FIRST)
+ , EventHook<Event::ExpireTick>(this, EventHook<Event::ExpireTick>::Priority::FIRST)
+ , ss(this)
+ , commandossession(this)
+ , commandosexception(this)
+ , akills("xlinemanager/sgline")
+ , etype(this)
+ {
+ this->SetPermanent(true);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = Config->GetModule(this);
+
+ session_limit = block->Get<int>("defaultsessionlimit");
+ max_session_kill = block->Get<int>("maxsessionkill");
+ session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
+ sle_reason = block->Get<Anope::string>("sessionlimitexceeded");
+ sle_detailsloc = block->Get<Anope::string>("sessionlimitdetailsloc");
+
+ max_exception_limit = block->Get<int>("maxsessionlimit");
+ exception_expiry = block->Get<time_t>("exceptionexpiry");
+
+ ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32");
+ ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128");
+
+ if (ipv4_cidr > 32 || ipv6_cidr > 128)
+ throw ConfigException(Module::name + ": session CIDR value out of range");
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined())
+ return;
+
+ cidr u_ip(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
+ if (!u_ip.valid())
+ return;
+
+ Session* &session = this->ss.FindOrCreateSession(u_ip);
+
+ if (session)
+ {
+ bool kill = false;
+ if (session->count >= session_limit)
+ {
+ kill = true;
+ Exception *e = this->ss.FindException(u);
+ if (e)
+ {
+ kill = false;
+ if (e->GetLimit() && session->count >= e->GetLimit())
+ kill = true;
+ }
+ }
+
+ ++session->count;
+
+ if (kill && !exempt)
+ {
+ ServiceBot *OperServ = Config->GetClient("OperServ");
+ if (OperServ)
+ {
+ if (!sle_reason.empty())
+ {
+ Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip.addr());
+ u->SendMessage(OperServ, message);
+ }
+ if (!sle_detailsloc.empty())
+ u->SendMessage(OperServ, sle_detailsloc);
+ }
+
+ ++session->hits;
+
+ const Anope::string &akillmask = "*@" + session->addr.mask();
+ if (max_session_kill && session->hits >= max_session_kill && akills && !akills->HasEntry(akillmask))
+ {
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(akillmask);
+ x->SetBy(OperServ ? OperServ->nick : "");
+ x->SetExpires(Anope::CurTime + session_autokill_expiry);
+ x->SetReason("Session limit exceeded");
+ x->SetID(XLineManager::GenerateUID());
+
+ akills->AddXLine(x);
+ akills->Send(NULL, x);
+
+ Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
+ }
+ else
+ {
+ u->Kill(OperServ, "Session limit exceeded");
+ }
+ }
+ }
+ else
+ {
+ session = new Session(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
+ }
+ }
+
+ void OnUserQuit(User *u, const Anope::string &msg) override
+ {
+ if (!session_limit || !u->server || u->server->IsULined())
+ return;
+
+ SessionService::SessionMap &sessions = this->ss.GetSessions();
+ SessionService::SessionMap::iterator sit = this->ss.FindSessionIterator(u->ip);
+
+ if (sit == sessions.end())
+ return;
+
+ Session *session = sit->second;
+
+ if (session->count > 1)
+ {
+ --session->count;
+ return;
+ }
+
+ delete session;
+ sessions.erase(sit);
+ }
+
+ void OnExpireTick() override
+ {
+ if (Anope::NoExpire)
+ return;
+
+ for (Exception *e : Serialize::GetObjects<Exception *>())
+ {
+ if (!e->GetExpires() || e->GetExpires() > Anope::CurTime)
+ continue;
+
+ ServiceBot *OperServ = Config->GetClient("OperServ");
+ Log(OperServ, "expire/exception") << "Session exception for " << e->GetMask() << " has expired.";
+ e->Delete();
+ }
+ }
+};
+
+MODULE_INIT(OSSession)
diff --git a/modules/commands/os_set.cpp b/modules/operserv/set.cpp
index 5aca2f370..f12f43722 100644
--- a/modules/commands/os_set.cpp
+++ b/modules/operserv/set.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -54,8 +62,6 @@ class CommandOSSet : public Command
}
else
source.Reply(_("Setting for READONLY must be \002ON\002 or \002OFF\002."));
-
- return;
}
void DoSetSuperAdmin(CommandSource &source, const std::vector<Anope::string> &params)
@@ -76,7 +82,7 @@ class CommandOSSet : public Command
*
* Rob
**/
- bool super_admin = Config->GetModule(this->owner)->Get<bool>("superadmin");
+ bool super_admin = Config->GetModule(this->GetOwner())->Get<bool>("superadmin");
if (!super_admin)
source.Reply(_("Super admin can not be set because it is not enabled in the configuration."));
else if (setting.equals_ci("ON"))
@@ -93,8 +99,6 @@ class CommandOSSet : public Command
}
else
source.Reply(_("Setting for super admin must be \002ON\002 or \002OFF\002."));
-
- return;
}
void DoSetDebug(CommandSource &source, const std::vector<Anope::string> &params)
@@ -129,7 +133,7 @@ class CommandOSSet : public Command
return;
}
catch (const ConvertException &) { }
-
+
source.Reply(_("Setting for DEBUG must be \002ON\002, \002OFF\002, or a positive number."));
}
@@ -160,8 +164,6 @@ class CommandOSSet : public Command
}
else
source.Reply(_("Setting for NOEXPIRE must be \002ON\002 or \002OFF\002."));
-
- return;
}
public:
CommandOSSet(Module *creator) : Command(creator, "operserv/set", 1, 2)
@@ -170,7 +172,7 @@ class CommandOSSet : public Command
this->SetSyntax(_("\037option\037 \037setting\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &option = params[0];
@@ -186,18 +188,13 @@ class CommandOSSet : public Command
return this->DoSetSuperAdmin(source, params);
else
this->OnSyntaxError(source, "");
-
- return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
if (subcommand.empty())
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various global Services options. Option names\n"
- "currently defined are:\n"
+ source.Reply(_("Sets various global Services options. Option names currently defined are:\n"
" READONLY Set read-only or read-write mode\n"
" DEBUG Activate or deactivate debug mode\n"
" NOEXPIRE Activate or deactivate no expire mode\n"
@@ -205,50 +202,37 @@ class CommandOSSet : public Command
" LIST List the options"));
}
else if (subcommand.equals_ci("LIST"))
- source.Reply(_("Syntax: \002LIST\002\n"
- " \n"
- "Display the various %s settings."), source.service->nick.c_str());
+ //source.Reply(_("Syntax: \002LIST\002\n"
+ // " \n"
+ source.Reply(("Display the various {0} settings."), source.service->nick);
else if (subcommand.equals_ci("READONLY"))
- source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n"
- " \n"
- "Sets read-only mode on or off. In read-only mode, normal\n"
- "users will not be allowed to modify any Services data,\n"
- "including channel and nickname access lists, etc. IRCops\n"
- "with sufficient Services privileges will be able to modify\n"
- "Services' AKILL, SQLINE, SNLINE and ignore lists, drop,\n"
- "suspend or forbid nicknames and channels, and manage news,\n"
- "oper info and DNS, but any such changes will not be saved\n"
- "unless read-only mode is deactivated before Services are\n"
- "terminated or restarted.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--readonly\002."));
+ //source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n"
+ // " \n"
+ source.Reply(_("Sets read-only mode on or off. In read-only mode, norma users will not be allowed to modify any Services data, including channel and nickname access lists, etc."
+ "Services Operators will still be able to do most tasks, but should understand any changes they do may not be permanent.\n"
+ "\n"
+ "This option is equivalent to the command-line option \002--readonly\002."));
else if (subcommand.equals_ci("DEBUG"))
- source.Reply(_("Syntax: \002DEBUG {ON | OFF}\002\n"
- " \n"
- "Sets debug mode on or off.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--debug\002."));
+ //source.Reply(_("Syntax: \002DEBUG {ON | OFF}\002\n"
+ // " \n"
+ source.Reply(_("Sets debug mode on or off.\n"
+ "\n"
+ "This option is equivalent to the command-line option \002--debug\002."));
else if (subcommand.equals_ci("NOEXPIRE"))
- source.Reply(_("Syntax: \002NOEXPIRE {ON | OFF}\002\n"
- " \n"
- "Sets no expire mode on or off. In no expire mode, nicks,\n"
- "channels, akills and exceptions won't expire until the\n"
- "option is unset.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--noexpire\002."));
+ //source.Reply(_("Syntax: \002NOEXPIRE {ON | OFF}\002\n"
+ // " \n"
+ source.Reply(_("Sets no expire mode on or off. In no expire mode, nicks, channels, akills and exceptions won't expire until the option is unset.\n"
+ "\n"
+ "This option is equivalent to the command-line option \002--noexpire\002."));
else if (subcommand.equals_ci("SUPERADMIN"))
- source.Reply(_("Syntax: \002SUPERADMIN {ON | OFF}\002\n"
- " \n"
- "Setting this will grant you extra privileges such as the\n"
- "ability to be \"founder\" on all channel's etc...\n"
- " \n"
- "This option is \002not\002 persistent, and should only be used when\n"
- "needed, and set back to OFF when no longer needed."));
+ //source.Reply(_("Syntax: \002SUPERADMIN {ON | OFF}\002\n"
+ // " \n"
+ source.Reply(_("Setting this will grant you extra privileges, such as the ability to be \"founder\" on all channels."
+ "\n"
+ "This option is \002not\002 persistent, and should only be used when needed, and set back to OFF when no longer needed."));
else
return false;
+
return true;
}
};
@@ -258,8 +242,8 @@ class OSSet : public Module
CommandOSSet commandosset;
public:
- OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosset(this)
+ OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosset(this)
{
}
};
diff --git a/modules/commands/os_shutdown.cpp b/modules/operserv/shutdown.cpp
index 1142edbc0..c0adc182e 100644
--- a/modules/commands/os_shutdown.cpp
+++ b/modules/operserv/shutdown.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -16,10 +24,10 @@ class CommandOSQuit : public Command
public:
CommandOSQuit(Module *creator) : Command(creator, "operserv/quit", 0, 0)
{
- this->SetDesc(_("Terminate Services WITHOUT saving"));
+ this->SetDesc(_("Terminate Services without saving"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
Log(LOG_ADMIN, source, this);
Anope::QuitReason = source.command + " command received from " + source.GetNick();
@@ -27,14 +35,11 @@ class CommandOSQuit : public Command
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to do an immediate shutdown; databases are\n"
- "\002not\002 saved. This command should not be used unless\n"
- "damage to the in-memory copies of the databases is feared\n"
- "and they should not be saved."));
+ source.Reply(_("Causes Services to do an immediate shutdown; databases may \002not\002 saved."
+ " If you are using a real time database such as SQL or Redis, this command is not useful."
+ " This command should not be used unless damage to the in-memory copies of the databases is feared and they should not be saved."));
return true;
}
};
@@ -47,7 +52,7 @@ class CommandOSRestart : public Command
this->SetDesc(_("Save databases and restart Services"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
Log(LOG_ADMIN, source, this);
Anope::QuitReason = source.command + " command received from " + source.GetNick();
@@ -56,11 +61,9 @@ class CommandOSRestart : public Command
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(_("Causes Services to save all databases and then restart\n"
- "(i.e. exit and immediately re-run the executable)."));
+ source.Reply(_("Causes Services to restart."));
return true;
}
};
@@ -73,7 +76,7 @@ class CommandOSShutdown : public Command
this->SetDesc(_("Terminate services with save"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
Log(LOG_ADMIN, source, this);
Anope::QuitReason = source.command + " command received from " + source.GetNick();
@@ -82,11 +85,9 @@ class CommandOSShutdown : public Command
return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to save all databases and then shut down."));
+ source.Reply(_("Causes Services to shut down"));
return true;
}
};
diff --git a/modules/operserv/stats.cpp b/modules/operserv/stats.cpp
new file mode 100644
index 000000000..8476e616e
--- /dev/null
+++ b/modules/operserv/stats.cpp
@@ -0,0 +1,327 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/operserv/session.h"
+#include "modules/operserv/stats.h"
+
+class StatsImpl : public Stats
+{
+ friend class StatsType;
+
+ unsigned int maxusercnt = 0;
+ time_t maxusertime = 0;
+
+ public:
+
+ using Stats::Stats;
+
+ unsigned int GetMaxUserCount() override;
+ void SetMaxUserCount(unsigned int i) override;
+
+ time_t GetMaxUserTime() override;
+ void SetMaxUserTime(time_t t) override;
+};
+
+class StatsType : public Serialize::Type<StatsImpl>
+{
+ public:
+ Serialize::Field<StatsImpl, unsigned int> maxusercount;
+ Serialize::Field<StatsImpl, time_t> maxusertime;
+
+ StatsType(Module *me) : Serialize::Type<StatsImpl>(me)
+ , maxusercount(this, "maxusercount", &StatsImpl::maxusercnt)
+ , maxusertime(this, "maxusertime", &StatsImpl::maxusertime)
+ {
+ }
+};
+
+unsigned int StatsImpl::GetMaxUserCount()
+{
+ return Get(&StatsType::maxusercount);
+}
+
+void StatsImpl::SetMaxUserCount(unsigned int i)
+{
+ Set(&StatsType::maxusercount, i);
+}
+
+time_t StatsImpl::GetMaxUserTime()
+{
+ return Get(&StatsType::maxusertime);
+}
+
+void StatsImpl::SetMaxUserTime(time_t t)
+{
+ Set(&StatsType::maxusertime, t);
+}
+
+/**
+ * Count servers connected to server s
+ * @param s The server to start counting from
+ * @return Amount of servers connected to server s
+ **/
+static int stats_count_servers(Server *s)
+{
+ if (!s)
+ return 0;
+
+ int count = 1;
+
+ if (!s->GetLinks().empty())
+ for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
+ count += stats_count_servers(s->GetLinks()[i]);
+
+ return count;
+}
+
+class CommandOSStats : public Command
+{
+ ServiceReference<XLineManager> akills, snlines, sqlines;
+ ServiceReference<SessionService> session_service;
+
+ private:
+ void DoStatsAkill(CommandSource &source)
+ {
+ int timeout;
+ if (akills)
+ {
+ /* AKILLs */
+ source.Reply(_("Current number of AKILLs: \002{0}\002"), akills->GetCount());
+ timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59;
+ if (timeout >= 172800)
+ source.Reply(_("Default AKILL expiry time: \002{0} days\002"), timeout / 86400);
+ else if (timeout >= 86400)
+ source.Reply(_("Default AKILL expiry time: \0021 day\002"));
+ else if (timeout >= 7200)
+ source.Reply(_("Default AKILL expiry time: \002{0} hours\002"), timeout / 3600);
+ else if (timeout >= 3600)
+ source.Reply(_("Default AKILL expiry time: \0021 hour\002"));
+ else if (timeout >= 120)
+ source.Reply(_("Default AKILL expiry time: \002{0} minutes\002"), timeout / 60);
+ else if (timeout >= 60)
+ source.Reply(_("Default AKILL expiry time: \0021 minute\002"));
+ else
+ source.Reply(_("Default AKILL expiry time: \002No expiration\002"));
+ }
+ if (snlines)
+ {
+ /* SNLINEs */
+ source.Reply(_("Current number of SNLINEs: \002{0}\002"), snlines->GetCount());
+ timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59;
+ if (timeout >= 172800)
+ source.Reply(_("Default SNLINE expiry time: \002{0} days\002"), timeout / 86400);
+ else if (timeout >= 86400)
+ source.Reply(_("Default SNLINE expiry time: \0021 day\002"));
+ else if (timeout >= 7200)
+ source.Reply(_("Default SNLINE expiry time: \002{0} hours\002"), timeout / 3600);
+ else if (timeout >= 3600)
+ source.Reply(_("Default SNLINE expiry time: \0021 hour\002"));
+ else if (timeout >= 120)
+ source.Reply(_("Default SNLINE expiry time: \002{0} minutes\002"), timeout / 60);
+ else if (timeout >= 60)
+ source.Reply(_("Default SNLINE expiry time: \0021 minute\002"));
+ else
+ source.Reply(_("Default SNLINE expiry time: \002No expiration\002"));
+ }
+ if (sqlines)
+ {
+ /* SQLINEs */
+ source.Reply(_("Current number of SQLINEs: \002{0}\002"), sqlines->GetCount());
+ timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59;
+ if (timeout >= 172800)
+ source.Reply(_("Default SQLINE expiry time: \002{0} days\002"), timeout / 86400);
+ else if (timeout >= 86400)
+ source.Reply(_("Default SQLINE expiry time: \0021 day\002"));
+ else if (timeout >= 7200)
+ source.Reply(_("Default SQLINE expiry time: \002{0} hours\002"), timeout / 3600);
+ else if (timeout >= 3600)
+ source.Reply(_("Default SQLINE expiry time: \0021 hour\002"));
+ else if (timeout >= 120)
+ source.Reply(_("Default SQLINE expiry time: \002{0} minutes\002"), timeout / 60);
+ else if (timeout >= 60)
+ source.Reply(_("Default SQLINE expiry time: \0021 minute\002"));
+ else
+ source.Reply(_("Default SQLINE expiry time: \002No expiration\002"));
+ }
+ }
+
+ void DoStatsReset(CommandSource &source)
+ {
+ Stats *stats = Serialize::GetObject<Stats *>();
+ stats->SetMaxUserCount(UserListByNick.size());
+ source.Reply(_("Statistics reset."));
+ return;
+ }
+
+ void DoStatsUptime(CommandSource &source)
+ {
+ Stats *stats = Serialize::GetObject<Stats *>();
+ time_t uptime = Anope::CurTime - Anope::StartTime;
+
+ source.Reply(_("Current users: \002{0}\002 (\002{1}\002 ops)"), UserListByNick.size(), OperCount);
+ source.Reply(_("Maximum users: \002{0}\002 ({1})"), stats->GetMaxUserCount(), Anope::strftime(stats->GetMaxUserTime(), source.GetAccount()));
+ source.Reply(_("Services up \002{0}\002."), Anope::Duration(uptime, source.GetAccount()));
+ }
+
+ void DoStatsUplink(CommandSource &source)
+ {
+ Anope::string buf;
+ for (std::set<Anope::string>::iterator it = Servers::Capab.begin(); it != Servers::Capab.end(); ++it)
+ buf += " " + *it;
+ if (!buf.empty())
+ buf.erase(buf.begin());
+
+ source.Reply(_("Uplink server: \002{0}\002"), Me->GetLinks().front()->GetName());
+ source.Reply(_("Uplink capab: {0}"), buf);
+ source.Reply(_("Servers found: {0}"), stats_count_servers(Me->GetLinks().front()));
+ }
+
+ template<typename T> void GetHashStats(const T& map, size_t& entries, size_t& buckets, size_t& max_chain)
+ {
+ entries = map.size(), buckets = map.bucket_count(), max_chain = 0;
+ for (size_t i = 0; i < buckets; ++i)
+ if (map.bucket_size(i) > max_chain)
+ max_chain = map.bucket_size(i);
+ }
+
+ void DoStatsHash(CommandSource &source)
+ {
+ size_t entries, buckets, max_chain;
+
+ GetHashStats(UserListByNick, entries, buckets, max_chain);
+ source.Reply(_("Users (nick): {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+
+ if (!UserListByUID.empty())
+ {
+ GetHashStats(UserListByUID, entries, buckets, max_chain);
+ source.Reply(_("Users (uid): {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+ }
+
+ GetHashStats(ChannelList, entries, buckets, max_chain);
+ source.Reply(_("Channels: {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+
+ GetHashStats(ChanServ::service->GetChannels(), entries, buckets, max_chain);
+ source.Reply(_("Registered channels: {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+
+ GetHashStats(NickServ::service->GetNickMap(), entries, buckets, max_chain);
+ source.Reply(_("Registered nicknames: {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+
+ GetHashStats(NickServ::service->GetAccountMap(), entries, buckets, max_chain);
+ source.Reply(_("Registered nick groups: {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+
+ if (session_service)
+ {
+ GetHashStats(session_service->GetSessions(), entries, buckets, max_chain);
+ source.Reply(_("Sessions: {0} entries, {1} buckets, longest chain is {2}"), entries, buckets, max_chain);
+ }
+ }
+
+ public:
+ CommandOSStats(Module *creator) : Command(creator, "operserv/stats", 0, 1)
+ , akills("sgline")
+ , snlines("snline")
+ , sqlines("sqline")
+ {
+ this->SetDesc(_("Show status of Services and network"));
+ this->SetSyntax("[AKILL | HASH | UPLINK | UPTIME | ALL | RESET]");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ Anope::string extra = !params.empty() ? params[0] : "";
+
+ Log(LOG_ADMIN, source, this) << extra;
+
+ if (extra.equals_ci("RESET"))
+ return this->DoStatsReset(source);
+
+ if (extra.equals_ci("ALL") || extra.equals_ci("AKILL"))
+ this->DoStatsAkill(source);
+
+ if (extra.equals_ci("ALL") || extra.equals_ci("HASH"))
+ this->DoStatsHash(source);
+
+ if (extra.equals_ci("ALL") || extra.equals_ci("UPLINK"))
+ this->DoStatsUplink(source);
+
+ if (extra.empty() || extra.equals_ci("ALL") || extra.equals_ci("UPTIME"))
+ this->DoStatsUptime(source);
+
+ if (!extra.empty() && !extra.equals_ci("ALL") && !extra.equals_ci("AKILL") && !extra.equals_ci("HASH") && !extra.equals_ci("UPLINK") && !extra.equals_ci("UPTIME"))
+ source.Reply(_("Unknown STATS option: \002{0}\002"), extra);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Without any option, shows the current number of users online, and the highest number of users online since Services was started, and the length of time Services has been running.\n"
+ "\n"
+ "With the \002AKILL\002 option, displays the current size of the AKILL list and the current default expiry time.\n"
+ "\n"
+ "The \002RESET\002 option currently resets the maximum user count to the number of users currently present on the network.\n"
+ "\n"
+ "The \002UPLINK\002 option displays information about the current server Anope uses as an uplink to the network.\n"
+ "\n"
+ "The \002HASH\002 option displays information about the hash maps.\n"
+ "\n"
+ "The \002ALL\002 option displays all of the above statistics."));
+ return true;
+ }
+};
+
+class OSStats : public Module
+ , public EventHook<Event::UserConnect>
+{
+ CommandOSStats commandosstats;
+ StatsType stats_type;
+
+ Stats *GetStats()
+ {
+ Stats *stats = Serialize::GetObject<Stats *>();
+ if (stats)
+ return stats;
+ else
+ return Serialize::New<Stats *>();
+ }
+
+ public:
+ OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::UserConnect>(this)
+ , commandosstats(this)
+ , stats_type(this)
+ {
+ }
+
+ void OnUserConnect(User *u, bool &exempt) override
+ {
+ Stats *stats = GetStats();
+
+ if (stats && UserListByNick.size() > stats->GetMaxUserCount())
+ {
+ stats->SetMaxUserCount(UserListByNick.size());
+ stats->SetMaxUserTime(Anope::CurTime);
+
+ Server *sserver = u->server;
+ if (sserver && sserver->IsSynced())
+ Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size();
+ }
+ }
+};
+
+MODULE_INIT(OSStats)
diff --git a/modules/commands/os_svs.cpp b/modules/operserv/svs.cpp
index 769adb338..0a5acac2f 100644
--- a/modules/commands/os_svs.cpp
+++ b/modules/operserv/svs.cpp
@@ -1,12 +1,20 @@
-/* OperServ core functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +28,7 @@ class CommandOSSVSNick : public Command
this->SetSyntax(_("\037nick\037 \037newnick\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const Anope::string &nick = params[0];
Anope::string newnick = params[1];
@@ -36,35 +44,32 @@ class CommandOSSVSNick : public Command
unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
if (newnick.length() > nicklen)
{
- source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), nicklen, newnick.c_str());
+ source.Reply(_("Nick \002{0}\002 was truncated to \002{1}\002 characters."), newnick, nicklen);
newnick = params[1].substr(0, nicklen);
}
/* Check for valid characters */
if (!IRCD->IsNickValid(newnick))
{
- source.Reply(_("Nick \002%s\002 is an illegal nickname and cannot be used."), newnick.c_str());
+ source.Reply(_("Nick \002{0}\002 is an illegal nickname and cannot be used."), newnick);
return;
}
/* Check for a nick in use or a forbidden/suspended nick */
if (!(u2 = User::Find(nick, true)))
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), nick);
else if (!nick.equals_ci(newnick) && User::Find(newnick))
- source.Reply(_("Nick \002%s\002 is currently in use."), newnick.c_str());
+ source.Reply(_("\002{0}\002 is currently in use."), newnick);
else
{
- source.Reply(_("The nick \002%s\002 is now being changed to \002%s\002."), nick.c_str(), newnick.c_str());
+ source.Reply(_("\002{0}\002 is now being changed to \002{1}\002."), nick, newnick);
Log(LOG_ADMIN, source, this) << "to change " << nick << " to " << newnick;
IRCD->SendForceNickChange(u2, newnick, Anope::CurTime);
}
- return;
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
source.Reply(_("Forcefully changes a user's nickname from \037nick\037 to \037newnick\037."));
return true;
}
@@ -76,10 +81,10 @@ class CommandOSSVSJoin : public Command
CommandOSSVSJoin(Module *creator) : Command(creator, "operserv/svsjoin", 2, 2)
{
this->SetDesc(_("Forcefully join a user to a channel"));
- this->SetSyntax(_("\037nick\037 \037channel\037"));
+ this->SetSyntax(_("\037user\037 \037channel\037"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (!IRCD->CanSVSJoin)
{
@@ -90,26 +95,24 @@ class CommandOSSVSJoin : public Command
User *target = User::Find(params[0], true);
Channel *c = Channel::Find(params[1]);
if (target == NULL)
- source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), params[0]);
else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
- source.Reply(ACCESS_DENIED);
- else if (!IRCD->IsChannelValid(params[1]))
- source.Reply(CHAN_X_INVALID, params[1].c_str());
+ source.Reply(_("Access denied."));
+ else if (!c && !IRCD->IsChannelValid(params[1]))
+ source.Reply(_("\002{0}\002 isn't a valid channel."), params[1]);
else if (c && c->FindUser(target))
- source.Reply(_("\002%s\002 is already in \002%s\002."), target->nick.c_str(), c->name.c_str());
+ source.Reply(_("\002{0}\002 is already in \002{1}\002."), target->nick, c->name);
else
{
IRCD->SendSVSJoin(*source.service, target, params[1], "");
Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to join " << params[1];
- source.Reply(_("\002%s\002 has been joined to \002%s\002."), target->nick.c_str(), params[1].c_str());
+ source.Reply(_("\002{0}\002 has been joined to \002{1}\002."), target->nick, params[1]);
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forcefully join a user to a channel."));
+ source.Reply(_("Forcefully join \037user\037 to \037channel\037."));
return true;
}
};
@@ -123,7 +126,7 @@ class CommandOSSVSPart : public Command
this->SetSyntax(_("\037nick\037 \037channel\037 [\037reason\037]"));
}
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
if (!IRCD->CanSVSJoin)
{
@@ -135,13 +138,13 @@ class CommandOSSVSPart : public Command
Channel *c = Channel::Find(params[1]);
const Anope::string &reason = params.size() > 2 ? params[2] : "";
if (target == NULL)
- source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
+ source.Reply(_("\002{0}\002 isn't currently online."), params[0]);
else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
- source.Reply(ACCESS_DENIED);
+ source.Reply(_("Access denied."));
else if (!c)
- source.Reply(CHAN_X_NOT_IN_USE, params[1].c_str());
+ source.Reply(_("Channel \002{0}\002 doesn't exist."), params[1]);
else if (!c->FindUser(target))
- source.Reply(_("\002%s\002 is not in \002%s\002."), target->nick.c_str(), c->name.c_str());
+ source.Reply(_("\002{0}\002 is not in \002{1}\002."), target->nick, c->name);
else
{
IRCD->SendSVSPart(*source.service, target, params[1], reason);
@@ -149,15 +152,13 @@ class CommandOSSVSPart : public Command
Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name << " with reason " << reason;
else
Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name;
- source.Reply(_("\002%s\002 has been parted from \002%s\002."), target->nick.c_str(), c->name.c_str());
+ source.Reply(_("\002{0}\002 has been parted from \002{1}\002."), target->nick, c->name);
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forcefully part a user from a channel."));
+ source.Reply(_("Forcefully part \037user\037 from \037channel\037."));
return true;
}
};
diff --git a/modules/operserv/sxline.cpp b/modules/operserv/sxline.cpp
new file mode 100644
index 000000000..748418790
--- /dev/null
+++ b/modules/operserv/sxline.cpp
@@ -0,0 +1,701 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSSXLineBase : public Command
+{
+ private:
+ virtual XLineManager* xlm() anope_abstract;
+
+ virtual void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) anope_abstract;
+
+ void OnDel(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ if (!this->xlm() || this->xlm()->GetXLines().empty())
+ {
+ source.Reply(_("{0} list is empty."), source.command);
+ return;
+ }
+
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(source, "DEL");
+ return;
+ }
+
+ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ unsigned int deleted = 0;
+
+ NumberList(mask, true,
+ [&](unsigned int number)
+ {
+ XLine *x = this->xlm()->GetEntry(number - 1);
+
+ if (!x)
+ return;
+
+ Log(LOG_ADMIN, source, this) << "to remove " << x->GetMask() << " from the list";
+
+ ++deleted;
+ x->Delete();
+ },
+ [&]()
+ {
+ if (!deleted)
+ source.Reply(_("No matching entries on the {0} list."), source.command);
+ else if (deleted == 1)
+ source.Reply(_("Deleted \0021\002 entry from the {0} list."), source.command);
+ else
+ source.Reply(_("Deleted \002{0}\002 entries from the {1} list."), deleted, source.command);
+ });
+ }
+ else
+ {
+ XLine *x = this->xlm()->HasEntry(mask);
+
+ if (!x)
+ {
+ source.Reply(_("\002{0}\002 not found on the {1] list."), mask, source.command);
+ return;
+ }
+
+ EventManager::Get()->Dispatch(&Event::DelXLine::OnDelXLine, source, x, this->xlm());
+
+ x->Delete();
+ source.Reply(_("\002{0}\002 deleted from the {1} list."), mask, source.command);
+ Log(LOG_ADMIN, source, this) << "to remove " << mask << " from the list";
+ }
+
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
+ {
+ if (!this->xlm() || this->xlm()->GetXLines().empty())
+ {
+ source.Reply(_("{0} list is empty."), source.command);
+ return;
+ }
+
+ const Anope::string &mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
+ {
+ NumberList(mask, false,
+ [&](unsigned int number)
+ {
+ XLine *x = this->xlm()->GetEntry(number - 1);
+
+ if (!x)
+ return;
+
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(number);
+ entry["Mask"] = x->GetMask();
+ entry["By"] = x->GetBy();
+ entry["Created"] = Anope::strftime(x->GetCreated(), NULL, true);
+ entry["Expires"] = Anope::Expires(x->GetExpires(), source.nc);
+ entry["ID"] = x->GetID();
+ entry["Reason"] = x->GetReason();
+ list.AddEntry(entry);
+ },
+ []{});
+ }
+ else
+ {
+ unsigned int i = 0;
+ for (XLine *x : this->xlm()->GetXLines())
+ {
+ if (mask.empty() || mask.equals_ci(x->GetMask()) || mask == x->GetID() || Anope::Match(x->GetMask(), mask, false, true))
+ {
+ ListFormatter::ListEntry entry;
+ entry["Number"] = stringify(i + 1);
+ entry["Mask"] = x->GetMask();
+ entry["By"] = x->GetBy();
+ entry["Created"] = Anope::strftime(x->GetCreated(), NULL, true);
+ entry["Expires"] = Anope::Expires(x->GetExpires(), source.nc);
+ entry["ID"] = x->GetID();
+ entry["Reason"] = x->GetReason();
+ list.AddEntry(entry);
+ }
+ }
+ }
+
+ if (list.IsEmpty())
+ source.Reply(_("No matching entries on the {0} list."), source.command);
+ else
+ {
+ source.Reply(_("{0} list:"), source.command);
+
+ std::vector<Anope::string> replies;
+ list.Process(replies);
+
+ for (unsigned i = 0; i < replies.size(); ++i)
+ source.Reply(replies[i]);
+ }
+ }
+
+ void OnList(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ void OnView(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ ListFormatter list(source.GetAccount());
+ list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires"));
+ if (Config->GetModule("operserv")->Get<bool>("akillids"))
+ list.AddColumn(_("ID"));
+ list.AddColumn(_("Reason"));
+
+ this->ProcessList(source, params, list);
+ }
+
+ void OnClear(CommandSource &source)
+ {
+ EventManager::Get()->Dispatch(&Event::DelXLine::OnDelXLine, source, nullptr, this->xlm());
+
+ for (XLine *x : this->xlm()->GetXLines())
+ x->Delete();
+
+ Log(LOG_ADMIN, source, this) << "to CLEAR the list";
+ source.Reply(_("The {0} list has been cleared."), source.command);
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+ public:
+ CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 4)
+ {
+ }
+
+ const Anope::string GetDesc(CommandSource &source) const override
+ {
+ return Anope::printf(Language::Translate(source.GetAccount(), _("Manipulate the %s list")), source.command.upper().c_str());
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &cmd = params[0];
+
+ if (cmd.equals_ci("ADD"))
+ return this->OnAdd(source, params);
+ else if (cmd.equals_ci("DEL"))
+ return this->OnDel(source, params);
+ else if (cmd.equals_ci("LIST"))
+ return this->OnList(source, params);
+ else if (cmd.equals_ci("VIEW"))
+ return this->OnView(source, params);
+ else if (cmd.equals_ci("CLEAR"))
+ return this->OnClear(source);
+ else
+ this->OnSyntaxError(source, "");
+ }
+
+ virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) override = 0;
+};
+
+class CommandOSSNLine : public CommandOSSXLineBase
+{
+ XLineManager *xlm() override
+ {
+ return this->snlines;
+ }
+
+ void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!this->xlm())
+ return;
+
+ unsigned last_param = 2;
+ Anope::string param, expiry;
+
+ param = params.size() > 1 ? params[1] : "";
+ if (!param.empty() && param[0] == '+')
+ {
+ expiry = param;
+ param = params.size() > 2 ? params[2] : "";
+ last_param = 3;
+ }
+
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d");
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires && expires < 60)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ else if (expires > 0)
+ expires += Anope::CurTime;
+
+ if (param.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ Anope::string rest = param;
+ if (params.size() > last_param)
+ rest += " " + params[last_param];
+
+ if (rest.find(':') == Anope::string::npos)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ sepstream sep(rest, ':');
+ Anope::string mask;
+ sep.GetToken(mask);
+ Anope::string reason = sep.GetRemaining();
+
+ if (mask.empty() || reason.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (mask[0] == '/' && mask[mask.length() - 1] == '/')
+ {
+ if (!Config->regex_flags)
+ {
+ source.Reply(_("Regex is disabled."));
+ return;
+ }
+
+ Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
+ try
+ {
+ std::regex(stripped_mask.str(), Config->regex_flags);
+ }
+ catch (const std::regex_error &ex)
+ {
+ source.Reply(ex.what());
+ return;
+ }
+ }
+
+ /* Clean up the last character of the mask if it is a space
+ * See bug #761
+ */
+ unsigned masklen = mask.length();
+ if (mask[masklen - 1] == ' ')
+ mask.erase(masklen - 1);
+
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
+ if (mask.find_first_not_of("/.*?") == Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; please use a more specific mask."), mask);
+ return;
+ }
+
+ if (!this->xlm()->CanAdd(source, mask, expires, reason))
+ return;
+
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(source.GetNick());
+ x->SetExpires(expires);
+ x->SetReason(reason);
+
+ if (Config->GetModule("operserv")->Get<bool>("akillids"))
+ x->SetID(XLineManager::GenerateUID());
+
+ unsigned int affected = 0;
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (this->xlm()->Check(it->second, x))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; please use a more specific mask."), mask);
+ Log(LOG_ADMIN, source, this) << "tried to " << source.command << " " << percent << "% of the network (" << affected << " users)";
+ delete x;
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::AddXLine::OnAddXLine, source, x, this->xlm());
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return;
+ }
+
+ this->xlm()->AddXLine(x);
+
+ if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes"))
+ {
+ Anope::string rreason = "G-Lined: " + reason;
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *user = it->second;
+
+ if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
+ user->Kill(Me, rreason);
+ }
+
+ this->xlm()->Send(NULL, x);
+ }
+
+ source.Reply(_("\002{0}\002 added to the {1} list."), mask, source.command);
+ Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ ServiceReference<XLineManager> snlines;
+ public:
+ CommandOSSNLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/snline")
+ , snlines("xlinemanager/snline")
+ {
+ this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax("CLEAR");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("\002{0} ADD\002 adds the given \037mask\037 to the {0} list for the given \037reason\037."
+ " \037expiry\037 is specified as an integer followed by one of \037d\037 (days), \037h\037 (hours), or \037m\037 (minutes)."
+ " If a unit specifier is not included, the default is days, so \037+30\037 by itself means 30 days."
+ " To add a {0} which does not expire, use \037+0\037."
+ " The default {0} expiry time is \002{1}\002."
+ " Because the real name may contain spaces, the separator between it and the reason is a \002colon\002."),
+ source.command, Anope::Duration(Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d"), source.GetAccount()));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your mask in // if this is desired."), regexengine);
+ }
+ }
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes the given \037mask\037 from the {0} list if it is present."
+ " If a list of entry numbers is given, those entries are deleted."));
+ else if (subcommand.equals_ci("LIST") || subcommand.equals_ci("VIEW"))
+ source.Reply(_("The \002{0} LIST\002 and \002{0} VIEW\002 commands displays the {0} list.\n"
+ "If a wildcard \037mask\037 is given, only those entries matching the \037mask\037 are displayed."
+ " If a list of entry numbers is given, only those entries are shown."
+ " \002VIEW\002 is similar to \002LIST\002 but also shows who created the {0}, when it was created, and when it expires.\n"
+ "\n"
+ "Example:\n"
+ "\n"
+ " {0} LIST 2-5,7-9\n"
+ " Lists {0} entries numbered 2 through 5 and 7 through 9.\n"),
+ source.command);
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("\002{0} CLEAR\002 removes all entries from the {0} list."),
+ source.command);
+ else
+ {
+ CommandInfo *help = source.service->FindCommand("generic/help");
+
+ source.Reply(_("Allows you to manipulate the {0} list."
+ " If a user attempts to use a realname that matches a {0} mask, services will kill the user."
+ "\n"
+ "The \002ADD\002 command adds \037mask\037 to the {0} list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the {0} list.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002VIEW\002 commands both show the {0} list, but \002VIEW\002 also shows who created the {0} entry, when it was created, and when it expires.\n"
+ "\002{msg}{service} {help} {command} [LIST | VIEW]\002 for more information.\n"
+ "\n"
+ "The \002CLEAR\002 command clears th auto kill list."
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information.\n"),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "help"_kw = help->cname, "command"_kw = source.command);
+ }
+ return true;
+ }
+};
+
+class CommandOSSQLine : public CommandOSSXLineBase
+{
+ XLineManager *xlm() override
+ {
+ return this->sqlines;
+ }
+
+ void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (!this->xlm())
+ return;
+
+ unsigned last_param = 2;
+ Anope::string expiry, mask;
+
+ mask = params.size() > 1 ? params[1] : "";
+ if (!mask.empty() && mask[0] == '+')
+ {
+ expiry = mask;
+ mask = params.size() > 2 ? params[2] : "";
+ last_param = 3;
+ }
+
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d");
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires && expires < 60)
+ {
+ source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
+ return;
+ }
+ else if (expires > 0)
+ expires += Anope::CurTime;
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ Anope::string reason = params[last_param];
+ if (last_param == 2 && params.size() > 3)
+ reason += " " + params[3];
+
+ if (mask.empty() || reason.empty())
+ {
+ this->OnSyntaxError(source, "ADD");
+ return;
+ }
+
+ if (mask[0] == '/' && mask[mask.length() - 1] == '/')
+ {
+ if (!Config->regex_flags)
+ {
+ source.Reply(_("Regex is disabled."));
+ return;
+ }
+
+ Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
+ try
+ {
+ std::regex(stripped_mask.str(), Config->regex_flags);
+ }
+ catch (const std::regex_error &ex)
+ {
+ source.Reply(ex.what());
+ return;
+ }
+ }
+
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
+ if (mask.find_first_not_of("./?*") == Anope::string::npos)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; please use a more specific mask."), mask);
+ return;
+ }
+
+ if (!this->sqlines->CanAdd(source, mask, expires, reason))
+ return;
+
+ XLine *x = Serialize::New<XLine *>();
+ x->SetMask(mask);
+ x->SetBy(source.GetNick());
+ x->SetExpires(expires);
+ x->SetReason(reason);
+
+ if (Config->GetModule("operserv")->Get<bool>("akillids"))
+ x->SetID(XLineManager::GenerateUID());
+
+ unsigned int affected = 0;
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (this->xlm()->Check(it->second, x))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_("\002{0}\002 coverage is too wide; please use a more specific mask."), mask);
+ Log(LOG_ADMIN, source, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)";
+ delete x;
+ return;
+ }
+
+ EventReturn MOD_RESULT;
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::AddXLine::OnAddXLine, source, x, this->xlm());
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return;
+ }
+
+ this->xlm()->AddXLine(x);
+
+ if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes"))
+ {
+ Anope::string rreason = "Q-Lined: " + reason;
+
+ if (mask[0] == '#')
+ {
+ for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
+ {
+ Channel *c = cit->second;
+
+ if (!Anope::Match(c->name, mask, false, true))
+ continue;
+
+ std::vector<User *> users;
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
+ {
+ ChanUserContainer *uc = it->second;
+ User *user = uc->user;
+
+ if (!user->HasMode("OPER") && user->server != Me)
+ users.push_back(user);
+ }
+
+ for (unsigned i = 0; i < users.size(); ++i)
+ c->Kick(NULL, users[i], "%s", reason.c_str());
+ }
+ }
+ else
+ {
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *user = it->second;
+
+ if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
+ user->Kill(Me, rreason);
+ }
+ }
+
+ this->xlm()->Send(NULL, x);
+ }
+
+ source.Reply(_("\002{0}\002 added to the {1} list."), mask, source.command);
+ Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ if (Anope::ReadOnly)
+ source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ }
+
+ ServiceReference<XLineManager> sqlines;
+ public:
+ CommandOSSQLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/sqline")
+ , sqlines("xlinemanager/sqline")
+ {
+ this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
+ this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
+ this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
+ this->SetSyntax("CLEAR");
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ if (subcommand.equals_ci("ADD"))
+ {
+ source.Reply(_("\002{0} ADD\002 adds the given \037mask\037 to the {0} list for the given \037reason\037."
+ " \037expiry\037 is specified as an integer followed by one of \037d\037 (days), \037h\037 (hours), or \037m\037 (minutes)."
+ " If a unit specifier is not included, the default is days, so \037+30\037 by itself means 30 days."
+ " To add a {0} which does not expire, use \037+0\037."
+ " The default {0} expiry time is \002{1}\002."),
+ source.command, Anope::Duration(Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d"), source.GetAccount()));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your mask in // if this is desired."), regexengine);
+ }
+ }
+ else if (subcommand.equals_ci("DEL"))
+ source.Reply(_("The \002{0} DEL\002 command removes the given \037mask\037 from the {0} list if it is present."
+ " If a list of entry numbers is given, those entries are deleted."));
+ else if (subcommand.equals_ci("LIST") || subcommand.equals_ci("VIEW"))
+ source.Reply(_("The \002{0} LIST\002 and \002{0} VIEW\002 commands displays the {0} list.\n"
+ "If a wildcard \037mask\037 is given, only those entries matching the \037mask\037 are displayed."
+ " If a list of entry numbers is given, only those entries are shown."
+ " \002VIEW\002 is similar to \002LIST\002 but also shows who created the {0}, when it was created, and when it expires.\n"
+ "\n"
+ "Example:\n"
+ "\n"
+ " {0} LIST 2-5,7-9\n"
+ " Lists {0} entries numbered 2 through 5 and 7 through 9.\n"),
+ source.command);
+ else if (subcommand.equals_ci("CLEAR"))
+ source.Reply(_("\002{0} CLEAR\002 removes all entries from the {0} list."),
+ source.command);
+ else
+ {
+ CommandInfo *help = source.service->FindCommand("generic/help");
+
+ source.Reply(_("Allows you to manipulate the {0} list."
+ " If a user attempts to use a nickname that matches a {0} mask, services will force the user off of the nickname."
+ " If the first character of the mask is a #, services will prevent the use of matching channels."
+ "\n"
+ "The \002ADD\002 command adds \037mask\037 to the {0} list.\n"
+ "\002{msg}{service} {help} {command} ADD\002 for more information.\n"
+ "\n"
+ "The \002DEL\002 command removes \037mask\037 from the {0} list.\n"
+ "\002{msg}{service} {help} {command} DEL\002 for more information.\n"
+ "\n"
+ "The \002LIST\002 and \002VIEW\002 commands both show the {0} list, but \002VIEW\002 also shows who created the {0} entry, when it was created, and when it expires.\n"
+ "\002{msg}{service} {help} {command} [LIST | VIEW]\002 for more information.\n"
+ "\n"
+ "The \002CLEAR\002 command clears th auto kill list."
+ "\002{msg}{service} {help} {command} CLEAR\002 for more information.\n"),
+ "msg"_kw = Config->StrictPrivmsg, "service"_kw = source.service->nick, "help"_kw = help->cname, "command"_kw = source.command);
+ }
+ return true;
+ }
+};
+
+class OSSXLine : public Module
+{
+ CommandOSSNLine commandossnline;
+ CommandOSSQLine commandossqline;
+
+ public:
+ OSSXLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
+ commandossnline(this), commandossqline(this)
+ {
+ }
+};
+
+MODULE_INIT(OSSXLine)
diff --git a/modules/operserv/update.cpp b/modules/operserv/update.cpp
new file mode 100644
index 000000000..753644415
--- /dev/null
+++ b/modules/operserv/update.cpp
@@ -0,0 +1,57 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandOSUpdate : public Command
+{
+ public:
+ CommandOSUpdate(Module *creator) : Command(creator, "operserv/update", 0, 0)
+ {
+ this->SetDesc(_("Force the Services databases to be updated immediately"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ Log(LOG_ADMIN, source, this);
+ source.Reply(_("Updating databases."));
+ Anope::SaveDatabases();
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Causes Services to update all database files."));
+ return true;
+ }
+};
+
+class OSUpdate : public Module
+{
+ CommandOSUpdate commandosupdate;
+
+ public:
+ OSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandosupdate(this)
+ {
+
+ }
+};
+
+MODULE_INIT(OSUpdate)
diff --git a/modules/protocol/CMakeLists.txt b/modules/protocol/CMakeLists.txt
new file mode 100644
index 000000000..9a236d6d0
--- /dev/null
+++ b/modules/protocol/CMakeLists.txt
@@ -0,0 +1,2 @@
+build_modules(${CMAKE_CURRENT_SOURCE_DIR})
+build_modules_dependencies(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 16d593fab..a32a7606d 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -1,12 +1,20 @@
-/* Bahamut functions
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Please read COPYING and README for further details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -16,7 +24,7 @@ class ChannelModeFlood : public ChannelModeParam
public:
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
- bool IsValid(Anope::string &value) const anope_override
+ bool IsValid(Anope::string &value) const override
{
try
{
@@ -45,91 +53,97 @@ class BahamutIRCdProto : public IRCDProto
MaxModes = 60;
}
- void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) override
{
if (Servers::Capab.count("TSMODE") > 0)
{
- UplinkSocket::Message(source) << "MODE " << dest->name << " " << dest->creation_time << " " << buf;
+ IRCMessage message(source, "MODE", dest->name, dest->creation_time);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
else
+ {
IRCDProto::SendModeInternal(source, dest, buf);
+ }
}
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
+ IRCMessage message(source, "SVSMODE", u->nick, u->timestamp);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
}
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick, time_t time) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t time) override
{
- UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << time << " :Being held for registered user";
+ Uplink::Send(Me, "SVSHOLD", nick, time, "Being held for registered user");
}
/* SVSHOLD - release */
- void SendSVSHoldDel(const Anope::string &nick) anope_override
+ void SendSVSHoldDel(const Anope::string &nick) override
{
- UplinkSocket::Message(Me) << "SVSHOLD " << nick << " 0";
+ Uplink::Send(Me, "SVSHOLD", nick, 0);
}
/* SQLINE */
- void SendSQLine(User *, const XLine *x) anope_override
+ void SendSQLine(User *, XLine *x) override
{
- UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
+ Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason());
}
/* UNSLINE */
- void SendSGLineDel(const XLine *x) anope_override
+ void SendSGLineDel(XLine *x) override
{
- UplinkSocket::Message() << "UNSGLINE 0 :" << x->mask;
+ Uplink::Send("UNSGLINE", 0, x->GetMask());
}
/* UNSZLINE */
- void SendSZLineDel(const XLine *x) anope_override
+ void SendSZLineDel(XLine *x) override
{
/* this will likely fail so its only here for legacy */
- UplinkSocket::Message() << "UNSZLINE 0 " << x->GetHost();
+ Uplink::Send("UNSZLINE", 0, x->GetHost());
/* this is how we are supposed to deal with it */
- UplinkSocket::Message() << "RAKILL " << x->GetHost() << " *";
+ Uplink::Send("RAKILL", x->GetHost(), "*");
}
/* SZLINE */
- void SendSZLine(User *, const XLine *x) anope_override
+ void SendSZLine(User *, XLine *x) override
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
/* this will likely fail so its only here for legacy */
- UplinkSocket::Message() << "SZLINE " << x->GetHost() << " :" << x->GetReason();
+ Uplink::Send("SZLINE", x->GetHost(), x->GetReason());
/* this is how we are supposed to deal with it */
- UplinkSocket::Message() << "AKILL " << x->GetHost() << " * " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason();
+ Uplink::Send("AKILL", x->GetHost(), "*", timeleft, x->GetBy(), Anope::CurTime, x->GetReason());
}
/* SVSNOOP */
- void SendSVSNOOP(const Server *server, bool set) anope_override
+ void SendSVSNOOP(const Server *server, bool set) override
{
- UplinkSocket::Message() << "SVSNOOP " << server->GetName() << " " << (set ? "+" : "-");
+ Uplink::Send("SVSNOOP", server->GetName(), set ? "+" : "-");
}
/* SGLINE */
- void SendSGLine(User *, const XLine *x) anope_override
+ void SendSGLine(User *, XLine *x) override
{
- UplinkSocket::Message() << "SGLINE " << x->mask.length() << " :" << x->mask << ":" << x->GetReason();
+ Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason());
}
/* RAKILL */
- void SendAkillDel(const XLine *x) anope_override
+ void SendAkillDel(XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
return;
@@ -145,25 +159,26 @@ class BahamutIRCdProto : public IRCDProto
}
}
- UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser();
+ Uplink::Send("RAKKILL", x->GetHost(), x->GetUser());
}
/* TOPIC */
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- UplinkSocket::Message(source) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
+ Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
}
/* UNSQLINE */
- void SendSQLineDel(const XLine *x) anope_override
+ void SendSQLineDel(XLine *x) override
{
- UplinkSocket::Message() << "UNSQLINE " << x->mask;
+ Uplink::Send("UNSQLINE", x->GetMask());
}
/* JOIN - SJOIN */
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override
{
- UplinkSocket::Message(user) << "SJOIN " << c->creation_time << " " << c->name;
+ Uplink::Send(user, "SJOIN", c->creation_time, c->name);
+
if (status)
{
/* First save the channel status incase uc->Status == status */
@@ -175,7 +190,7 @@ class BahamutIRCdProto : public IRCDProto
if (uc != NULL)
uc->status.Clear();
- BotInfo *setter = BotInfo::Find(user->GetUID());
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
@@ -184,7 +199,7 @@ class BahamutIRCdProto : public IRCDProto
}
}
- void SendAkill(User *u, XLine *x) anope_override
+ void SendAkill(User *u, XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
{
@@ -192,21 +207,26 @@ class BahamutIRCdProto : public IRCDProto
{
/* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->manager->Check(it->second, x))
+ if (x->GetManager()->Check(it->second, x))
this->SendAkill(it->second, x);
return;
}
- const XLine *old = x;
+ XLine *old = x;
- if (old->manager->HasEntry("*@" + u->host))
+ if (old->GetManager()->HasEntry("*@" + u->host))
return;
/* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- x = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
- old->manager->AddXLine(x);
-
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
+ x = Serialize::New<XLine *>();
+ x->SetMask("*@" + u->host);
+ x->SetBy(old->GetBy());
+ x->SetExpires(old->GetExpires());
+ x->SetReason(old->GetReason());
+ x->SetID(old->GetID());
+ old->GetManager()->AddXLine(x);
+
+ Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask();
}
/* ZLine if we can instead */
@@ -221,46 +241,47 @@ class BahamutIRCdProto : public IRCDProto
}
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
if (timeleft > 172800)
timeleft = 172800;
- UplinkSocket::Message() << "AKILL " << x->GetHost() << " " << x->GetUser() << " " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason();
+
+ Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason());
}
/*
Note: if the stamp is null 0, the below usage is correct of Bahamut
*/
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "SVSKILL " << user->nick << " :" << buf;
+ Uplink::Send(source, "SVSKILL", user->nick, buf);
}
- void SendBOB() anope_override
+ void SendBOB() override
{
- UplinkSocket::Message() << "BURST";
+ Uplink::Send("BURST");
}
- void SendEOB() anope_override
+ void SendEOB() override
{
- UplinkSocket::Message() << "BURST 0";
+ Uplink::Send("BURST", 0);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message() << "NICK " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " " << u->server->GetName() << " 0 0 :" << u->realname;
+ Uplink::Send("NICK", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, u->server->GetName(), 0, 0, u->realname);
}
/* SERVER */
- void SendServer(const Server *server) anope_override
+ void SendServer(const Server *server) override
{
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
+ Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription());
}
- void SendConnect() anope_override
+ void SendConnect() override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " :TS";
- UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3";
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS");
+ Uplink::Send("CAPAB", "SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3");
SendServer(Me);
/*
* SVINFO
@@ -270,24 +291,24 @@ class BahamutIRCdProto : public IRCDProto
* parv[3] = server is standalone or connected to non-TS only
* parv[4] = server's idea of UTC time
*/
- UplinkSocket::Message() << "SVINFO 3 1 0 :" << Anope::CurTime;
+ Uplink::Send("SVINFO", 3, 1, 0, Anope::CurTime);
this->SendBOB();
}
- void SendChannel(Channel *c) anope_override
+ void SendChannel(Channel *c) override
{
Anope::string modes = c->GetModes(true, true);
if (modes.empty())
modes = "+";
- UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " " << modes << " :";
+ Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
}
- void SendLogin(User *u, NickAlias *) anope_override
+ void SendLogin(User *u, NickServ::Nick *) override
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %d", u->signon);
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1");
}
@@ -297,7 +318,7 @@ struct IRCDMessageBurst : IRCDMessage
{
IRCDMessageBurst(Module *creator) : IRCDMessage(creator, "BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
/* If we found a server with the given source, that one just
* finished bursting. If there was no source, then our uplink
@@ -315,7 +336,7 @@ struct IRCDMessageMode : IRCDMessage
{
IRCDMessageMode(Module *creator, const Anope::string &sname) : IRCDMessage(creator, sname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params.size() > 2 && IRCD->IsChannelValid(params[0]))
{
@@ -366,7 +387,7 @@ struct IRCDMessageNick : IRCDMessage
{
IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params.size() == 10)
{
@@ -377,13 +398,13 @@ struct IRCDMessageNick : IRCDMessage
return;
}
- NickAlias *na = NULL;
+ NickServ::Nick *na = NULL;
time_t signon = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0,
stamp = params[7].is_pos_number_only() ? convertTo<time_t>(params[7]) : 0;
- if (signon && signon == stamp)
- na = NickAlias::Find(params[0]);
+ if (signon && signon == stamp && NickServ::service)
+ na = NickServ::service->FindNick(params[0]);
- User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? *na->nc : NULL);
+ User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? na->GetAccount() : NULL);
}
else
source.GetUser()->ChangeNick(params[0]);
@@ -394,7 +415,7 @@ struct IRCDMessageServer : IRCDMessage
{
IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]);
@@ -405,7 +426,7 @@ struct IRCDMessageSJoin : IRCDMessage
{
IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Anope::string modes;
if (params.size() >= 4)
@@ -461,7 +482,7 @@ struct IRCDMessageTopic : IRCDMessage
{
IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Channel *c = Channel::Find(params[0]);
if (c)
@@ -470,6 +491,7 @@ struct IRCDMessageTopic : IRCDMessage
};
class ProtoBahamut : public Module
+ , public EventHook<Event::UserNickChange>
{
BahamutIRCdProto ircd_proto;
@@ -501,60 +523,40 @@ class ProtoBahamut : public Module
IRCDMessageSJoin message_sjoin;
IRCDMessageTopic message_topic;
- void AddModes()
- {
- /* Add user modes */
- ModeManager::AddUserMode(new UserModeOperOnly("SERV_ADMIN", 'A'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserModeOperOnly("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
-
- /* b/e/I */
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
-
- /* v/h/o/a/q */
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1));
-
- /* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- }
-
public:
- ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_capab(this), message_error(this), message_invite(this),
- message_join(this), message_kick(this), message_kill(this), message_motd(this), message_notice(this),
- message_part(this), message_ping(this), message_privmsg(this), message_quit(this),
- message_squit(this), message_stats(this), message_time(this), message_version(this), message_whois(this),
-
- message_burst(this), message_mode(this, "MODE"), message_svsmode(this, "SVSMODE"),
- message_nick(this), message_server(this), message_sjoin(this), message_topic(this)
- {
-
- this->AddModes();
-
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
+ ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::UserNickChange>(this)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_join(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_burst(this)
+ , message_mode(this, "MODE")
+ , message_svsmode(this, "SVSMODE")
+ , message_nick(this)
+ , message_server(this)
+ , message_sjoin(this)
+ , message_topic(this)
+ {
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
IRCD->SendLogout(u);
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index c381ef124..c69fbaf5f 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -1,28 +1,39 @@
-/* Charybdis IRCD functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2006-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+/* Dependencies: anope_protocol.ratbox */
+
#include "module.h"
-#include "modules/cs_mode.h"
#include "modules/sasl.h"
+#include "modules/protocol/hybrid.h"
+#include "modules/protocol/charybdis.h"
+#include "modules/protocol/ratbox.h"
+#include "modules/chanserv/mode.h"
static Anope::string UplinkSID;
-static ServiceReference<IRCDProto> ratbox("IRCDProto", "ratbox");
-
class ChannelModeLargeBan : public ChannelMode
{
public:
ChannelModeLargeBan(const Anope::string &mname, char modeChar) : ChannelMode(mname, modeChar) { }
- bool CanSet(User *u) const anope_override
+ bool CanSet(User *u) const override
{
return u && u->HasMode("OPER");
}
@@ -31,8 +42,10 @@ class ChannelModeLargeBan : public ChannelMode
class CharybdisProto : public IRCDProto
{
+ ServiceReference<IRCDProto> ratbox; // XXX
public:
CharybdisProto(Module *creator) : IRCDProto(creator, "Charybdis 3.4+")
+ , ratbox("ratbox")
{
DefaultPseudoclientModes = "+oiS";
CanCertFP = true;
@@ -46,43 +59,32 @@ class CharybdisProto : public IRCDProto
MaxModes = 4;
}
- void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) anope_override { ratbox->SendSVSKillInternal(source, targ, reason); }
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { ratbox->SendGlobalNotice(bi, dest, msg); }
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { ratbox->SendGlobalPrivmsg(bi, dest, msg); }
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override { ratbox->SendGlobopsInternal(source, buf); }
- void SendSGLine(User *u, const XLine *x) anope_override { ratbox->SendSGLine(u, x); }
- void SendSGLineDel(const XLine *x) anope_override { ratbox->SendSGLineDel(x); }
- void SendAkill(User *u, XLine *x) anope_override { ratbox->SendAkill(u, x); }
- void SendAkillDel(const XLine *x) anope_override { ratbox->SendAkillDel(x); }
- void SendSQLineDel(const XLine *x) anope_override { ratbox->SendSQLineDel(x); }
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { ratbox->SendJoin(user, c, status); }
- void SendServer(const Server *server) anope_override { ratbox->SendServer(server); }
- void SendChannel(Channel *c) anope_override { ratbox->SendChannel(c); }
- void SendTopic(const MessageSource &source, Channel *c) anope_override { ratbox->SendTopic(source, c); }
- bool IsIdentValid(const Anope::string &ident) anope_override { return ratbox->IsIdentValid(ident); }
- void SendLogin(User *u, NickAlias *na) anope_override { ratbox->SendLogin(u, na); }
- void SendLogout(User *u) anope_override { ratbox->SendLogout(u); }
-
- void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) override { ratbox->SendSVSKillInternal(source, targ, reason); }
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { ratbox->SendGlobalNotice(bi, dest, msg); }
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { ratbox->SendGlobalPrivmsg(bi, dest, msg); }
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override { ratbox->SendGlobopsInternal(source, buf); }
+ void SendSGLine(User *u, XLine *x) override { ratbox->SendSGLine(u, x); }
+ void SendSGLineDel(XLine *x) override { ratbox->SendSGLineDel(x); }
+ void SendAkill(User *u, XLine *x) override { ratbox->SendAkill(u, x); }
+ void SendAkillDel(XLine *x) override { ratbox->SendAkillDel(x); }
+ void SendSQLineDel(XLine *x) override { ratbox->SendSQLineDel(x); }
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override { ratbox->SendJoin(user, c, status); }
+ void SendServer(const Server *server) override { ratbox->SendServer(server); }
+ void SendChannel(Channel *c) override { ratbox->SendChannel(c); }
+ void SendTopic(const MessageSource &source, Channel *c) override { ratbox->SendTopic(source, c); }
+ bool IsIdentValid(const Anope::string &ident) override { return ratbox->IsIdentValid(ident); }
+ void SendLogin(User *u, NickServ::Nick *na) override { ratbox->SendLogin(u, na); }
+ void SendLogout(User *u) override { ratbox->SendLogout(u); }
+
+ void SendSQLine(User *, XLine *x) override
{
- Anope::string mechlist;
-
- for (unsigned i = 0; i < mechanisms.size(); ++i)
- {
- mechlist += "," + mechanisms[i];
- }
-
- UplinkSocket::Message(Me) << "ENCAP * MECHLIST :" << (mechanisms.empty() ? "" : mechlist.substr(1));
+ Uplink::Send(Me, "RESV", "*", x->GetMask(), x->GetReason());
}
- void SendSQLine(User *, const XLine *x) anope_override
+ void SendConnect() override
{
- UplinkSocket::Message(Me) << "RESV * " << x->mask << " :" << x->GetReason();
- }
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
- void SendConnect() anope_override
- {
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
/*
* Received: CAPAB :BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN
* KNOCK MLOCK QS RSFNC SAVE SERVICES TB UNKLN
@@ -106,7 +108,7 @@ class CharybdisProto : public IRCDProto
* UNKLN - Can do UNKLINE (encap only)
* QS - Can handle quit storm removal
*/
- UplinkSocket::Message() << "CAPAB :BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN KNOCK MLOCK QS RSFNC SERVICES TB UNKLN";
+ Uplink::Send("CAPAB", "BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN KNOCK MLOCK QS RSFNC SERVICES TB UNKLN");
/* Make myself known to myself in the serverlist */
SendServer(Me);
@@ -118,160 +120,141 @@ class CharybdisProto : public IRCDProto
* arg[2] = '0'
* arg[3] = server's idea of UTC time
*/
- UplinkSocket::Message() << "SVINFO 6 6 0 :" << Anope::CurTime;
+ Uplink::Send("SVINFO", 6, 6, Anope::CurTime);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "EUID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " * * :" << u->realname;
+ Uplink::Send(Me, "EUID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), "*", "*", u->realname);
}
- void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override
+ void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override
{
- UplinkSocket::Message(Me) << "ENCAP " << u->server->GetName() << " RSFNC " << u->GetUID()
- << " " << newnick << " " << when << " " << u->timestamp;
+ Uplink::Send(Me, "ENCAP", u->server->GetName(), "RSFNC", u->GetUID(),
+ newnick, when, u->timestamp);
}
- void SendSVSHold(const Anope::string &nick, time_t delay) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t delay) override
{
- UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << delay << " " << nick;
+ Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", delay, nick);
}
- void SendSVSHoldDel(const Anope::string &nick) anope_override
+ void SendSVSHoldDel(const Anope::string &nick) override
{
- UplinkSocket::Message(Me) << "ENCAP * NICKDELAY 0 " << nick;
+ Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", 0, nick);
}
- void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) anope_override
+ void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override
{
- UplinkSocket::Message(Me) << "ENCAP * CHGHOST " << u->GetUID() << " :" << host;
+ Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host);
}
- void SendVhostDel(User *u) anope_override
+ void SendVhostDel(User *u) override
{
this->SendVhost(u, "", u->host);
}
- void SendSASLMessage(const SASL::Message &message) anope_override
+ void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) override
+ {
+ Anope::string mechlist;
+
+ for (unsigned i = 0; i < mechanisms.size(); ++i)
+ {
+ mechlist += "," + mechanisms[i];
+ }
+
+ Uplink::Send(Me, "ENCAP", "*", "MECHLIST", mechlist.empty() ? "" : mechlist.substr(1));
+ }
+
+ void SendSASLMessage(const SASL::Message &message) override
{
Server *s = Server::Find(message.target.substr(0, 3));
- UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : message.target.substr(0, 3)) << " SASL " << message.source << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : (" " + message.ext));
+ Uplink::Send(Me, "ENCAP", s ? s->GetName() : message.target.substr(0, 3), "SASL", message.source, message.target, message.type, message.data, message.ext.empty() ? "" : message.ext);
}
- void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
+ void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override
{
Server *s = Server::Find(uid.substr(0, 3));
- UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * " << (!vident.empty() ? vident : '*') << " " << (!vhost.empty() ? vhost : '*') << " " << acc;
+ Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc);
}
};
-struct IRCDMessageEncap : IRCDMessage
+void charybdis::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT);}
+ User *u = source.GetUser();
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ // In a burst, states that the source user is logged in as the account.
+ if (params[1] == "LOGIN" || params[1] == "SU")
{
- User *u = source.GetUser();
-
- // In a burst, states that the source user is logged in as the account.
- if (params[1] == "LOGIN" || params[1] == "SU")
- {
- NickCore *nc = NickCore::Find(params[2]);
- if (!nc)
- return;
- u->Login(nc);
- }
- // Received: :42XAAAAAE ENCAP * CERTFP :3f122a9cc7811dbad3566bf2cec3009007c0868f
- if (params[1] == "CERTFP")
- {
- u->fingerprint = params[2];
- FOREACH_MOD(OnFingerprint, (u));
- }
- /*
- * Received: :42X ENCAP * SASL 42XAAAAAH * S PLAIN
- * Received: :42X ENCAP * SASL 42XAAAAAC * D A
- *
- * Part of a SASL authentication exchange. The mode is 'C' to send some data
- * (base64 encoded), or 'S' to end the exchange (data indicates type of
- * termination: 'A' for abort, 'F' for authentication failure, 'S' for
- * authentication success).
- *
- * Charybdis only accepts messages from SASL agents; these must have umode +S
- */
- if (params[1] == "SASL" && SASL::sasl && params.size() >= 6)
- {
- SASL::Message m;
- m.source = params[2];
- m.target = params[3];
- m.type = params[4];
- m.data = params[5];
- m.ext = params.size() > 6 ? params[6] : "";
-
- SASL::sasl->ProcessMessage(m);
- }
+ NickServ::Account *nc = NickServ::FindAccount(params[2]);
+ if (!nc)
+ return;
+ u->Login(nc);
+ }
+ // Received: :42XAAAAAE ENCAP * CERTFP :3f122a9cc7811dbad3566bf2cec3009007c0868f
+ if (params[1] == "CERTFP")
+ {
+ u->fingerprint = params[2];
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
}
-};
-
-struct IRCDMessageEUID : IRCDMessage
-{
- IRCDMessageEUID(Module *creator) : IRCDMessage(creator, "EUID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
/*
- * :42X EUID DukePyrolator 1 1353240577 +Zi ~jens erft-5d80b00b.pool.mediaWays.net 93.128.176.11 42XAAAAAD * * :jens
- * :<SID> EUID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <VHOST> <IP> <UID> <REALHOST> <ACCOUNT> :<GECOS>
- * 0 1 2 3 4 5 6 7 8 9 10
+ * Received: :42X ENCAP * SASL 42XAAAAAH * S PLAIN
+ * Received: :42X ENCAP * SASL 42XAAAAAC * D A
*
- * Introduces a user. The hostname field is now always the visible host.
- * The realhost field is * if the real host is equal to the visible host.
- * The account field is * if the login is not set.
- * Note that even if both new fields are *, an EUID command still carries more
- * information than a UID command (namely that real host is visible host and the
- * user is not logged in with services). Hence a NICK or UID command received
- * from a remote server should not be sent in EUID form to other servers.
+ * Part of a SASL authentication exchange. The mode is 'C' to send some data
+ * (base64 encoded), or 'S' to end the exchange (data indicates type of
+ * termination: 'A' for abort, 'F' for authentication failure, 'S' for
+ * authentication success).
+ *
+ * Charybdis only accepts messages from SASL agents; these must have umode +S
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ if (params[1] == "SASL" && sasl && params.size() >= 6)
{
- NickAlias *na = NULL;
- if (params[9] != "*")
- na = NickAlias::Find(params[9]);
-
- User::OnIntroduce(params[0], params[4], (params[8] != "*" ? params[8] : params[5]), params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? *na->nc : NULL);
+ SASL::Message m;
+ m.source = params[2];
+ m.target = params[3];
+ m.type = params[4];
+ m.data = params[5];
+ m.ext = params.size() > 6 ? params[6] : "";
+
+ sasl->ProcessMessage(m);
}
-};
+}
-// we can't use this function from ratbox because we set a local variable here
-struct IRCDMessageServer : IRCDMessage
+void charybdis::EUID::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ NickServ::Nick *na = NULL;
+ if (params[9] != "*")
+ na = NickServ::FindNick(params[9]);
- // SERVER dev.anope.de 1 :charybdis test server
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- // Servers other then our immediate uplink are introduced via SID
- if (params[1] != "1")
- return;
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
+ User::OnIntroduce(params[0], params[4], (params[8] != "*" ? params[8] : params[5]), params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? na->GetAccount() : NULL);
+}
// we can't use this function from ratbox because we set a local variable here
-struct IRCDMessagePass : IRCDMessage
+// SERVER dev.anope.de 1 :charybdis test server
+void charybdis::Server::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ // Servers other then our immediate uplink are introduced via SID
+ if (params[1] != "1")
+ return;
+ new ::Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
+ IRCD->SendPing(Me->GetName(), params[0]);
+}
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- // UplinkSID is used in IRCDMessageServer
- UplinkSID = params[3];
- }
-};
+// we can't use this function from ratbox because we set a local variable here
+void charybdis::Pass::Run(MessageSource &source, const std::vector<Anope::string> &params)
+{
+ // UplinkSID is used in server handler
+ UplinkSID = params[3];
+}
class ProtoCharybdis : public Module
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::MLockEvents>
{
- Module *m_ratbox;
+ ServiceReference<ModeLocks> mlocks;
CharybdisProto ircd_proto;
@@ -296,125 +279,115 @@ class ProtoCharybdis : public Module
Message::Version message_version;
Message::Whois message_whois;
- /* Ratbox Message Handlers */
- ServiceAlias message_bmask, message_join, message_nick, message_pong, message_sid, message_sjoin,
- message_tb, message_tmode, message_uid;
-
/* Our message handlers */
- IRCDMessageEncap message_encap;
- IRCDMessageEUID message_euid;
- IRCDMessagePass message_pass;
- IRCDMessageServer message_server;
+ hybrid::BMask message_bmask;
+ charybdis::Encap message_encap;
+ charybdis::EUID message_euid;
+ ratbox::Join message_join;
+ hybrid::Nick message_nick;
+ charybdis::Pass message_pass;
+ hybrid::Pong message_pong;
+ charybdis::Server message_server;
+ hybrid::SID message_sid;
+ hybrid::SJoin message_sjoin;
+ ratbox::TB message_tb;
+ hybrid::TMode message_tmode;
+ ratbox::UID message_uid;
bool use_server_side_mlock;
- void AddModes()
- {
- /* Add user modes */
- ModeManager::AddUserMode(new UserMode("NOFORWARD", 'Q'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z'));
- ModeManager::AddUserMode(new UserModeNoone("SSL", 'Z'));
-
- /* b/e/I */
- ModeManager::AddChannelMode(new ChannelModeList("QUIET", 'q'));
-
- /* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'f'));
- ModeManager::AddChannelMode(new ChannelMode("ALLOWFORWARD", 'F'));
- ModeManager::AddChannelMode(new ChannelMode("ALLINVITE", 'g'));
- ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j'));
- ModeManager::AddChannelMode(new ChannelModeLargeBan("LBAN", 'L'));
- ModeManager::AddChannelMode(new ChannelMode("PERM", 'P'));
- ModeManager::AddChannelMode(new ChannelMode("NOFORWARD", 'Q'));
- ModeManager::AddChannelMode(new ChannelMode("OPMODERATED", 'z'));
- }
-
public:
- ProtoCharybdis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this),
- message_kill(this), message_mode(this), message_motd(this), message_notice(this), message_part(this),
- message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), message_stats(this),
- message_time(this), message_topic(this), message_version(this), message_whois(this),
-
- message_bmask("IRCDMessage", "charybdis/bmask", "ratbox/bmask"),
- message_join("IRCDMessage", "charybdis/join", "ratbox/join"),
- message_nick("IRCDMessage", "charybdis/nick", "ratbox/nick"),
- message_pong("IRCDMessage", "charybdis/pong", "ratbox/pong"),
- message_sid("IRCDMessage", "charybdis/sid", "ratbox/sid"),
- message_sjoin("IRCDMessage", "charybdis/sjoin", "ratbox/sjoin"),
- message_tb("IRCDMessage", "charybdis/tb", "ratbox/tb"),
- message_tmode("IRCDMessage", "charybdis/tmode", "ratbox/tmode"),
- message_uid("IRCDMessage", "charybdis/uid", "ratbox/uid"),
-
- message_encap(this), message_euid(this), message_pass(this), message_server(this)
-
- {
-
-
- if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK)
- throw ModuleException("Unable to load ratbox");
- m_ratbox = ModuleManager::FindModule("ratbox");
- if (!m_ratbox)
- throw ModuleException("Unable to find ratbox");
- if (!ratbox)
- throw ModuleException("No protocol interface for ratbox");
-
- this->AddModes();
- }
-
- ~ProtoCharybdis()
+ ProtoCharybdis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::ChannelSync>(this)
+ , EventHook<Event::MLockEvents>(this)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_mode(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_topic(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_bmask(this)
+ , message_encap(this)
+ , message_euid(this)
+ , message_join(this)
+ , message_nick(this)
+ , message_pass(this)
+ , message_pong(this)
+ , message_server(this)
+ , message_sid(this)
+ , message_sjoin(this)
+ , message_tb(this)
+ , message_tmode(this)
+ , message_uid(this)
{
- m_ratbox = ModuleManager::FindModule("ratbox");
- ModuleManager::UnloadModule(m_ratbox, NULL);
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
}
- void OnChannelSync(Channel *c) anope_override
+ void OnChannelSync(Channel *c) override
{
- if (!c->ci)
+ if (!c->ci || !mlocks)
return;
- ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
- if (use_server_side_mlock && modelocks && Servers::Capab.count("MLOCK") > 0)
+ if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(c->ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
+ Uplink::Send(Me, "MLOCK", c->creation_time, c->ci->GetName(), modes);
}
}
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
+ if (!mlocks)
+ return EVENT_CONTINUE;
+
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), modes);
}
return EVENT_CONTINUE;
}
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnUnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
+ if (!mlocks)
+ return EVENT_CONTINUE;
+
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), modes);
}
return EVENT_CONTINUE;
}
};
+template<> void ModuleInfo<ProtoCharybdis>(ModuleDef *def)
+{
+ def->Depends("ratbox");
+}
+
MODULE_INIT(ProtoCharybdis)
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index 2db72717e..c1d85bcf8 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -1,35 +1,51 @@
-/* ircd-hybrid-8 protocol module
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team <team@anope.org>
- * (C) 2012-2016 ircd-hybrid development team
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2012-2016 ircd-hybrid development team
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
+#include "modules/protocol/hybrid.h"
static Anope::string UplinkSID;
class HybridProto : public IRCDProto
{
- BotInfo *FindIntroduced()
+ ServiceBot *FindIntroduced()
{
- BotInfo *bi = Config->GetClient("OperServ");
-
+ ServiceBot *bi = Config->GetClient("OperServ");
if (bi && bi->introduced)
return bi;
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- if (it->second->introduced)
- return it->second;
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+ if (u->type == UserType::BOT)
+ {
+ bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ if (bi->introduced)
+ return bi;
+ }
+ }
return NULL;
}
- void SendSVSKillInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *u, const Anope::string &buf) override
{
IRCDProto::SendSVSKillInternal(source, u, buf);
u->KillInternal(source, buf);
@@ -52,73 +68,72 @@ class HybridProto : public IRCDProto
MaxModes = 6;
}
- void SendInvite(const MessageSource &source, const Channel *c, User *u) anope_override
+ void SendInvite(const MessageSource &source, const Channel *c, User *u) override
{
- UplinkSocket::Message(source) << "INVITE " << u->GetUID() << " " << c->name << " " << c->creation_time;
+ Uplink::Send(source, "INVITE", u->GetUID(), c->name, c->creation_time);
}
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "NOTICE $$" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "NOTICE", "$$" + dest->GetName(), msg);
}
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "PRIVMSG $$" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "PRIVMSG", "$$" + dest->GetName(), msg);
}
- void SendSQLine(User *, const XLine *x) anope_override
+ void SendSQLine(User *, XLine *x) override
{
- UplinkSocket::Message(FindIntroduced()) << "RESV * " << (x->expires ? x->expires - Anope::CurTime : 0) << " " << x->mask << " :" << x->reason;
+ Uplink::Send(FindIntroduced(), "RESV", "*", x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetMask(), x->GetReason());
}
- void SendSGLineDel(const XLine *x) anope_override
+ void SendSGLineDel(XLine *x) override
{
- UplinkSocket::Message(Config->GetClient("OperServ")) << "UNXLINE * " << x->mask;
+ Uplink::Send(Config->GetClient("OperServ"), "UNXLINE", "*", x->GetMask());
}
- void SendSGLine(User *, const XLine *x) anope_override
+ void SendSGLine(User *, XLine *x) override
{
- UplinkSocket::Message(Config->GetClient("OperServ")) << "XLINE * " << x->mask << " " << (x->expires ? x->expires - Anope::CurTime : 0) << " :" << x->GetReason();
+ Uplink::Send(Config->GetClient("OperServ"), "XLINE", "*", x->GetMask(), x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetReason());
}
- void SendSZLineDel(const XLine *x) anope_override
+ void SendSZLineDel(XLine *x) override
{
- UplinkSocket::Message(Config->GetClient("OperServ")) << "UNDLINE * " << x->GetHost();
+ Uplink::Send(Config->GetClient("OperServ"), "UNDLINE", "*", x->GetHost());
}
- void SendSZLine(User *, const XLine *x) anope_override
+ void SendSZLine(User *, XLine *x) override
{
/* Calculate the time left before this would expire, capping it at 2 days */
- time_t timeleft = x->expires - Anope::CurTime;
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- UplinkSocket::Message(Config->GetClient("OperServ")) << "DLINE * " << timeleft << " " << x->GetHost() << " :" << x->GetReason();
+ Uplink::Send(Config->GetClient("OperServ"), "DLINE", "*", timeleft, x->GetHost(), x->GetReason());
}
- void SendAkillDel(const XLine *x) anope_override
+ void SendAkillDel(XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
return;
- UplinkSocket::Message(Config->GetClient("OperServ")) << "UNKLINE * " << x->GetUser() << " " << x->GetHost();
+ Uplink::Send(Config->GetClient("OperServ"), "UNKLINE", "*", x->GetUser(), x->GetHost());
}
- void SendSQLineDel(const XLine *x) anope_override
+ void SendSQLineDel(XLine *x) override
{
- UplinkSocket::Message(Config->GetClient("OperServ")) << "UNRESV * " << x->mask;
+ Uplink::Send(Config->GetClient("OperServ"), "UNRESV", "*", x->GetMask());
}
- void SendJoin(User *u, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *u, Channel *c, const ChannelStatus *status) override
{
/*
* Note that we must send our modes with the SJOIN and can not add them to the
* mode stacker because ircd-hybrid does not allow *any* client to op itself
*/
- UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :"
- << (status != NULL ? status->BuildModePrefixList() : "") << u->GetUID();
+ Uplink::Send("SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), (status != NULL ? status->BuildModePrefixList() : "") + u->GetUID());
/* And update our internal status for this user since this is not going through our mode handling system */
if (status)
@@ -130,7 +145,7 @@ class HybridProto : public IRCDProto
}
}
- void SendAkill(User *u, XLine *x) anope_override
+ void SendAkill(User *u, XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
{
@@ -141,50 +156,55 @@ class HybridProto : public IRCDProto
* Find users that match and ban them.
*/
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->manager->Check(it->second, x))
+ if (x->GetManager()->Check(it->second, x))
this->SendAkill(it->second, x);
return;
}
- const XLine *old = x;
+ XLine *old = x;
- if (old->manager->HasEntry("*@" + u->host))
+ if (old->GetManager()->HasEntry("*@" + u->host))
return;
/* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- XLine *xline = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
-
- old->manager->AddXLine(xline);
- x = xline;
-
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#"
- << u->realname << " matches " << old->mask;
+ XLine *xl = Serialize::New<XLine *>();
+ xl->SetMask("*@" + u->host);
+ xl->SetBy(old->GetBy());
+ xl->SetExpires(old->GetExpires());
+ xl->SetReason(old->GetReason());
+ xl->SetID(old->GetID());
+
+ old->GetManager()->AddXLine(xl);
+ x = xl;
+
+ Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#"
+ << u->realname << " matches " << old->GetMask();
}
/* Calculate the time left before this would expire, capping it at 2 days */
- time_t timeleft = x->expires - Anope::CurTime;
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- UplinkSocket::Message(Config->GetClient("OperServ")) << "KLINE * " << timeleft << " " << x->GetUser() << " " << x->GetHost() << " :" << x->GetReason();
+ Uplink::Send(Config->GetClient("OperServ"), "KLINE", timeleft, x->GetUser(), x->GetHost(), x->GetReason());
}
- void SendServer(const Server *server) anope_override
+ void SendServer(const Server *server) override
{
if (server == Me)
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() + 1 << " :" << server->GetDescription();
+ Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription());
else
- UplinkSocket::Message(Me) << "SID " << server->GetName() << " " << server->GetHops() + 1 << " " << server->GetSID() << " :" << server->GetDescription();
+ Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
}
- void SendConnect() anope_override
+ void SendConnect() override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
/*
- * As of January 13, 2016, ircd-hybrid-8 does support the following capabilities
+ * As of January 13, 2016, ircd-hybrid-8 supports the following capabilities
* which are required to work with IRC-services:
*
* QS - Can handle quit storm removal
@@ -197,97 +217,103 @@ class HybridProto : public IRCDProto
* SVS - Supports services
* EOB - Supports End Of Burst message
*/
- UplinkSocket::Message() << "CAPAB :QS EX CHW IE ENCAP TBURST SVS HOPS EOB";
+ Uplink::Send("CAPAB", "QS EX CHW IE ENCAP TBURST SVS HOPS EOB");
SendServer(Me);
- UplinkSocket::Message() << "SVINFO 6 6 0 :" << Anope::CurTime;
+ Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " "
- << u->GetIdent() << " " << u->host << " 0.0.0.0 " << u->GetUID() << " * :" << u->realname;
+ Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "0.0.0.0", u->GetUID(), "*", u->realname);
}
- void SendEOB() anope_override
+ void SendEOB() override
{
- UplinkSocket::Message(Me) << "EOB";
+ Uplink::Send(Me, "EOB");
}
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "SVSMODE " << u->GetUID() << " " << u->timestamp << " " << buf;
+ IRCMessage message(source, "SVSMODE", u->GetUID(), u->timestamp);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
- void SendLogin(User *u, NickAlias *na) anope_override
+ void SendLogin(User *u, NickServ::Nick *na) override
{
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %s", na->nc->display.c_str());
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %s", na->GetAccount()->GetDisplay().c_str());
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d *");
}
- void SendChannel(Channel *c) anope_override
+ void SendChannel(Channel *c) override
{
Anope::string modes = c->GetModes(true, true);
if (modes.empty())
modes = "+";
- UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " " << modes << " :";
+ Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
}
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- UplinkSocket::Message(source) << "TBURST " << c->creation_time << " " << c->name << " " << c->topic_ts << " " << c->topic_setter << " :" << c->topic;
+ Uplink::Send(source, "TBURST", c->creation_time, c->name, c->topic_ts, c->topic_setter, c->topic);
}
- void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override
+ void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override
{
- UplinkSocket::Message(Me) << "SVSNICK " << u->GetUID() << " " << newnick << " " << when;
+ Uplink::Send(Me, "SVSNICK", u->GetUID(), newnick, when);
}
- void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) anope_override
+ void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override
{
- UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan;
+ Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
}
- void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override
+ void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) override
{
if (!param.empty())
- UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan << " :" << param;
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan, param);
else
- UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan;
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan);
}
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) override
{
+#if 0
XLine x(nick, Me->GetName(), Anope::CurTime + t, "Being held for registered user");
this->SendSQLine(NULL, &x);
+#endif
}
+#warning "xline on stack"
- void SendSVSHoldDel(const Anope::string &nick) anope_override
+ void SendSVSHoldDel(const Anope::string &nick) override
{
+#if 0
XLine x(nick);
this->SendSQLineDel(&x);
+#endif
}
- void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) anope_override
+ void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override
{
u->SetMode(Config->GetClient("HostServ"), "CLOAK", host);
}
- void SendVhostDel(User *u) anope_override
+ void SendVhostDel(User *u) override
{
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK", u->host);
}
- bool IsIdentValid(const Anope::string &ident) anope_override
+ bool IsIdentValid(const Anope::string &ident) override
{
if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
return false;
@@ -311,65 +337,44 @@ class HybridProto : public IRCDProto
}
};
-struct IRCDMessageBMask : IRCDMessage
+/* 0 1 2 3 */
+/* :0MC BMASK 1350157102 #channel b :*!*@*.test.com */
+void hybrid::BMask::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageBMask(Module *creator) : IRCDMessage(creator, "BMASK", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ Channel *c = Channel::Find(params[1]);
+ ChannelMode *mode = ModeManager::FindChannelModeByChar(params[2][0]);
- /* 0 1 2 3 */
- /* :0MC BMASK 1350157102 #channel b :*!*@*.test.com */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ if (c && mode)
{
- Channel *c = Channel::Find(params[1]);
- ChannelMode *mode = ModeManager::FindChannelModeByChar(params[2][0]);
-
- if (c && mode)
- {
- spacesepstream bans(params[3]);
- Anope::string token;
-
- while (bans.GetToken(token))
- c->SetModeInternal(source, mode, token);
- }
+ spacesepstream bans(params[3]);
+ Anope::string token;
+ while (bans.GetToken(token))
+ c->SetModeInternal(source, mode, token);
}
-};
+}
-struct IRCDMessageEOB : IRCDMessage
+void hybrid::EOB::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageEOB(Module *craetor) : IRCDMessage(craetor, "EOB", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetServer()->Sync(true);
- }
-};
+ source.GetServer()->Sync(true);
+}
-struct IRCDMessageJoin : Message::Join
+void hybrid::Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageJoin(Module *creator) : Message::Join(creator, "JOIN") { }
+ if (params.size() < 2)
+ return;
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.size() < 2)
- return;
+ std::vector<Anope::string> p = params;
+ p.erase(p.begin());
- std::vector<Anope::string> p = params;
- p.erase(p.begin());
-
- return Message::Join::Run(source, p);
- }
-};
+ return Message::Join::Run(source, p);
+}
-struct IRCDMessageNick : IRCDMessage
+/* 0 1 */
+/* :0MCAAAAAB NICK newnick 1350157102 */
+void hybrid::Nick::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- /* 0 1 */
- /* :0MCAAAAAB NICK newnick 1350157102 */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->ChangeNick(params[0], convertTo<time_t>(params[1]));
- }
-};
+ source.GetUser()->ChangeNick(params[0], convertTo<time_t>(params[1]));
+}
struct IRCDMessagePass : IRCDMessage
{
@@ -377,207 +382,158 @@ struct IRCDMessagePass : IRCDMessage
/* 0 1 2 3 */
/* PASS password TS 6 0MC */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
UplinkSID = params[3];
}
};
-struct IRCDMessagePong : IRCDMessage
+void hybrid::Pong::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessagePong(Module *creator) : IRCDMessage(creator, "PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ source.GetServer()->Sync(false);
+}
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetServer()->Sync(false);
- }
-};
-
-struct IRCDMessageServer : IRCDMessage
+/* 0 1 2 */
+/* SERVER hades.arpa 1 :ircd-hybrid test server */
+void hybrid::Server::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ /* Servers other than our immediate uplink are introduced via SID */
+ if (params[1] != "1")
+ return;
- /* 0 1 2 */
- /* SERVER hades.arpa 1 :ircd-hybrid test server */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* Servers other than our immediate uplink are introduced via SID */
- if (params[1] != "1")
- return;
+ new ::Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
+ IRCD->SendPing(Me->GetName(), params[0]);
+}
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
-
-struct IRCDMessageSID : IRCDMessage
+void hybrid::SID::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageSID(Module *creator) : IRCDMessage(creator, "SID", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- /* 0 1 2 3 */
- /* :0MC SID hades.arpa 2 4XY :ircd-hybrid test server */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]);
+ unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
+ new ::Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]);
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
+ IRCD->SendPing(Me->GetName(), params[0]);
+}
-struct IRCDMessageSJoin : IRCDMessage
+void hybrid::SJoin::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string modes;
-
- if (params.size() >= 3)
- for (unsigned i = 2; i < params.size() - 1; ++i)
- modes += " " + params[i];
+ Anope::string modes;
+ if (params.size() >= 3)
+ for (unsigned i = 2; i < params.size() - 1; ++i)
+ modes += " " + params[i];
+ if (!modes.empty())
+ modes.erase(modes.begin());
- if (!modes.empty())
- modes.erase(modes.begin());
+ std::list<Message::Join::SJoinUser> users;
- std::list<Message::Join::SJoinUser> users;
+ spacesepstream sep(params[params.size() - 1]);
+ Anope::string buf;
- spacesepstream sep(params[params.size() - 1]);
- Anope::string buf;
+ while (sep.GetToken(buf))
+ {
+ Message::Join::SJoinUser sju;
- while (sep.GetToken(buf))
+ /* Get prefixes from the nick */
+ for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
{
- Message::Join::SJoinUser sju;
-
- /* Get prefixes from the nick */
- for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
- {
- buf.erase(buf.begin());
- sju.first.AddMode(ch);
- }
-
- sju.second = User::Find(buf);
- if (!sju.second)
- {
- Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
- continue;
- }
+ buf.erase(buf.begin());
+ sju.first.AddMode(ch);
+ }
- users.push_back(sju);
+ sju.second = User::Find(buf);
+ if (!sju.second)
+ {
+ Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
+ continue;
}
- time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
- Message::Join::SJoin(source, params[1], ts, modes, users);
+ users.push_back(sju);
}
-};
-struct IRCDMessageSVSMode : IRCDMessage
-{
- IRCDMessageSVSMode(Module *creator) : IRCDMessage(creator, "SVSMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+ time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
+ Message::Join::SJoin(source, params[1], ts, modes, users);
+}
- /*
- * parv[0] = nickname
- * parv[1] = TS
- * parv[2] = mode
- * parv[3] = optional argument (services id)
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = User::Find(params[0]);
-
- if (!u)
- return;
+/*
+ * parv[0] = nickname
+ * parv[1] = TS
+ * parv[2] = mode
+ * parv[3] = optional argument (services id)
+ */
+void hybrid::SVSMode::Run(MessageSource &source, const std::vector<Anope::string> &params)
+{
+ User *u = User::Find(params[0]);
+ if (!u)
+ return;
- if (!params[1].is_pos_number_only() || convertTo<time_t>(params[1]) != u->timestamp)
- return;
+ if (!params[1].is_pos_number_only() || convertTo<time_t>(params[1]) != u->timestamp)
+ return;
- u->SetModesInternal(source, "%s", params[2].c_str());
- }
-};
+ u->SetModesInternal(source, "%s", params[2].c_str());
+}
-struct IRCDMessageTBurst : IRCDMessage
+void hybrid::TBurst::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageTBurst(Module *creator) : IRCDMessage(creator, "TBURST", 5) { }
+ Anope::string setter;
+ sepstream(params[3], '!').GetToken(setter, 0);
+ time_t topic_time = Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime;
+ Channel *c = Channel::Find(params[1]);
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string setter;
- sepstream(params[3], '!').GetToken(setter, 0);
- time_t topic_time = Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime;
- Channel *c = Channel::Find(params[1]);
+ if (c)
+ c->ChangeTopicInternal(NULL, setter, params[4], topic_time);
+}
- if (c)
- c->ChangeTopicInternal(NULL, setter, params[4], topic_time);
- }
-};
-
-struct IRCDMessageTMode : IRCDMessage
+void hybrid::TMode::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageTMode(Module *creator) : IRCDMessage(creator, "TMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+ time_t ts = 0;
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ try
{
- time_t ts = 0;
-
- try
- {
- ts = convertTo<time_t>(params[0]);
- }
- catch (const ConvertException &) { }
+ ts = convertTo<time_t>(params[0]);
+ }
+ catch (const ConvertException &) { }
- Channel *c = Channel::Find(params[1]);
- Anope::string modes = params[2];
+ Channel *c = Channel::Find(params[1]);
+ Anope::string modes = params[2];
- for (unsigned i = 3; i < params.size(); ++i)
- modes += " " + params[i];
+ for (unsigned i = 3; i < params.size(); ++i)
+ modes += " " + params[i];
- if (c)
- c->SetModesInternal(source, modes, ts);
- }
-};
+ if (c)
+ c->SetModesInternal(source, modes, ts);
+}
-struct IRCDMessageUID : IRCDMessage
+/* 0 1 2 3 4 5 6 7 8 9 */
+/* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB Steve :Mining all the time */
+void hybrid::UID::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- /* 0 1 2 3 4 5 6 7 8 9 */
- /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB Steve :Mining all the time */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string ip = params[6];
+ Anope::string ip = params[6];
- if (ip == "0") /* Can be 0 for spoofed clients */
- ip.clear();
+ if (ip == "0") /* Can be 0 for spoofed clients */
+ ip.clear();
- NickAlias *na = NULL;
- if (params[8] != "0" && params[8] != "*")
- na = NickAlias::Find(params[8]);
+ NickServ::Nick *na = NULL;
+ if (params[8] != "0" && params[8] != "*")
+ na = NickServ::FindNick(params[8]);
- /* Source is always the server */
- User::OnIntroduce(params[0], params[4], params[5], "",
- ip, source.GetServer(),
- params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0,
- params[3], params[7], na ? *na->nc : NULL);
- }
-};
+ /* Source is always the server */
+ User::OnIntroduce(params[0], params[4], params[5], "",
+ ip, source.GetServer(),
+ params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0,
+ params[3], params[7], na ? na->GetAccount() : NULL);
+}
-struct IRCDMessageCertFP: IRCDMessage
+/* 0 */
+/* :0MCAAAAAB CERTFP 4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */
+void hybrid::CertFP::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageCertFP(Module *creator) : IRCDMessage(creator, "CERTFP", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+ User *u = source.GetUser();
- /* 0 */
- /* :0MCAAAAAB CERTFP 4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- u->fingerprint = params[0];
- FOREACH_MOD(OnFingerprint, (u));
- }
-};
+ u->fingerprint = params[0];
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
+}
class ProtoHybrid : public Module
+ , public EventHook<Event::UserNickChange>
{
HybridProto ircd_proto;
@@ -603,90 +559,62 @@ class ProtoHybrid : public Module
Message::Whois message_whois;
/* Our message handlers */
- IRCDMessageBMask message_bmask;
- IRCDMessageEOB message_eob;
- IRCDMessageJoin message_join;
- IRCDMessageNick message_nick;
+ hybrid::CertFP message_certfp;
+ hybrid::BMask message_bmask;
+ hybrid::EOB message_eob;
+ hybrid::Join message_join;
+ hybrid::Nick message_nick;
IRCDMessagePass message_pass;
- IRCDMessagePong message_pong;
- IRCDMessageServer message_server;
- IRCDMessageSID message_sid;
- IRCDMessageSJoin message_sjoin;
- IRCDMessageSVSMode message_svsmode;
- IRCDMessageTBurst message_tburst;
- IRCDMessageTMode message_tmode;
- IRCDMessageUID message_uid;
- IRCDMessageCertFP message_certfp;
-
- void AddModes()
- {
- /* Add user modes */
- ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a'));
- ModeManager::AddUserMode(new UserModeOperOnly("CALLERID", 'g'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserMode("HIDECHANS", 'p'));
- ModeManager::AddUserMode(new UserMode("HIDEIDLE", 'q'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
- ModeManager::AddUserMode(new UserMode("DEAF", 'D'));
- ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G'));
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeNoone("SSL", 'S'));
- ModeManager::AddUserMode(new UserModeNoone("WEBIRC", 'W'));
-
- /* b/e/I */
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
-
- /* v/h/o */
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
-
- /* l/k */
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
-
- /* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'S'));
- ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T'));
- }
+ hybrid::Pong message_pong;
+ hybrid::Server message_server;
+ hybrid::SID message_sid;
+ hybrid::SJoin message_sjoin;
+ hybrid::SVSMode message_svsmode;
+ hybrid::TBurst message_tburst;
+ hybrid::TMode message_tmode;
+ hybrid::UID message_uid;
public:
- ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this),
- message_kill(this), message_mode(this), message_motd(this), message_notice(this), message_part(this),
- message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), message_stats(this),
- message_time(this), message_topic(this), message_version(this), message_whois(this),
- message_bmask(this), message_eob(this), message_join(this),
- message_nick(this), message_pass(this), message_pong(this), message_server(this), message_sid(this),
- message_sjoin(this), message_svsmode(this), message_tburst(this), message_tmode(this), message_uid(this),
- message_certfp(this)
- {
- if (Config->GetModule(this))
- this->AddModes();
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
+ ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::UserNickChange>(this)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_mode(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_topic(this)
+ , message_version(this)
+ , message_whois(this)
+ , message_bmask(this)
+ , message_eob(this)
+ , message_join(this)
+ , message_nick(this)
+ , message_pass(this)
+ , message_pong(this)
+ , message_server(this)
+ , message_sid(this)
+ , message_sjoin(this)
+ , message_svsmode(this)
+ , message_tburst(this)
+ , message_tmode(this)
+ , message_uid(this)
+ , message_certfp(this)
+ {
+ }
+
+ void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
}
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
deleted file mode 100644
index b8d846d5f..000000000
--- a/modules/protocol/inspircd12.cpp
+++ /dev/null
@@ -1,1383 +0,0 @@
-/* inspircd 1.2 functions
- *
- * (C) 2003-2016 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/sasl.h"
-
-struct SASLUser
-{
- Anope::string uid;
- Anope::string acc;
- time_t created;
-};
-
-static std::list<SASLUser> saslusers;
-
-static Anope::string rsquit_server, rsquit_id;
-
-class ChannelModeFlood : public ChannelModeParam
-{
- public:
- ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- try
- {
- Anope::string rest;
- if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
- return true;
- }
- catch (const ConvertException &) { }
-
- return false;
- }
-};
-
-class InspIRCd12Proto : public IRCDProto
-{
- private:
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
- {
- IRCDProto::SendSVSKillInternal(source, user, buf);
- user->KillInternal(source, buf);
- }
-
- void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent)
- {
- if (!Servers::Capab.count("CHGIDENT"))
- Log() << "CHGIDENT not loaded!";
- else
- UplinkSocket::Message(Me) << "CHGIDENT " << nick << " " << vIdent;
- }
-
- void SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost)
- {
- if (!Servers::Capab.count("CHGHOST"))
- Log() << "CHGHOST not loaded!";
- else
- UplinkSocket::Message(Me) << "CHGHOST " << nick << " " << vhost;
- }
-
- void SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason)
- {
- UplinkSocket::Message(Me) << "ADDLINE " << xtype << " " << mask << " " << addedby << " " << Anope::CurTime << " " << duration << " :" << reason;
- }
-
- void SendDelLine(const Anope::string &xtype, const Anope::string &mask)
- {
- UplinkSocket::Message(Me) << "DELLINE " << xtype << " " << mask;
- }
-
- public:
- InspIRCd12Proto(Module *creator) : IRCDProto(creator, "InspIRCd 1.2")
- {
- DefaultPseudoclientModes = "+I";
- CanSVSNick = true;
- CanSVSJoin = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- CanSQLine = true;
- CanSZLine = true;
- CanSVSHold = true;
- CanCertFP = true;
- RequiresID = true;
- MaxModes = 20;
- }
-
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
- {
- UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
- }
-
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
- {
- UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
- }
-
- void SendAkillDel(const XLine *x) anope_override
- {
- /* InspIRCd may support regex bans */
- if (x->IsRegex() && Servers::Capab.count("RLINE"))
- {
- Anope::string mask = x->mask;
- size_t h = x->mask.find('#');
- if (h != Anope::string::npos)
- mask = mask.replace(h, 1, ' ');
- SendDelLine("R", mask);
- return;
- }
- else if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr addr(x->GetHost());
- if (addr.valid())
- {
- IRCD->SendSZLineDel(x);
- return;
- }
- }
-
- SendDelLine("G", x->GetUser() + "@" + x->GetHost());
- }
-
- void SendTopic(const MessageSource &source, Channel *c) anope_override
- {
- if (Servers::Capab.count("SVSTOPIC"))
- {
- UplinkSocket::Message(c->ci->WhoSends()) << "SVSTOPIC " << c->name << " " << c->topic_ts << " " << c->topic_setter << " :" << c->topic;
- }
- else
- {
- /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */
- time_t ts = c->topic_ts;
- if (c->topic_time > ts)
- ts = Anope::CurTime;
- /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */
- UplinkSocket::Message(source) << "FTOPIC " << c->name << " " << ts << " " << c->topic_setter << " :" << c->topic;
- }
- }
-
- void SendVhostDel(User *u) anope_override
- {
- if (u->HasMode("CLOAK"))
- this->SendChgHostInternal(u->nick, u->chost);
- else
- this->SendChgHostInternal(u->nick, u->host);
-
- if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent())
- this->SendChgIdentInternal(u->nick, u->GetIdent());
- }
-
- void SendAkill(User *u, XLine *x) anope_override
- {
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
- timeleft = 172800;
-
- /* InspIRCd may support regex bans, if they do we can send this and forget about it */
- if (x->IsRegex() && Servers::Capab.count("RLINE"))
- {
- Anope::string mask = x->mask;
- size_t h = x->mask.find('#');
- if (h != Anope::string::npos)
- mask = mask.replace(h, 1, ' ');
- SendAddLine("R", mask, timeleft, x->by, x->GetReason());
- return;
- }
- else if (x->IsRegex() || x->HasNickOrReal())
- {
- if (!u)
- {
- /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->manager->Check(it->second, x))
- this->SendAkill(it->second, x);
- return;
- }
-
- const XLine *old = x;
-
- if (old->manager->HasEntry("*@" + u->host))
- return;
-
- /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- x = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
- old->manager->AddXLine(x);
-
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
- }
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr addr(x->GetHost());
- if (addr.valid())
- {
- IRCD->SendSZLine(u, x);
- return;
- }
- }
-
- SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->by, x->GetReason());
- }
-
- void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) anope_override
- {
- User *u = User::Find(dest);
- UplinkSocket::Message() << "PUSH " << dest << " ::" << Me->GetName() << " " << numeric << " " << (u ? u->nick : dest) << " " << buf;
- }
-
- void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override
- {
- UplinkSocket::Message(source) << "FMODE " << dest->name << " " << dest->creation_time << " " << buf;
- }
-
- void SendClientIntroduction(User *u) anope_override
- {
- Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "UID " << u->GetUID() << " " << u->timestamp << " " << u->nick << " " << u->host << " " << u->host << " " << u->GetIdent() << " 0.0.0.0 " << u->timestamp << " " << modes << " :" << u->realname;
- if (modes.find('o') != Anope::string::npos)
- UplinkSocket::Message(u) << "OPERTYPE :services";
- }
-
- /* SERVER services-dev.chatspike.net password 0 :Description here */
- void SendServer(const Server *server) anope_override
- {
- /* if rsquit is set then we are waiting on a squit */
- if (rsquit_id.empty() && rsquit_server.empty())
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink].password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription();
- }
-
- void SendSquit(Server *s, const Anope::string &message) anope_override
- {
- if (s != Me)
- {
- rsquit_id = s->GetSID();
- rsquit_server = s->GetName();
- UplinkSocket::Message() << "RSQUIT " << s->GetName() << " :" << message;
- }
- else
- UplinkSocket::Message() << "SQUIT " << s->GetName() << " :" << message;
- }
-
- /* JOIN */
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
- {
- UplinkSocket::Message(Me) << "FJOIN " << c->name << " " << c->creation_time << " +" << c->GetModes(true, true) << " :," << user->GetUID();
- /* Note that we can send this with the FJOIN but choose not to
- * because the mode stacker will handle this and probably will
- * merge these modes with +nrt and other mlocked modes
- */
- if (status)
- {
- /* First save the channel status incase uc->Status == status */
- ChannelStatus cs = *status;
- /* If the user is internally on the channel with flags, kill them so that
- * the stacker will allow this.
- */
- ChanUserContainer *uc = c->FindUser(user);
- if (uc != NULL)
- uc->status.Clear();
-
- BotInfo *setter = BotInfo::Find(user->GetUID());
- for (size_t i = 0; i < cs.Modes().length(); ++i)
- c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
-
- if (uc != NULL)
- uc->status = cs;
- }
- }
-
- /* UNSQLINE */
- void SendSQLineDel(const XLine *x) anope_override
- {
- SendDelLine("Q", x->mask);
- }
-
- /* SQLINE */
- void SendSQLine(User *, const XLine *x) anope_override
- {
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
- timeleft = 172800;
- SendAddLine("Q", x->mask, timeleft, x->by, x->GetReason());
- }
-
- void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) anope_override
- {
- if (!vIdent.empty())
- this->SendChgIdentInternal(u->nick, vIdent);
- if (!vhost.empty())
- this->SendChgHostInternal(u->nick, vhost);
- }
-
- void SendConnect() anope_override
- {
- SendServer(Me);
- }
-
- /* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override
- {
- UplinkSocket::Message(Config->GetClient("NickServ")) << "SVSHOLD " << nick << " " << t << " :Being held for registered user";
- }
-
- /* SVSHOLD - release */
- void SendSVSHoldDel(const Anope::string &nick) anope_override
- {
- UplinkSocket::Message(Config->GetClient("NickServ")) << "SVSHOLD " << nick;
- }
-
- /* UNSZLINE */
- void SendSZLineDel(const XLine *x) anope_override
- {
- SendDelLine("Z", x->GetHost());
- }
-
- /* SZLINE */
- void SendSZLine(User *, const XLine *x) anope_override
- {
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
- timeleft = 172800;
- SendAddLine("Z", x->GetHost(), timeleft, x->by, x->GetReason());
- }
-
- void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) anope_override
- {
- UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan;
- }
-
- void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override
- {
- if (!param.empty())
- UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan << " :" << param;
- else
- UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan;
- }
-
- void SendSWhois(const MessageSource &, const Anope::string &who, const Anope::string &mask) anope_override
- {
- User *u = User::Find(who);
-
- UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " swhois :" << mask;
- }
-
- void SendBOB() anope_override
- {
- UplinkSocket::Message(Me) << "BURST " << Anope::CurTime;
- Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Me->GetName() << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString();
- }
-
- void SendEOB() anope_override
- {
- UplinkSocket::Message(Me) << "ENDBURST";
- }
-
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
- {
- if (Servers::Capab.count("GLOBOPS"))
- UplinkSocket::Message(source) << "SNONOTICE g :" << buf;
- else
- UplinkSocket::Message(source) << "SNONOTICE A :" << buf;
- }
-
- void SendLogin(User *u, NickAlias *na) anope_override
- {
- /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */
- if (na->nc->HasExt("UNCONFIRMED"))
- return;
-
- UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << na->nc->display;
- }
-
- void SendLogout(User *u) anope_override
- {
- UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :";
- }
-
- void SendChannel(Channel *c) anope_override
- {
- UplinkSocket::Message(Me) << "FJOIN " << c->name << " " << c->creation_time << " +" << c->GetModes(true, true) << " :";
- }
-
- void SendOper(User *u) anope_override
- {
- }
-
- void SendSASLMessage(const SASL::Message &message) anope_override
- {
- UplinkSocket::Message(Me) << "ENCAP " << message.target.substr(0, 3) << " SASL " << message.source << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : (" " + message.ext));
- }
-
- void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
- {
- UplinkSocket::Message(Me) << "METADATA " << uid << " accountname :" << acc;
-
- SASLUser su;
- su.uid = uid;
- su.acc = acc;
- su.created = Anope::CurTime;
-
- for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
- {
- SASLUser &u = *it;
-
- if (u.created + 30 < Anope::CurTime || u.uid == uid)
- it = saslusers.erase(it);
- else
- ++it;
- }
-
- saslusers.push_back(su);
- }
-
- bool IsExtbanValid(const Anope::string &mask) anope_override
- {
- return mask.length() >= 3 && mask[1] == ':';
- }
-
- bool IsIdentValid(const Anope::string &ident) anope_override
- {
- if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
- return false;
-
- for (unsigned i = 0; i < ident.length(); ++i)
- {
- const char &c = ident[i];
-
- if (c >= 'A' && c <= '}')
- continue;
-
- if ((c >= '0' && c <= '9') || c == '-' || c == '.')
- continue;
-
- return false;
- }
-
- return true;
- }
-};
-
-class InspIRCdExtBan : public ChannelModeList
-{
- public:
- InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
-
- if (mask.find("m:") == 0 || mask.find("N:") == 0)
- {
- Anope::string real_mask = mask.substr(2);
-
- Entry en(this->name, real_mask);
- if (en.Matches(u))
- return true;
- }
- else if (mask.find("j:") == 0)
- {
- Anope::string real_mask = mask.substr(2);
-
- Channel *c = Channel::Find(real_mask);
- if (c != NULL && c->FindUser(u) != NULL)
- return true;
- }
- else if (mask.find("M:") == 0 || mask.find("R:") == 0)
- {
- Anope::string real_mask = mask.substr(2);
-
- if (u->IsIdentified() && real_mask.equals_ci(u->Account()->display))
- return true;
- }
- else if (mask.find("r:") == 0)
- {
- Anope::string real_mask = mask.substr(2);
-
- if (Anope::Match(u->realname, real_mask))
- return true;
- }
- else if (mask.find("s:") == 0)
- {
- Anope::string real_mask = mask.substr(2);
-
- if (Anope::Match(u->server->GetName(), real_mask))
- return true;
- }
-
- return false;
- }
-};
-
-struct IRCDMessageCapab : Message::Capab
-{
- IRCDMessageCapab(Module *creator) : Message::Capab(creator, "CAPAB") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params[0].equals_cs("START"))
- {
- /* reset CAPAB */
- Servers::Capab.clear();
- Servers::Capab.insert("NOQUIT");
- IRCD->CanSVSHold = false;
- }
- else if (params[0].equals_cs("MODULES") && params.size() > 1)
- {
- if (params[1].find("m_globops.so") != Anope::string::npos)
- Servers::Capab.insert("GLOBOPS");
- if (params[1].find("m_services_account.so") != Anope::string::npos)
- Servers::Capab.insert("SERVICES");
- if (params[1].find("m_svshold.so") != Anope::string::npos)
- IRCD->CanSVSHold = true;
- if (params[1].find("m_chghost.so") != Anope::string::npos)
- Servers::Capab.insert("CHGHOST");
- if (params[1].find("m_chgident.so") != Anope::string::npos)
- Servers::Capab.insert("CHGIDENT");
- if (params[1].find("m_hidechans.so") != Anope::string::npos)
- Servers::Capab.insert("HIDECHANS");
- if (params[1].find("m_servprotect.so") != Anope::string::npos)
- IRCD->DefaultPseudoclientModes = "+Ik";
- if (params[1].find("m_rline.so") != Anope::string::npos)
- Servers::Capab.insert("RLINE");
- }
- else if (params[0].equals_cs("CAPABILITIES") && params.size() > 1)
- {
- spacesepstream ssep(params[1]);
- Anope::string capab;
- while (ssep.GetToken(capab))
- {
- if (capab.find("CHANMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'b':
- ModeManager::AddChannelMode(new InspIRCdExtBan("BAN", 'b'));
- continue;
- case 'e':
- ModeManager::AddChannelMode(new InspIRCdExtBan("EXCEPT", 'e'));
- continue;
- case 'I':
- ModeManager::AddChannelMode(new InspIRCdExtBan("INVITEOVERRIDE", 'I'));
- continue;
- /* InspIRCd sends q and a here if they have no prefixes */
- case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '@', 4));
- continue;
- case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT" , 'a', '@', 3));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'k':
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'F':
- ModeManager::AddChannelMode(new ChannelModeParam("NICKFLOOD", 'F', true));
- continue;
- case 'J':
- ModeManager::AddChannelMode(new ChannelModeParam("NOREJOIN", 'J', true));
- continue;
- case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L', true));
- continue;
- case 'f':
- ModeManager::AddChannelMode(new ChannelModeFlood('f', true));
- continue;
- case 'j':
- ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true));
- continue;
- case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t], true));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'A':
- ModeManager::AddChannelMode(new ChannelMode("ALLINVITE", 'A'));
- continue;
- case 'B':
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCAPS", 'B'));
- continue;
- case 'C':
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- continue;
- case 'D':
- ModeManager::AddChannelMode(new ChannelMode("DELAYEDJOIN", 'D'));
- continue;
- case 'G':
- ModeManager::AddChannelMode(new ChannelMode("CENSOR", 'G'));
- continue;
- case 'K':
- ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K'));
- continue;
- case 'M':
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- continue;
- case 'N':
- ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N'));
- continue;
- case 'O':
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- continue;
- case 'P':
- ModeManager::AddChannelMode(new ChannelMode("PERM", 'P'));
- continue;
- case 'Q':
- ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q'));
- continue;
- case 'R':
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- continue;
- case 'S':
- ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S'));
- continue;
- case 'T':
- ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T'));
- continue;
- case 'c':
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- continue;
- case 'i':
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- continue;
- case 'm':
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- continue;
- case 'n':
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- continue;
- case 'p':
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- continue;
- case 'r':
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- continue;
- case 's':
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- continue;
- case 't':
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- continue;
- case 'u':
- ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u'));
- continue;
- case 'z':
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'z'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelMode("", modebuf[t]));
- }
- }
- }
- else if (capab.find("USERMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- while (sep.GetToken(modebuf))
- {
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'h':
- ModeManager::AddUserMode(new UserModeOperOnly("HELPOP", 'h'));
- continue;
- case 'B':
- ModeManager::AddUserMode(new UserMode("BOT", 'B'));
- continue;
- case 'G':
- ModeManager::AddUserMode(new UserMode("CENSOR", 'G'));
- continue;
- case 'H':
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H'));
- continue;
- case 'I':
- ModeManager::AddUserMode(new UserMode("PRIV", 'I'));
- continue;
- case 'Q':
- ModeManager::AddUserMode(new UserModeOperOnly("HIDDEN", 'Q'));
- continue;
- case 'R':
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- continue;
- case 'S':
- ModeManager::AddUserMode(new UserMode("STRIPCOLOR", 'S'));
- continue;
- case 'W':
- ModeManager::AddUserMode(new UserMode("WHOIS", 'W'));
- continue;
- case 'c':
- ModeManager::AddUserMode(new UserMode("COMMONCHANS", 'c'));
- continue;
- case 'g':
- ModeManager::AddUserMode(new UserMode("CALLERID", 'g'));
- continue;
- case 'i':
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- continue;
- case 'k':
- ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'k'));
- continue;
- case 'o':
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- continue;
- case 'r':
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- continue;
- case 'w':
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- continue;
- case 'x':
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
- continue;
- case 'd':
- ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
- continue;
- default:
- ModeManager::AddUserMode(new UserMode("", modebuf[t]));
- }
- }
- }
- }
- else if (capab.find("PREFIX=(") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')'));
- Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end());
- unsigned short level = modes.length() - 1;
-
- for (size_t t = 0, end = modes.length(); t < end; ++t)
- {
- switch (modes[t])
- {
- case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', chars[t], level--));
- continue;
- case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', chars[t], level--));
- continue;
- case 'o':
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', chars[t], level--));
- continue;
- case 'h':
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', chars[t], level--));
- continue;
- case 'v':
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', chars[t], level--));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeStatus("", modes[t], chars[t], level--));
- }
- }
-
- ModeManager::RebuildStatusModes();
- }
- else if (capab.find("MAXMODES=") != Anope::string::npos)
- {
- Anope::string maxmodes(capab.begin() + 9, capab.end());
- IRCD->MaxModes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3;
- }
- }
- }
- else if (params[0].equals_cs("END"))
- {
- if (!Servers::Capab.count("GLOBOPS"))
- {
- UplinkSocket::Message() << "ERROR :m_globops is not loaded. This is required by Anope";
- Anope::QuitReason = "Remote server does not have the m_globops module loaded, and this is required.";
- Anope::Quitting = true;
- return;
- }
- if (!Servers::Capab.count("SERVICES"))
- {
- UplinkSocket::Message() << "ERROR :m_services_account.so is not loaded. This is required by Anope";
- Anope::QuitReason = "ERROR: Remote server does not have the m_services_account module loaded, and this is required.";
- Anope::Quitting = true;
- return;
- }
- if (!Servers::Capab.count("HIDECHANS"))
- {
- UplinkSocket::Message() << "ERROR :m_hidechans.so is not loaded. This is required by Anope";
- Anope::QuitReason = "ERROR: Remote server does not have the m_hidechans module loaded, and this is required.";
- Anope::Quitting = true;
- return;
- }
- if (!IRCD->CanSVSHold)
- Log() << "SVSHOLD missing, Usage disabled until module is loaded.";
- if (!Servers::Capab.count("CHGHOST"))
- Log() << "CHGHOST missing, Usage disabled until module is loaded.";
- if (!Servers::Capab.count("CHGIDENT"))
- Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
- }
-
- Message::Capab::Run(source, params);
- }
-};
-
-struct IRCDMessageChgIdent : IRCDMessage
-{
- IRCDMessageChgIdent(Module *creator) : IRCDMessage(creator, "CHGIDENT", 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = User::Find(params[0]);
- if (u)
- u->SetIdent(params[1]);
- }
-};
-
-struct IRCDMessageChgName : IRCDMessage
-{
- IRCDMessageChgName(Module *creator, const Anope::string &n) : IRCDMessage(creator, n, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->SetRealname(params[0]);
- }
-};
-
-struct IRCDMessageEncap : IRCDMessage
-{
- IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::Match(Me->GetSID(), params[0]) == false)
- return;
-
- if (SASL::sasl && params[1] == "SASL" && params.size() >= 6)
- {
- SASL::Message m;
- m.source = params[2];
- m.target = params[3];
- m.type = params[4];
- m.data = params[5];
- m.ext = params.size() > 6 ? params[6] : "";
-
- SASL::sasl->ProcessMessage(m);
- }
- }
-};
-
-struct IRCDMessageEndburst : IRCDMessage
-{
- IRCDMessageEndburst(Module *creator) : IRCDMessage(creator, "ENDBURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Server *s = source.GetServer();
-
- Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName();
-
- s->Sync(true);
- }
-};
-
-struct IRCDMessageFHost : IRCDMessage
-{
- IRCDMessageFHost(Module *creator, const Anope::string &n) : IRCDMessage(creator, n, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->SetDisplayedHost(params[0]);
- }
-};
-
-struct IRCDMessageFJoin : IRCDMessage
-{
- IRCDMessageFJoin(Module *creator) : IRCDMessage(creator, "FJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string modes;
- if (params.size() >= 3)
- {
- for (unsigned i = 2; i < params.size() - 1; ++i)
- modes += " " + params[i];
- if (!modes.empty())
- modes.erase(modes.begin());
- }
-
- std::list<Message::Join::SJoinUser> users;
-
- spacesepstream sep(params[params.size() - 1]);
- Anope::string buf;
- while (sep.GetToken(buf))
- {
- Message::Join::SJoinUser sju;
-
- /* Loop through prefixes and find modes for them */
- for (char c; (c = buf[0]) != ',' && c;)
- {
- buf.erase(buf.begin());
- sju.first.AddMode(c);
- }
- /* Erase the , */
- if (!buf.empty())
- buf.erase(buf.begin());
-
- sju.second = User::Find(buf);
- if (!sju.second)
- {
- Log(LOG_DEBUG) << "FJOIN for non-existent user " << buf << " on " << params[0];
- continue;
- }
-
- users.push_back(sju);
- }
-
- time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
- Message::Join::SJoin(source, params[0], ts, modes, users);
- }
-};
-
-struct IRCDMessageFMode : IRCDMessage
-{
- IRCDMessageFMode(Module *creator) : IRCDMessage(creator, "FMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* :source FMODE #test 12345678 +nto foo */
-
- Anope::string modes = params[2];
- for (unsigned n = 3; n < params.size(); ++n)
- modes += " " + params[n];
-
- Channel *c = Channel::Find(params[0]);
- time_t ts;
-
- try
- {
- ts = convertTo<time_t>(params[1]);
- }
- catch (const ConvertException &)
- {
- ts = 0;
- }
-
- if (c)
- c->SetModesInternal(source, modes, ts);
- }
-};
-
-struct IRCDMessageFTopic : IRCDMessage
-{
- IRCDMessageFTopic(Module *creator) : IRCDMessage(creator, "FTOPIC", 4) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* :source FTOPIC channel topicts setby :topic */
-
- Channel *c = Channel::Find(params[0]);
- if (c)
- c->ChangeTopicInternal(NULL, params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
- }
-};
-
-struct IRCDMessageIdle : IRCDMessage
-{
- IRCDMessageIdle(Module *creator) : IRCDMessage(creator, "IDLE", 1) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- BotInfo *bi = BotInfo::Find(params[0]);
- if (bi)
- UplinkSocket::Message(bi) << "IDLE " << source.GetSource() << " " << Anope::StartTime << " " << (Anope::CurTime - bi->lastmsg);
- else
- {
- User *u = User::Find(params[0]);
- if (u && u->server == Me)
- UplinkSocket::Message(u) << "IDLE " << source.GetSource() << " " << Anope::StartTime << " 0";
- }
- }
-};
-
-/*
- * source = numeric of the sending server
- * params[0] = uuid
- * params[1] = metadata name
- * params[2] = data
- */
-struct IRCDMessageMetadata : IRCDMessage
-{
- IRCDMessageMetadata(Module *creator) : IRCDMessage(creator, "METADATA", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (isdigit(params[0][0]))
- {
- if (params[1].equals_cs("accountname"))
- {
- User *u = User::Find(params[0]);
- NickCore *nc = NickCore::Find(params[2]);
- if (u && nc)
- u->Login(nc);
- }
-
- /*
- * possible incoming ssl_cert messages:
- * Received: :409 METADATA 409AAAAAA ssl_cert :vTrSe c38070ce96e41cc144ed6590a68d45a6 <...> <...>
- * Received: :409 METADATA 409AAAAAC ssl_cert :vTrSE Could not get peer certificate: error:00000000:lib(0):func(0):reason(0)
- */
- else if (params[1].equals_cs("ssl_cert"))
- {
- User *u = User::Find(params[0]);
- if (!u)
- return;
- u->Extend<bool>("ssl");
- Anope::string data = params[2].c_str();
- size_t pos1 = data.find(' ') + 1;
- size_t pos2 = data.find(' ', pos1);
- if ((pos2 - pos1) >= 32) // inspircd supports md5 and sha1 fingerprint hashes -> size 32 or 40 bytes.
- {
- u->fingerprint = data.substr(pos1, pos2 - pos1);
- }
- FOREACH_MOD(OnFingerprint, (u));
- }
- }
- else if (params[0][0] == '#')
- {
- }
- else if (params[0] == "*")
- {
- // Wed Oct 3 15:40:27 2012: S[14] O :20D METADATA * modules :-m_svstopic.so
-
- if (params[1].equals_cs("modules") && !params[2].empty())
- {
- // only interested when it comes from our uplink
- Server* server = source.GetServer();
- if (!server || server->GetUplink() != Me)
- return;
-
- bool plus = (params[2][0] == '+');
- if (!plus && params[2][0] != '-')
- return;
-
- bool required = false;
- Anope::string capab, module = params[2].substr(1);
-
- if (module.equals_cs("m_services_account.so"))
- required = true;
- else if (module.equals_cs("m_hidechans.so"))
- required = true;
- else if (module.equals_cs("m_chghost.so"))
- capab = "CHGHOST";
- else if (module.equals_cs("m_chgident.so"))
- capab = "CHGIDENT";
- else if (module.equals_cs("m_svshold.so"))
- capab = "SVSHOLD";
- else if (module.equals_cs("m_rline.so"))
- capab = "RLINE";
- else if (module.equals_cs("m_topiclock.so"))
- capab = "TOPICLOCK";
- else
- return;
-
- if (required)
- {
- if (!plus)
- Log() << "Warning: InspIRCd unloaded module " << module << ", Anope won't function correctly without it";
- }
- else
- {
- if (plus)
- Servers::Capab.insert(capab);
- else
- Servers::Capab.erase(capab);
-
- Log() << "InspIRCd " << (plus ? "loaded" : "unloaded") << " module " << module << ", adjusted functionality";
- }
-
- }
- }
- }
-};
-
-struct IRCDMessageMode : IRCDMessage
-{
- IRCDMessageMode(Module *creator) : IRCDMessage(creator, "MODE", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (IRCD->IsChannelValid(params[0]))
- {
- Channel *c = Channel::Find(params[0]);
-
- Anope::string modes = params[1];
- for (unsigned n = 2; n < params.size(); ++n)
- modes += " " + params[n];
-
- if (c)
- c->SetModesInternal(source, modes);
- }
- else
- {
- /* InspIRCd lets opers change another
- users modes, we have to kludge this
- as it slightly breaks RFC1459
- */
- User *u = source.GetUser();
- // This can happen with server-origin modes.
- if (!u)
- u = User::Find(params[0]);
- // if it's still null, drop it like fire.
- // most likely situation was that server introduced a nick which we subsequently akilled
- if (u)
- u->SetModesInternal(source, "%s", params[1].c_str());
- }
- }
-};
-
-struct IRCDMessageNick : IRCDMessage
-{
- IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->ChangeNick(params[0]);
- }
-};
-
-struct IRCDMessageOperType : IRCDMessage
-{
- IRCDMessageOperType(Module *creator) : IRCDMessage(creator, "OPERTYPE", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* opertype is equivalent to mode +o because servers
- don't do this directly */
- User *u = source.GetUser();
- if (!u->HasMode("OPER"))
- u->SetModesInternal(source, "+o");
- }
-};
-
-struct IRCDMessageRSQuit : IRCDMessage
-{
- IRCDMessageRSQuit(Module *creator) : IRCDMessage(creator, "RSQUIT", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Server *s = Server::Find(params[0]);
- const Anope::string &reason = params.size() > 1 ? params[1] : "";
- if (!s)
- return;
-
- UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << reason;
- s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
- }
-};
-
-struct IRCDMessageSetIdent : IRCDMessage
-{
- IRCDMessageSetIdent(Module *creator) : IRCDMessage(creator, "SETIDENT", 0) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->SetIdent(params[0]);
- }
-};
-
-struct IRCDMessageServer : IRCDMessage
-{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 5) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- /*
- * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central!
- * 0: name
- * 1: pass
- * 2: hops
- * 3: numeric
- * 4: desc
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned int hops = Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0;
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[4], params[3]);
- }
-};
-
-struct IRCDMessageSQuit : Message::SQuit
-{
- IRCDMessageSQuit(Module *creator) : Message::SQuit(creator) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params[0] == rsquit_id || params[0] == rsquit_server)
- {
- /* squit for a recently squit server, introduce the juped server now */
- Server *s = Server::Find(rsquit_server);
-
- rsquit_id.clear();
- rsquit_server.clear();
-
- if (s && s->IsJuped())
- IRCD->SendServer(s);
- }
- else
- Message::SQuit::Run(source, params);
- }
-};
-
-struct IRCDMessageTime : IRCDMessage
-{
- IRCDMessageTime(Module *creator) : IRCDMessage(creator, "TIME", 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- UplinkSocket::Message(Me) << "TIME " << source.GetSource() << " " << params[1] << " " << Anope::CurTime;
- }
-};
-
-struct IRCDMessageUID : IRCDMessage
-{
- IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- /*
- * [Nov 03 22:09:58.176252 2009] debug: Received: :964 UID 964AAAAAC 1225746297 w00t2 localhost testnet.user w00t 127.0.0.1 1225746302 +iosw +ACGJKLNOQcdfgjklnoqtx :Robin Burchell <w00t@inspircd.org>
- * 0: uid
- * 1: ts
- * 2: nick
- * 3: host
- * 4: dhost
- * 5: ident
- * 6: ip
- * 7: signon
- * 8+: modes and params -- IMPORTANT, some modes (e.g. +s) may have parameters. So don't assume a fixed position of realname!
- * last: realname
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- time_t ts = convertTo<time_t>(params[1]);
-
- Anope::string modes = params[8];
- for (unsigned i = 9; i < params.size() - 1; ++i)
- modes += " " + params[i];
-
- NickAlias *na = NULL;
- if (SASL::sasl)
- for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
- {
- SASLUser &u = *it;
-
- if (u.created + 30 < Anope::CurTime)
- it = saslusers.erase(it);
- else if (u.uid == params[0])
- {
- na = NickAlias::Find(u.acc);
- it = saslusers.erase(it);
- }
- else
- ++it;
- }
-
- User *u = User::OnIntroduce(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? *na->nc : NULL);
- if (u)
- u->signon = convertTo<time_t>(params[7]);
- }
-};
-
-class ProtoInspIRCd12 : public Module
-{
- InspIRCd12Proto ircd_proto;
- ExtensibleItem<bool> ssl;
-
- /* Core message handlers */
- Message::Away message_away;
- Message::Error message_error;
- Message::Invite message_invite;
- Message::Join message_join;
- Message::Kick message_kick;
- Message::Kill message_kill;
- Message::MOTD message_motd;
- Message::Notice message_notice;
- Message::Part message_part;
- Message::Ping message_ping;
- Message::Privmsg message_privmsg;
- Message::Quit message_quit;
- Message::Stats message_stats;
- Message::Topic message_topic;
-
- /* Our message handlers */
- IRCDMessageChgIdent message_chgident;
- IRCDMessageChgName message_setname, message_chgname;
- IRCDMessageCapab message_capab;
- IRCDMessageEncap message_encap;
- IRCDMessageEndburst message_endburst;
- IRCDMessageFHost message_fhost, message_sethost;
- IRCDMessageFJoin message_fjoin;
- IRCDMessageFMode message_fmode;
- IRCDMessageFTopic message_ftopic;
- IRCDMessageIdle message_idle;
- IRCDMessageMetadata message_metadata;
- IRCDMessageMode message_mode;
- IRCDMessageNick message_nick;
- IRCDMessageOperType message_opertype;
- IRCDMessageRSQuit message_rsquit;
- IRCDMessageSetIdent message_setident;
- IRCDMessageServer message_server;
- IRCDMessageSQuit message_squit;
- IRCDMessageTime message_time;
- IRCDMessageUID message_uid;
-
- public:
- ProtoInspIRCd12(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this), ssl(this, "ssl"),
- message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), message_kill(this),
- message_motd(this), message_notice(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this),
- message_stats(this), message_topic(this),
-
- message_chgident(this), message_setname(this, "SETNAME"), message_chgname(this, "FNAME"), message_capab(this), message_encap(this),
- message_endburst(this),
- message_fhost(this, "FHOST"), message_sethost(this, "SETHOST"), message_fjoin(this), message_fmode(this), message_ftopic(this),
- message_idle(this), message_metadata(this), message_mode(this), message_nick(this), message_opertype(this), message_rsquit(this),
- message_setident(this), message_server(this), message_squit(this), message_time(this), message_uid(this)
- {
- Servers::Capab.insert("NOQUIT");
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
- {
- /* InspIRCd 1.2 doesn't set -r on nick change, remove -r here. Note that if we have to set +r later
- * this will cancel out this -r, resulting in no mode changes.
- *
- * Do not set -r if we don't have a NickServ loaded - DP
- */
- BotInfo *NickServ = Config->GetClient("NickServ");
- if (NickServ)
- u->RemoveMode(NickServ, "REGISTERED");
- }
-};
-
-MODULE_INIT(ProtoInspIRCd12)
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 859bc667f..f8bf9b30e 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -1,23 +1,73 @@
-/* Inspircd 2.0 functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
-#include "modules/cs_mode.h"
+#include "modules/sasl.h"
+#include "modules/chanserv/mode.h"
+#include "modules/chanserv/set.h"
-static unsigned int spanningtree_proto_ver = 0;
+struct SASLUser
+{
+ Anope::string uid;
+ Anope::string acc;
+ time_t created;
+};
-static ServiceReference<IRCDProto> insp12("IRCDProto", "inspircd12");
+static std::list<SASLUser> saslusers;
+static Anope::string rsquit_server, rsquit_id;
+static unsigned int spanningtree_proto_ver = 0;
class InspIRCd20Proto : public IRCDProto
{
+ private:
+ void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) override
+ {
+ IRCDProto::SendSVSKillInternal(source, user, buf);
+ user->KillInternal(source, buf);
+ }
+
+ void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent)
+ {
+ if (!Servers::Capab.count("CHGIDENT"))
+ Log() << "CHGIDENT not loaded!";
+ else
+ Uplink::Send(Me, "CHGIDENT", nick, vIdent);
+ }
+
+ void SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost)
+ {
+ if (!Servers::Capab.count("CHGHOST"))
+ Log() << "CHGHOST not loaded!";
+ else
+ Uplink::Send(Me, "CHGHOST", nick, vhost);
+ }
+
+ void SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason)
+ {
+ Uplink::Send(Me, "ADDLINE", xtype, mask, addedby, Anope::CurTime, duration, reason);
+ }
+
+ void SendDelLine(const Anope::string &xtype, const Anope::string &mask)
+ {
+ Uplink::Send(Me, "DELLINE", xtype, mask);
+ }
+
public:
InspIRCd20Proto(Module *creator) : IRCDProto(creator, "InspIRCd 2.0")
{
@@ -34,70 +84,390 @@ class InspIRCd20Proto : public IRCDProto
MaxModes = 20;
}
- void SendConnect() anope_override
+ void SendConnect() override
+ {
+ Uplink::Send("CAPAB START 1202");
+ Uplink::Send("CAPAB CAPABILITIES :PROTOCOL=1202");
+ Uplink::Send("CAPAB END");
+ SendServer(Me);
+ }
+
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
+ {
+ Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
+ }
+
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message() << "CAPAB START 1202";
- UplinkSocket::Message() << "CAPAB CAPABILITIES :PROTOCOL=1202";
- UplinkSocket::Message() << "CAPAB END";
- insp12->SendConnect();
+ Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
}
- void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) anope_override
+ void SendAkillDel(XLine *x) override
+ {
+ /* InspIRCd may support regex bans */
+ if (x->IsRegex() && Servers::Capab.count("RLINE"))
+ {
+ Anope::string mask = x->GetMask();
+ size_t h = mask.find('#');
+ if (h != Anope::string::npos)
+ mask = mask.replace(h, 1, ' ');
+ SendDelLine("R", mask);
+ return;
+ }
+ else if (x->IsRegex() || x->HasNickOrReal())
+ return;
+
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
+ {
+ cidr addr(x->GetHost());
+ if (addr.valid())
+ {
+ IRCD->SendSZLineDel(x);
+ return;
+ }
+ }
+
+ SendDelLine("G", x->GetUser() + "@" + x->GetHost());
+ }
+
+ void SendTopic(const MessageSource &source, Channel *c) override
+ {
+ if (Servers::Capab.count("SVSTOPIC"))
+ {
+ Uplink::Send(c->ci->WhoSends(), "SVSTOPIC", c->name, c->topic_ts, c->topic_setter, c->topic);
+ }
+ else
+ {
+ /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */
+ time_t ts = c->topic_ts;
+ if (c->topic_time > ts)
+ ts = Anope::CurTime;
+ /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */
+ Uplink::Send(source, "FTOPIC", c->name, ts, c->topic_setter, c->topic);
+ }
+ }
+
+ void SendVhostDel(User *u) override
+ {
+ if (u->HasMode("CLOAK"))
+ this->SendChgHostInternal(u->nick, u->chost);
+ else
+ this->SendChgHostInternal(u->nick, u->host);
+
+ if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent())
+ this->SendChgIdentInternal(u->nick, u->GetIdent());
+ }
+
+ void SendAkill(User *u, XLine *x) override
+ {
+ // Calculate the time left before this would expire, capping it at 2 days
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+
+ /* InspIRCd may support regex bans, if they do we can send this and forget about it */
+ if (x->IsRegex() && Servers::Capab.count("RLINE"))
+ {
+ Anope::string mask = x->GetMask();
+ size_t h = mask.find('#');
+ if (h != Anope::string::npos)
+ mask = mask.replace(h, 1, ' ');
+ SendAddLine("R", mask, timeleft, x->GetBy(), x->GetReason());
+ return;
+ }
+ else if (x->IsRegex() || x->HasNickOrReal())
+ {
+ if (!u)
+ {
+ /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (x->GetManager()->Check(it->second, x))
+ this->SendAkill(it->second, x);
+ return;
+ }
+
+ XLine *old = x;
+
+ if (old->GetManager()->HasEntry("*@" + u->host))
+ return;
+
+ /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
+ x = Serialize::New<XLine *>();
+ x->SetMask("*@" + u->host);
+ x->SetBy(old->GetBy());
+ x->SetExpires(old->GetExpires());
+ x->SetReason(old->GetReason());
+ old->GetManager()->AddXLine(x);
+
+ Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask();
+ }
+
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
+ {
+ cidr addr(x->GetHost());
+ if (addr.valid())
+ {
+ IRCD->SendSZLine(u, x);
+ return;
+ }
+ }
+
+ SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->GetBy(), x->GetReason());
+ }
+
+ void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) override
+ {
+ User *u = User::Find(dest);
+ Uplink::Send("PUSH", dest, ":" + Me->GetName() + " " + numeric + " " + (u ? u->nick : dest) + " " + buf);
+ }
+
+ void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) override
+ {
+ IRCMessage message(source, "FMODE", dest->name, dest->creation_time);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
+ }
+
+ void SendClientIntroduction(User *u) override
+ {
+ Anope::string modes = "+" + u->GetModes();
+ Uplink::Send(Me, "UID", u->GetUID(), u->timestamp, u->nick, u->host, u->host, u->GetIdent(), "0.0.0.0", u->timestamp, modes, u->realname);
+ if (modes.find('o') != Anope::string::npos)
+ Uplink::Send(u, "OPERTYPE", "services");
+ }
+
+ /* SERVER services-dev.chatspike.net password 0 :Description here */
+ void SendServer(const Server *server) override
+ {
+ /* if rsquit is set then we are waiting on a squit */
+ if (rsquit_id.empty() && rsquit_server.empty())
+ Uplink::Send("SERVER", server->GetName(), Config->Uplinks[Anope::CurrentUplink].password, server->GetHops(), server->GetSID(), server->GetDescription());
+ }
+
+ void SendSquit(Server *s, const Anope::string &message) override
+ {
+ if (s != Me)
+ {
+ rsquit_id = s->GetSID();
+ rsquit_server = s->GetName();
+
+ Uplink::Send("RSQUIT", s->GetName(), message);
+ }
+ else
+ {
+ Uplink::Send("SQUIT", s->GetName(), message);
+ }
+ }
+
+ /* JOIN */
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override
+ {
+ Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "," + user->GetUID());
+
+ /* Note that we can send this with the FJOIN but choose not to
+ * because the mode stacker will handle this and probably will
+ * merge these modes with +nrt and other mlocked modes
+ */
+ if (status)
+ {
+ /* First save the channel status incase uc->Status == status */
+ ChannelStatus cs = *status;
+ /* If the user is internally on the channel with flags, kill them so that
+ * the stacker will allow this.
+ */
+ ChanUserContainer *uc = c->FindUser(user);
+ if (uc != NULL)
+ uc->status.Clear();
+
+ ServiceBot *setter = ServiceBot::Find(user->nick);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
+ }
+ }
+
+ /* UNSQLINE */
+ void SendSQLineDel(XLine *x) override
+ {
+ SendDelLine("Q", x->GetMask());
+ }
+
+ /* SQLINE */
+ void SendSQLine(User *, XLine *x) override
+ {
+ // Calculate the time left before this would expire, capping it at 2 days
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+ SendAddLine("Q", x->GetMask(), timeleft, x->GetBy(), x->GetReason());
+ }
+
+ void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override
+ {
+ if (!vIdent.empty())
+ this->SendChgIdentInternal(u->nick, vIdent);
+ if (!vhost.empty())
+ this->SendChgHostInternal(u->nick, vhost);
+ }
+
+ /* SVSHOLD - set */
+ void SendSVSHold(const Anope::string &nick, time_t t) override
+ {
+ Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick, t, "Being held for registered user");
+ }
+
+ /* SVSHOLD - release */
+ void SendSVSHoldDel(const Anope::string &nick) override
+ {
+ Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick);
+ }
+
+ /* UNSZLINE */
+ void SendSZLineDel(XLine *x) override
+ {
+ SendDelLine("Z", x->GetHost());
+ }
+
+ /* SZLINE */
+ void SendSZLine(User *, XLine *x) override
+ {
+ // Calculate the time left before this would expire, capping it at 2 days
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+ SendAddLine("Z", x->GetHost(), timeleft, x->GetBy(), x->GetReason());
+ }
+
+ void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override
+ {
+ Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
+ }
+
+ void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) override
+ {
+ if (!param.empty())
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan, param);
+ else
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan);
+ }
+
+ void SendSWhois(const MessageSource &, const Anope::string &who, const Anope::string &mask) override
+ {
+ User *u = User::Find(who);
+
+ Uplink::Send(Me, "METADATA", u->GetUID(), "swhois", mask);
+ }
+
+ void SendBOB() override
+ {
+ Uplink::Send(Me, "BURST", Anope::CurTime);
+ Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
+ Uplink::Send(Me, "VERSION", "Anope-" + Anope::Version() + " " + Me->GetName() + " :" + IRCD->GetProtocolName() + " - (" + (enc ? enc->name : "none") + ") -- " + Anope::VersionBuildString());
+ }
+
+ void SendEOB() override
+ {
+ Uplink::Send(Me, "ENDBURST");
+ }
+
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override
+ {
+ if (Servers::Capab.count("GLOBOPS"))
+ Uplink::Send(source, "SNONOTICE", "g", buf);
+ else
+ Uplink::Send(source, "SNONOTICE", "A", buf);
+ }
+
+ void SendLogin(User *u, NickServ::Nick *na) override
+ {
+ /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */
+ if (na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ return;
+
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
+ }
+
+ void SendLogout(User *u) override
+ {
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
+ }
+
+ void SendChannel(Channel *c) override
+ {
+ Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "");
+ }
+
+ void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) override
{
Anope::string mechlist;
for (unsigned i = 0; i < mechanisms.size(); ++i)
mechlist += "," + mechanisms[i];
- UplinkSocket::Message(Me) << "METADATA * saslmechlist :" << (mechanisms.empty() ? "" : mechlist.substr(1));
- }
-
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override { insp12->SendSVSKillInternal(source, user, buf); }
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { insp12->SendGlobalNotice(bi, dest, msg); }
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { insp12->SendGlobalPrivmsg(bi, dest, msg); }
- void SendAkillDel(const XLine *x) anope_override { insp12->SendAkillDel(x); }
- void SendTopic(const MessageSource &whosets, Channel *c) anope_override { insp12->SendTopic(whosets, c); };
- void SendVhostDel(User *u) anope_override { insp12->SendVhostDel(u); }
- void SendAkill(User *u, XLine *x) anope_override { insp12->SendAkill(u, x); }
- void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) anope_override { insp12->SendNumericInternal(numeric, dest, buf); }
- void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override { insp12->SendModeInternal(source, dest, buf); }
- void SendClientIntroduction(User *u) anope_override { insp12->SendClientIntroduction(u); }
- void SendServer(const Server *server) anope_override { insp12->SendServer(server); }
- void SendSquit(Server *s, const Anope::string &message) anope_override { insp12->SendSquit(s, message); }
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { insp12->SendJoin(user, c, status); }
- void SendSQLineDel(const XLine *x) anope_override { insp12->SendSQLineDel(x); }
- void SendSQLine(User *u, const XLine *x) anope_override { insp12->SendSQLine(u, x); }
- void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendVhost(u, vident, vhost); }
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override { insp12->SendSVSHold(nick, t); }
- void SendSVSHoldDel(const Anope::string &nick) anope_override { insp12->SendSVSHoldDel(nick); }
- void SendSZLineDel(const XLine *x) anope_override { insp12->SendSZLineDel(x); }
- void SendSZLine(User *u, const XLine *x) anope_override { insp12->SendSZLine(u, x); }
- void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &other) anope_override { insp12->SendSVSJoin(source, u, chan, other); }
- void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override { insp12->SendSVSPart(source, u, chan, param); }
- void SendSWhois(const MessageSource &bi, const Anope::string &who, const Anope::string &mask) anope_override { insp12->SendSWhois(bi, who, mask); }
- void SendBOB() anope_override { insp12->SendBOB(); }
- void SendEOB() anope_override { insp12->SendEOB(); }
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) { insp12->SendGlobopsInternal(source, buf); }
- void SendLogin(User *u, NickAlias *na) anope_override { insp12->SendLogin(u, na); }
- void SendLogout(User *u) anope_override { insp12->SendLogout(u); }
- void SendChannel(Channel *c) anope_override { insp12->SendChannel(c); }
- void SendSASLMessage(const SASL::Message &message) anope_override { insp12->SendSASLMessage(message); }
- void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendSVSLogin(uid, acc, vident, vhost); }
- bool IsExtbanValid(const Anope::string &mask) anope_override { return insp12->IsExtbanValid(mask); }
- bool IsIdentValid(const Anope::string &ident) anope_override { return insp12->IsIdentValid(ident); }
-};
+ Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1));
+ }
-class InspIRCdAutoOpMode : public ChannelModeList
-{
- public:
- InspIRCdAutoOpMode(char mode) : ChannelModeList("AUTOOP", mode)
+ void SendSASLMessage(const SASL::Message &message) override
{
+ if (!message.ext.empty())
+ Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
+ message.source, message.target,
+ message.type, message.data, message.ext);
+ else
+ Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
+ message.source, message.target,
+ message.type, message.data);
}
- bool IsValid(Anope::string &mask) const anope_override
+ void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override
{
- // We can not validate this because we don't know about the
- // privileges of the setter so just reject attempts to set it.
- return false;
+ Uplink::Send(Me, "METADATA", uid, "accountname", acc);
+
+ SASLUser su;
+ su.uid = uid;
+ su.acc = acc;
+ su.created = Anope::CurTime;
+
+ for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
+ {
+ SASLUser &u = *it;
+
+ if (u.created + 30 < Anope::CurTime || u.uid == uid)
+ it = saslusers.erase(it);
+ else
+ ++it;
+ }
+
+ saslusers.push_back(su);
+ }
+
+ bool IsExtbanValid(const Anope::string &mask) override
+ {
+ return mask.length() >= 3 && mask[1] == ':';
+ }
+
+ bool IsIdentValid(const Anope::string &ident) override
+ {
+ if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
+ return false;
+
+ for (unsigned i = 0; i < ident.length(); ++i)
+ {
+ const char &c = ident[i];
+
+ if (c >= 'A' && c <= '}')
+ continue;
+
+ if ((c >= '0' && c <= '9') || c == '-' || c == '.')
+ continue;
+
+ return false;
+ }
+
+ return true;
}
};
@@ -111,13 +481,13 @@ class InspIRCdExtBan : public ChannelModeVirtual<ChannelModeList>
{
}
- ChannelMode *Wrap(Anope::string &param) anope_override
+ ChannelMode *Wrap(Anope::string &param) override
{
param = Anope::string(ext) + ":" + param;
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
}
- ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_override
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) override
{
if (cm->type != MODE_LIST || param.length() < 3 || param[0] != ext || param[1] != ':')
return cm;
@@ -136,7 +506,7 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
@@ -152,7 +522,7 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
@@ -188,12 +558,12 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
- return u->IsIdentified() && real_mask.equals_ci(u->Account()->display);
+ return u->IsIdentified() && real_mask.equals_ci(u->Account()->GetDisplay());
}
};
@@ -204,7 +574,7 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
@@ -219,7 +589,7 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
@@ -227,14 +597,14 @@ namespace InspIRCdExtban
}
};
- class FinerprintMatcher : public InspIRCdExtBan
+ class FingerprintMatcher : public InspIRCdExtBan
{
public:
- FinerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c)
+ FingerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c)
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
@@ -249,7 +619,7 @@ namespace InspIRCdExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
@@ -258,124 +628,11 @@ namespace InspIRCdExtban
};
}
-class ColonDelimitedParamMode : public ChannelModeParam
-{
- public:
- ColonDelimitedParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- return IsValid(value, false);
- }
-
- bool IsValid(const Anope::string &value, bool historymode) const
- {
- if (value.empty())
- return false; // empty param is never valid
-
- Anope::string::size_type pos = value.find(':');
- if ((pos == Anope::string::npos) || (pos == 0))
- return false; // no ':' or it's the first char, both are invalid
-
- Anope::string rest;
- try
- {
- if (convertTo<int>(value, rest, false) <= 0)
- return false; // negative numbers and zero are invalid
-
- rest = rest.substr(1);
- int n;
- if (historymode)
- {
- // For the history mode, the part after the ':' is a duration and it
- // can be in the user friendly "1d3h20m" format, make sure we accept that
- n = Anope::DoTime(rest);
- }
- else
- n = convertTo<int>(rest);
-
- if (n <= 0)
- return false;
- }
- catch (const ConvertException &e)
- {
- // conversion error, invalid
- return false;
- }
-
- return true;
- }
-};
-
-class SimpleNumberParamMode : public ChannelModeParam
-{
- public:
- SimpleNumberParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- if (value.empty())
- return false; // empty param is never valid
-
- try
- {
- if (convertTo<int>(value) <= 0)
- return false;
- }
- catch (const ConvertException &e)
- {
- // conversion error, invalid
- return false;
- }
-
- return true;
- }
-};
-
-class ChannelModeFlood : public ColonDelimitedParamMode
-{
- public:
- ChannelModeFlood(char modeChar) : ColonDelimitedParamMode("FLOOD", modeChar) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- // The parameter of this mode is a bit different, it may begin with a '*',
- // ignore it if that's the case
- Anope::string v = value[0] == '*' ? value.substr(1) : value;
- return ((!value.empty()) && (ColonDelimitedParamMode::IsValid(v)));
- }
-};
-
-class ChannelModeHistory : public ColonDelimitedParamMode
-{
- public:
- ChannelModeHistory(char modeChar) : ColonDelimitedParamMode("HISTORY", modeChar) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- return (ColonDelimitedParamMode::IsValid(value, true));
- }
-};
-
-class ChannelModeRedirect : public ChannelModeParam
-{
- public:
- ChannelModeRedirect(char modeChar) : ChannelModeParam("REDIRECT", modeChar, true) { }
-
- bool IsValid(Anope::string &value) const anope_override
- {
- // The parameter of this mode is a channel, and channel names start with '#'
- return ((!value.empty()) && (value[0] == '#'));
- }
-};
-
struct IRCDMessageCapab : Message::Capab
{
- std::map<char, Anope::string> chmodes, umodes;
-
IRCDMessageCapab(Module *creator) : Message::Capab(creator, "CAPAB") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params[0].equals_cs("START"))
{
@@ -384,15 +641,13 @@ struct IRCDMessageCapab : Message::Capab
if (spanningtree_proto_ver < 1202)
{
- UplinkSocket::Message() << "ERROR :Protocol mismatch, no or invalid protocol version given in CAPAB START";
+ Uplink::Send("ERROR", "Protocol mismatch, no or invalid protocol version given in CAPAB START");
Anope::QuitReason = "Protocol mismatch, no or invalid protocol version given in CAPAB START";
Anope::Quitting = true;
return;
}
/* reset CAPAB */
- chmodes.clear();
- umodes.clear();
Servers::Capab.insert("SERVERS");
Servers::Capab.insert("CHGHOST");
Servers::Capab.insert("CHGIDENT");
@@ -406,132 +661,35 @@ struct IRCDMessageCapab : Message::Capab
while (ssep.GetToken(capab))
{
+ if (capab.find('=') == Anope::string::npos)
+ continue;
+
Anope::string modename = capab.substr(0, capab.find('='));
Anope::string modechar = capab.substr(capab.find('=') + 1);
- ChannelMode *cm = NULL;
+ char symbol = 0;
- if (modename.equals_cs("admin"))
- cm = new ChannelModeStatus("PROTECT", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 3);
- else if (modename.equals_cs("allowinvite"))
- {
- cm = new ChannelMode("ALLINVITE", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("INVITEBAN", "BAN", 'A'));
- }
- else if (modename.equals_cs("auditorium"))
- cm = new ChannelMode("AUDITORIUM", modechar[0]);
- else if (modename.equals_cs("autoop"))
- cm = new InspIRCdAutoOpMode(modechar[0]);
- else if (modename.equals_cs("ban"))
- cm = new ChannelModeList("BAN", modechar[0]);
- else if (modename.equals_cs("banexception"))
- cm = new ChannelModeList("EXCEPT", modechar[0]);
- else if (modename.equals_cs("blockcaps"))
- {
- cm = new ChannelMode("BLOCKCAPS", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCAPSBAN", "BAN", 'B'));
- }
- else if (modename.equals_cs("blockcolor"))
- {
- cm = new ChannelMode("BLOCKCOLOR", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCOLORBAN", "BAN", 'c'));
- }
- else if (modename.equals_cs("c_registered"))
- cm = new ChannelModeNoone("REGISTERED", modechar[0]);
- else if (modename.equals_cs("censor"))
- cm = new ChannelMode("CENSOR", modechar[0]);
- else if (modename.equals_cs("delayjoin"))
- cm = new ChannelMode("DELAYEDJOIN", modechar[0]);
- else if (modename.equals_cs("delaymsg"))
- cm = new SimpleNumberParamMode("DELAYMSG", modechar[0]);
- else if (modename.equals_cs("filter"))
- cm = new ChannelModeList("FILTER", modechar[0]);
- else if (modename.equals_cs("flood"))
- cm = new ChannelModeFlood(modechar[0]);
- else if (modename.equals_cs("founder"))
- cm = new ChannelModeStatus("OWNER", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 4);
- else if (modename.equals_cs("halfop"))
- cm = new ChannelModeStatus("HALFOP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 1);
- else if (modename.equals_cs("history"))
- cm = new ChannelModeHistory(modechar[0]);
- else if (modename.equals_cs("invex"))
- cm = new ChannelModeList("INVITEOVERRIDE", modechar[0]);
- else if (modename.equals_cs("inviteonly"))
- cm = new ChannelMode("INVITE", modechar[0]);
- else if (modename.equals_cs("joinflood"))
- cm = new ColonDelimitedParamMode("JOINFLOOD", modechar[0]);
- else if (modename.equals_cs("key"))
- cm = new ChannelModeKey(modechar[0]);
- else if (modename.equals_cs("kicknorejoin"))
- cm = new SimpleNumberParamMode("NOREJOIN", modechar[0]);
- else if (modename.equals_cs("limit"))
- cm = new ChannelModeParam("LIMIT", modechar[0], true);
- else if (modename.equals_cs("moderated"))
- cm = new ChannelMode("MODERATED", modechar[0]);
- else if (modename.equals_cs("nickflood"))
- cm = new ColonDelimitedParamMode("NICKFLOOD", modechar[0]);
- else if (modename.equals_cs("noctcp"))
- {
- cm = new ChannelMode("NOCTCP", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOCTCPBAN", "BAN", 'C'));
- }
- else if (modename.equals_cs("noextmsg"))
- cm = new ChannelMode("NOEXTERNAL", modechar[0]);
- else if (modename.equals_cs("nokick"))
- {
- cm = new ChannelMode("NOKICK", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOKICKBAN", "BAN", 'Q'));
- }
- else if (modename.equals_cs("noknock"))
- cm = new ChannelMode("NOKNOCK", modechar[0]);
- else if (modename.equals_cs("nonick"))
- {
- cm = new ChannelMode("NONICK", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONICKBAN", "BAN", 'N'));
- }
- else if (modename.equals_cs("nonotice"))
+ if (modechar.empty())
+ continue;
+
+ if (modechar.length() == 2)
{
- cm = new ChannelMode("NONOTICE", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONOTICEBAN", "BAN", 'T'));
+ symbol = modechar[0];
+ modechar = modechar.substr(1);
}
- else if (modename.equals_cs("op"))
- cm = new ChannelModeStatus("OP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 2);
- else if (modename.equals_cs("operonly"))
- cm = new ChannelModeOperOnly("OPERONLY", modechar[0]);
- else if (modename.equals_cs("permanent"))
- cm = new ChannelMode("PERM", modechar[0]);
- else if (modename.equals_cs("private"))
- cm = new ChannelMode("PRIVATE", modechar[0]);
- else if (modename.equals_cs("redirect"))
- cm = new ChannelModeRedirect(modechar[0]);
- else if (modename.equals_cs("reginvite"))
- cm = new ChannelMode("REGISTEREDONLY", modechar[0]);
- else if (modename.equals_cs("regmoderated"))
- cm = new ChannelMode("REGMODERATED", modechar[0]);
- else if (modename.equals_cs("secret"))
- cm = new ChannelMode("SECRET", modechar[0]);
- else if (modename.equals_cs("sslonly"))
+
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modechar[0]);
+ if (cm == nullptr)
{
- cm = new ChannelMode("SSL", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::FinerprintMatcher("SSLBAN", "BAN", 'z'));
+ Log(this->GetOwner()) << "Warning: Uplink has unknown channel mode " << modename << "=" << modechar;
+ continue;
}
- else if (modename.equals_cs("stripcolor"))
+
+ char modesymbol = cm->type == MODE_STATUS ? (anope_dynamic_static_cast<ChannelModeStatus *>(cm))->symbol : 0;
+ if (symbol != modesymbol)
{
- cm = new ChannelMode("STRIPCOLOR", modechar[0]);
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("STRIPCOLORBAN", "BAN", 'S'));
+ Log(this->GetOwner()) << "Warning: Channel mode " << modename << " has a misconfigured status character";
+ continue;
}
- else if (modename.equals_cs("topiclock"))
- cm = new ChannelMode("TOPIC", modechar[0]);
- else if (modename.equals_cs("voice"))
- cm = new ChannelModeStatus("VOICE", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 0);
- /* Unknown status mode, (customprefix) - add it */
- else if (modechar.length() == 2)
- cm = new ChannelModeStatus(modename.upper(), modechar[1], modechar[0], -1);
- /* Unknown non status mode, add it to our list for later */
- else
- chmodes[modechar[0]] = modename.upper();
-
- if (cm)
- ModeManager::AddChannelMode(cm);
}
}
if (params[0].equals_cs("USERMODES") && params.size() > 1)
@@ -541,54 +699,21 @@ struct IRCDMessageCapab : Message::Capab
while (ssep.GetToken(capab))
{
+ if (capab.find('=') == Anope::string::npos)
+ continue;
+
Anope::string modename = capab.substr(0, capab.find('='));
Anope::string modechar = capab.substr(capab.find('=') + 1);
- UserMode *um = NULL;
-
- if (modename.equals_cs("bot"))
- um = new UserMode("BOT", modechar[0]);
- else if (modename.equals_cs("callerid"))
- um = new UserMode("CALLERID", modechar[0]);
- else if (modename.equals_cs("cloak"))
- um = new UserMode("CLOAK", modechar[0]);
- else if (modename.equals_cs("deaf"))
- um = new UserMode("DEAF", modechar[0]);
- else if (modename.equals_cs("deaf_commonchan"))
- um = new UserMode("COMMONCHANS", modechar[0]);
- else if (modename.equals_cs("helpop"))
- um = new UserModeOperOnly("HELPOP", modechar[0]);
- else if (modename.equals_cs("hidechans"))
- um = new UserMode("PRIV", modechar[0]);
- else if (modename.equals_cs("hideoper"))
- um = new UserModeOperOnly("HIDEOPER", modechar[0]);
- else if (modename.equals_cs("invisible"))
- um = new UserMode("INVIS", modechar[0]);
- else if (modename.equals_cs("invis-oper"))
- um = new UserModeOperOnly("INVISIBLE_OPER", modechar[0]);
- else if (modename.equals_cs("oper"))
- um = new UserModeOperOnly("OPER", modechar[0]);
- else if (modename.equals_cs("regdeaf"))
- um = new UserMode("REGPRIV", modechar[0]);
- else if (modename.equals_cs("servprotect"))
+
+ if (modechar.empty())
+ continue;
+
+ UserMode *um = ModeManager::FindUserModeByChar(modechar[0]);
+ if (um == nullptr)
{
- um = new UserModeNoone("PROTECTED", modechar[0]);
- IRCD->DefaultPseudoclientModes += modechar;
+ Log(this->GetOwner()) << "Warning: Uplink has unknown user mode " << modename << "=" << modechar;
+ continue;
}
- else if (modename.equals_cs("showwhois"))
- um = new UserMode("WHOIS", modechar[0]);
- else if (modename.equals_cs("u_censor"))
- um = new UserMode("CENSOR", modechar[0]);
- else if (modename.equals_cs("u_registered"))
- um = new UserModeNoone("REGISTERED", modechar[0]);
- else if (modename.equals_cs("u_stripcolor"))
- um = new UserMode("STRIPCOLOR", modechar[0]);
- else if (modename.equals_cs("wallops"))
- um = new UserMode("WALLOPS", modechar[0]);
- else
- umodes[modechar[0]] = modename.upper();
-
- if (um)
- ModeManager::AddUserMode(um);
}
}
else if (params[0].equals_cs("MODULES") && params.size() > 1)
@@ -603,7 +728,7 @@ struct IRCDMessageCapab : Message::Capab
else if (module.find("m_rline.so") == 0)
{
Servers::Capab.insert("RLINE");
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
if (!regexengine.empty() && module.length() > 11 && regexengine != module.substr(11))
Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << regexengine << ". This may cause inconsistencies.";
}
@@ -619,25 +744,11 @@ struct IRCDMessageCapab : Message::Capab
while (ssep.GetToken(module))
{
if (module.equals_cs("m_services_account.so"))
- {
Servers::Capab.insert("SERVICES");
- ModeManager::AddChannelMode(new InspIRCdExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'R'));
- ModeManager::AddChannelMode(new InspIRCdExtban::UnidentifiedMatcher("UNREGISTEREDBAN", "BAN", 'U'));
- }
else if (module.equals_cs("m_chghost.so"))
Servers::Capab.insert("CHGHOST");
else if (module.equals_cs("m_chgident.so"))
Servers::Capab.insert("CHGIDENT");
- else if (module == "m_channelban.so")
- ModeManager::AddChannelMode(new InspIRCdExtban::ChannelMatcher("CHANNELBAN", "BAN", 'j'));
- else if (module == "m_gecosban.so")
- ModeManager::AddChannelMode(new InspIRCdExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r'));
- else if (module == "m_nopartmessage.so")
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("PARTMESSAGEBAN", "BAN", 'p'));
- else if (module == "m_serverban.so")
- ModeManager::AddChannelMode(new InspIRCdExtban::ServerMatcher("SERVERBAN", "BAN", 's'));
- else if (module == "m_muteban.so")
- ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("QUIET", "BAN", 'm'));
}
}
else if (params[0].equals_cs("CAPABILITIES") && params.size() > 1)
@@ -646,89 +757,11 @@ struct IRCDMessageCapab : Message::Capab
Anope::string capab;
while (ssep.GetToken(capab))
{
- if (capab.find("CHANMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- if (ModeManager::FindChannelModeByChar(modebuf[t]))
- continue;
- ModeManager::AddChannelMode(new ChannelModeList(chmodes[modebuf[t]], modebuf[t]));
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- if (ModeManager::FindChannelModeByChar(modebuf[t]))
- continue;
- ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t]));
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- if (ModeManager::FindChannelModeByChar(modebuf[t]))
- continue;
- ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t], true));
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- if (ModeManager::FindChannelModeByChar(modebuf[t]))
- continue;
- ModeManager::AddChannelMode(new ChannelMode(chmodes[modebuf[t]], modebuf[t]));
- }
- }
- else if (capab.find("USERMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- sep.GetToken(modebuf);
- sep.GetToken(modebuf);
-
- if (sep.GetToken(modebuf))
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- ModeManager::AddUserMode(new UserModeParam(umodes[modebuf[t]], modebuf[t]));
-
- if (sep.GetToken(modebuf))
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- ModeManager::AddUserMode(new UserMode(umodes[modebuf[t]], modebuf[t]));
- }
- else if (capab.find("MAXMODES=") != Anope::string::npos)
+ if (capab.find("MAXMODES=") != Anope::string::npos)
{
Anope::string maxmodes(capab.begin() + 9, capab.end());
IRCD->MaxModes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3;
}
- else if (capab.find("PREFIX=") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')'));
- Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end());
- short level = modes.length() - 1;
-
- for (size_t t = 0, end = modes.length(); t < end; ++t)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[t]);
- if (cm == NULL || cm->type != MODE_STATUS)
- {
- Log() << "CAPAB PREFIX gave unknown channel status mode " << modes[t];
- continue;
- }
-
- ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
- cms->level = level--;
-
- Log(LOG_DEBUG) << cms->name << " is now level " << cms->level;
- }
-
- ModeManager::RebuildStatusModes();
- }
else if (capab == "GLOBOPS=1")
Servers::Capab.insert("GLOBOPS");
}
@@ -737,14 +770,14 @@ struct IRCDMessageCapab : Message::Capab
{
if (!Servers::Capab.count("SERVICES"))
{
- UplinkSocket::Message() << "ERROR :m_services_account.so is not loaded. This is required by Anope";
+ Uplink::Send("ERROR", "m_services_account.so is not loaded. This is required by Anope");
Anope::QuitReason = "ERROR: Remote server does not have the m_services_account module loaded, and this is required.";
Anope::Quitting = true;
return;
}
if (!ModeManager::FindUserModeByName("PRIV"))
{
- UplinkSocket::Message() << "ERROR :m_hidechans.so is not loaded. This is required by Anope";
+ Uplink::Send("ERROR", "m_hidechans.so is not loaded. This is required by Anope");
Anope::QuitReason = "ERROR: Remote server does not have the m_hidechans module loaded, and this is required.";
Anope::Quitting = true;
return;
@@ -755,9 +788,6 @@ struct IRCDMessageCapab : Message::Capab
Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!Servers::Capab.count("CHGIDENT"))
Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
-
- chmodes.clear();
- umodes.clear();
}
Message::Capab::Run(source, params);
@@ -766,11 +796,9 @@ struct IRCDMessageCapab : Message::Capab
struct IRCDMessageEncap : IRCDMessage
{
- ServiceReference<IRCDMessage> insp12_encap;
-
- IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4), insp12_encap("IRCDMessage", "inspircd12/encap") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+ IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (Anope::Match(Me->GetSID(), params[0]) == false)
return;
@@ -782,7 +810,7 @@ struct IRCDMessageEncap : IRCDMessage
return;
u->SetIdent(params[3]);
- UplinkSocket::Message(u) << "FIDENT " << params[3];
+ Uplink::Send(u, "FIDENT", params[3]);
}
else if (params[1] == "CHGHOST")
{
@@ -791,7 +819,7 @@ struct IRCDMessageEncap : IRCDMessage
return;
u->SetDisplayedHost(params[3]);
- UplinkSocket::Message(u) << "FHOST " << params[3];
+ Uplink::Send(u, "FHOST", params[3]);
}
else if (params[1] == "CHGNAME")
{
@@ -800,11 +828,22 @@ struct IRCDMessageEncap : IRCDMessage
return;
u->SetRealname(params[3]);
- UplinkSocket::Message(u) << "FNAME " << params[3];
+ Uplink::Send(u, "FNAME", params[3]);
}
+ }
+};
- if (insp12_encap)
- insp12_encap->Run(source, params);
+struct IRCDMessageEndburst : IRCDMessage
+{
+ IRCDMessageEndburst(Module *creator) : IRCDMessage(creator, "ENDBURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ Server *s = source.GetServer();
+
+ Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName();
+
+ s->Sync(true);
}
};
@@ -812,7 +851,7 @@ struct IRCDMessageFHost : IRCDMessage
{
IRCDMessageFHost(Module *creator) : IRCDMessage(creator, "FHOST", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = source.GetUser();
if (u->HasMode("CLOAK"))
@@ -825,19 +864,337 @@ struct IRCDMessageFIdent : IRCDMessage
{
IRCDMessageFIdent(Module *creator) : IRCDMessage(creator, "FIDENT", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
source.GetUser()->SetIdent(params[0]);
}
};
+struct IRCDMessageFJoin : IRCDMessage
+{
+ IRCDMessageFJoin(Module *creator) : IRCDMessage(creator, "FJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ Anope::string modes;
+ if (params.size() >= 3)
+ {
+ for (unsigned i = 2; i < params.size() - 1; ++i)
+ modes += " " + params[i];
+ if (!modes.empty())
+ modes.erase(modes.begin());
+ }
+
+ std::list<Message::Join::SJoinUser> users;
+
+ spacesepstream sep(params[params.size() - 1]);
+ Anope::string buf;
+ while (sep.GetToken(buf))
+ {
+ Message::Join::SJoinUser sju;
+
+ /* Loop through prefixes and find modes for them */
+ for (char c; (c = buf[0]) != ',' && c;)
+ {
+ buf.erase(buf.begin());
+ sju.first.AddMode(c);
+ }
+ /* Erase the , */
+ if (!buf.empty())
+ buf.erase(buf.begin());
+
+ sju.second = User::Find(buf);
+ if (!sju.second)
+ {
+ Log(LOG_DEBUG) << "FJOIN for non-existent user " << buf << " on " << params[0];
+ continue;
+ }
+
+ users.push_back(sju);
+ }
+
+ time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
+ Message::Join::SJoin(source, params[0], ts, modes, users);
+ }
+};
+
+struct IRCDMessageFMode : IRCDMessage
+{
+ IRCDMessageFMode(Module *creator) : IRCDMessage(creator, "FMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ /* :source FMODE #test 12345678 +nto foo */
+
+ Anope::string modes = params[2];
+ for (unsigned n = 3; n < params.size(); ++n)
+ modes += " " + params[n];
+
+ Channel *c = Channel::Find(params[0]);
+ time_t ts;
+
+ try
+ {
+ ts = convertTo<time_t>(params[1]);
+ }
+ catch (const ConvertException &)
+ {
+ ts = 0;
+ }
+
+ if (c)
+ c->SetModesInternal(source, modes, ts);
+ }
+};
+
+struct IRCDMessageFTopic : IRCDMessage
+{
+ IRCDMessageFTopic(Module *creator) : IRCDMessage(creator, "FTOPIC", 4) { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ /* :source FTOPIC channel topicts setby :topic */
+
+ Channel *c = Channel::Find(params[0]);
+ if (c)
+ c->ChangeTopicInternal(NULL, params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
+ }
+};
+
+struct IRCDMessageIdle : IRCDMessage
+{
+ IRCDMessageIdle(Module *creator) : IRCDMessage(creator, "IDLE", 1) { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ ServiceBot *bi = ServiceBot::Find(params[0]);
+ if (bi)
+ {
+ Uplink::Send(bi, "IDLE", source.GetSource(), Anope::StartTime, Anope::CurTime - bi->lastmsg);
+ }
+ else
+ {
+ User *u = User::Find(params[0]);
+ if (u && u->server == Me)
+ Uplink::Send(u, "IDLE", source.GetSource(), Anope::StartTime, 0);
+ }
+ }
+};
+
+/*
+ * source = numeric of the sending server
+ * params[0] = uuid
+ * params[1] = metadata name
+ * params[2] = data
+ */
+struct IRCDMessageMetadata : IRCDMessage
+{
+ const bool &do_topiclock, &do_mlock;
+
+ IRCDMessageMetadata(Module *creator, const bool &handle_topiclock, const bool &handle_mlock)
+ : IRCDMessage(creator, "METADATA", 3)
+ , do_topiclock(handle_topiclock)
+ , do_mlock(handle_mlock)
+ {
+ SetFlag(IRCDMESSAGE_REQUIRE_SERVER);
+ }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (isdigit(params[0][0]))
+ {
+ if (params[1].equals_cs("accountname"))
+ {
+ User *u = User::Find(params[0]);
+ NickServ::Account *nc = NickServ::FindAccount(params[2]);
+ if (u && nc)
+ u->Login(nc);
+ }
+
+ /*
+ * possible incoming ssl_cert messages:
+ * Received: :409 METADATA 409AAAAAA ssl_cert :vTrSe c38070ce96e41cc144ed6590a68d45a6 <...> <...>
+ * Received: :409 METADATA 409AAAAAC ssl_cert :vTrSE Could not get peer certificate: error:00000000:lib(0):func(0):reason(0)
+ */
+ else if (params[1].equals_cs("ssl_cert"))
+ {
+ User *u = User::Find(params[0]);
+ if (!u)
+ return;
+ u->Extend<bool>("ssl", true);
+ Anope::string data = params[2].c_str();
+ size_t pos1 = data.find(' ') + 1;
+ size_t pos2 = data.find(' ', pos1);
+ if ((pos2 - pos1) >= 32) // inspircd supports md5 and sha1 fingerprint hashes -> size 32 or 40 bytes.
+ {
+ u->fingerprint = data.substr(pos1, pos2 - pos1);
+ }
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
+ }
+ }
+ // We deliberately ignore non-bursting servers to avoid pseudoserver fights
+ else if ((params[0][0] == '#') && (!source.GetServer()->IsSynced()))
+ {
+ Channel *c = Channel::Find(params[0]);
+ if (c && c->ci)
+ {
+ if ((do_mlock) && (params[1] == "mlock"))
+ {
+ ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
+ Anope::string modes;
+ if (modelocks)
+ modes = modelocks->GetMLockAsString(c->ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
+
+ // Mode lock string is not what we say it is?
+ if (modes != params[2])
+ Uplink::Send(Me, "METADATA", c->name, "mlock", modes);
+ }
+ else if ((do_topiclock) && (params[1] == "topiclock"))
+ {
+ bool mystate = c->ci->GetExt<bool>("TOPICLOCK");
+ bool serverstate = (params[2] == "1");
+ if (mystate != serverstate)
+ Uplink::Send(Me, "METADATA", c->name, "topiclock", mystate ? "1" : "");
+ }
+ }
+ }
+ else if (params[0] == "*")
+ {
+ // Wed Oct 3 15:40:27 2012: S[14] O :20D METADATA * modules :-m_svstopic.so
+
+ if (params[1].equals_cs("modules") && !params[2].empty())
+ {
+ // only interested when it comes from our uplink
+ Server* server = source.GetServer();
+ if (!server || server->GetUplink() != Me)
+ return;
+
+ bool plus = (params[2][0] == '+');
+ if (!plus && params[2][0] != '-')
+ return;
+
+ bool required = false;
+ Anope::string capab, module = params[2].substr(1);
+
+ if (module.equals_cs("m_services_account.so"))
+ required = true;
+ else if (module.equals_cs("m_hidechans.so"))
+ required = true;
+ else if (module.equals_cs("m_chghost.so"))
+ capab = "CHGHOST";
+ else if (module.equals_cs("m_chgident.so"))
+ capab = "CHGIDENT";
+ else if (module.equals_cs("m_svshold.so"))
+ capab = "SVSHOLD";
+ else if (module.equals_cs("m_rline.so"))
+ capab = "RLINE";
+ else if (module.equals_cs("m_topiclock.so"))
+ capab = "TOPICLOCK";
+ else
+ return;
+
+ if (required)
+ {
+ if (!plus)
+ Log() << "Warning: InspIRCd unloaded module " << module << ", Anope won't function correctly without it";
+ }
+ else
+ {
+ if (plus)
+ Servers::Capab.insert(capab);
+ else
+ Servers::Capab.erase(capab);
+
+ Log() << "InspIRCd " << (plus ? "loaded" : "unloaded") << " module " << module << ", adjusted functionality";
+ }
+
+ }
+ }
+ }
+};
+
+struct IRCDMessageMode : IRCDMessage
+{
+ IRCDMessageMode(Module *creator) : IRCDMessage(creator, "MODE", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (IRCD->IsChannelValid(params[0]))
+ {
+ Channel *c = Channel::Find(params[0]);
+
+ Anope::string modes = params[1];
+ for (unsigned n = 2; n < params.size(); ++n)
+ modes += " " + params[n];
+
+ if (c)
+ c->SetModesInternal(source, modes);
+ }
+ else
+ {
+ /* InspIRCd lets opers change another
+ users modes, we have to kludge this
+ as it slightly breaks RFC1459
+ */
+ User *u = source.GetUser();
+ // This can happen with server-origin modes.
+ if (!u)
+ u = User::Find(params[0]);
+ // if it's still null, drop it like fire.
+ // most likely situation was that server introduced a nick which we subsequently akilled
+ if (u)
+ u->SetModesInternal(source, "%s", params[1].c_str());
+ }
+ }
+};
+
+struct IRCDMessageNick : IRCDMessage
+{
+ IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ source.GetUser()->ChangeNick(params[0]);
+ }
+};
+
+struct IRCDMessageOperType : IRCDMessage
+{
+ IRCDMessageOperType(Module *creator) : IRCDMessage(creator, "OPERTYPE", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ /* opertype is equivalent to mode +o because servers
+ dont do this directly */
+ User *u = source.GetUser();
+ if (!u->HasMode("OPER"))
+ u->SetModesInternal(source, "+o");
+ }
+};
+
+struct IRCDMessageRSQuit : IRCDMessage
+{
+ IRCDMessageRSQuit(Module *creator) : IRCDMessage(creator, "RSQUIT", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ Server *s = Server::Find(params[0]);
+ const Anope::string &reason = params.size() > 1 ? params[1] : "";
+ if (!s)
+ return;
+
+ Uplink::Send(Me, "SQUIT", s->GetSID(), reason);
+ s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
+ }
+};
+
struct IRCDMessageSave : IRCDMessage
{
time_t last_collide;
IRCDMessageSave(Module *creator) : IRCDMessage(creator, "SAVE", 2), last_collide(0) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *targ = User::Find(params[0]);
time_t ts;
@@ -873,54 +1230,118 @@ struct IRCDMessageSave : IRCDMessage
}
};
-class IRCDMessageMetadata : IRCDMessage
+struct IRCDMessageServer : IRCDMessage
{
- ServiceReference<IRCDMessage> insp12_metadata;
- const bool &do_topiclock;
- const bool &do_mlock;
+ IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 5) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ /*
+ * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central!
+ * 0: name
+ * 1: pass
+ * 2: hops
+ * 3: numeric
+ * 4: desc
+ */
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ unsigned int hops = Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0;
+ new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[4], params[3]);
+ }
+};
- public:
- IRCDMessageMetadata(Module *creator, const bool &handle_topiclock, const bool &handle_mlock) : IRCDMessage(creator, "METADATA", 3), insp12_metadata("IRCDMessage", "inspircd12/metadata"), do_topiclock(handle_topiclock), do_mlock(handle_mlock) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+struct IRCDMessageSQuit : Message::SQuit
+{
+ IRCDMessageSQuit(Module *creator) : Message::SQuit(creator) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
- // We deliberately ignore non-bursting servers to avoid pseudoserver fights
- if ((params[0][0] == '#') && (!source.GetServer()->IsSynced()))
+ if (params[0] == rsquit_id || params[0] == rsquit_server)
{
- Channel *c = Channel::Find(params[0]);
- if (c && c->ci)
+ /* squit for a recently squit server, introduce the juped server now */
+ Server *s = Server::Find(rsquit_server);
+
+ rsquit_id.clear();
+ rsquit_server.clear();
+
+ if (s && s->IsJuped())
+ IRCD->SendServer(s);
+ }
+ else
+ Message::SQuit::Run(source, params);
+ }
+};
+
+struct IRCDMessageTime : IRCDMessage
+{
+ IRCDMessageTime(Module *creator) : IRCDMessage(creator, "TIME", 2) { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ Uplink::Send(Me, "TIME", source.GetSource(), params[1], Anope::CurTime);
+ }
+};
+
+struct IRCDMessageUID : IRCDMessage
+{
+ ServiceReference<SASL::Service> sasl;
+
+ IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ /*
+ * [Nov 03 22:09:58.176252 2009] debug: Received: :964 UID 964AAAAAC 1225746297 w00t2 localhost testnet.user w00t 127.0.0.1 1225746302 +iosw +ACGJKLNOQcdfgjklnoqtx :Robin Burchell <w00t@inspircd.org>
+ * 0: uid
+ * 1: ts
+ * 2: nick
+ * 3: host
+ * 4: dhost
+ * 5: ident
+ * 6: ip
+ * 7: signon
+ * 8+: modes and params -- IMPORTANT, some modes (e.g. +s) may have parameters. So don't assume a fixed position of realname!
+ * last: realname
+ */
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ time_t ts = convertTo<time_t>(params[1]);
+
+ Anope::string modes = params[8];
+ for (unsigned i = 9; i < params.size() - 1; ++i)
+ modes += " " + params[i];
+
+ NickServ::Nick *na = NULL;
+ if (sasl)
+ for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
{
- if ((do_mlock) && (params[1] == "mlock"))
- {
- ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
- Anope::string modes;
- if (modelocks)
- modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
+ SASLUser &u = *it;
- // Mode lock string is not what we say it is?
- if (modes != params[2])
- UplinkSocket::Message(Me) << "METADATA " << c->name << " mlock :" << modes;
- }
- else if ((do_topiclock) && (params[1] == "topiclock"))
+ if (u.created + 30 < Anope::CurTime)
+ it = saslusers.erase(it);
+ else if (u.uid == params[0])
{
- bool mystate = c->ci->GetExt<bool>("TOPICLOCK");
- bool serverstate = (params[2] == "1");
- if (mystate != serverstate)
- UplinkSocket::Message(Me) << "METADATA " << c->name << " topiclock :" << (mystate ? "1" : "");
+ na = NickServ::FindNick(u.acc);
+ it = saslusers.erase(it);
}
+ else
+ ++it;
}
- }
- if (insp12_metadata)
- insp12_metadata->Run(source, params);
+ User *u = User::OnIntroduce(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? na->GetAccount() : NULL);
+ if (u)
+ u->signon = convertTo<time_t>(params[7]);
}
};
class ProtoInspIRCd20 : public Module
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::DelChan>
+ , public EventHook<Event::MLockEvents>
+ , public EventHook<Event::SetChannelOption>
{
- Module *m_insp12;
-
InspIRCd20Proto ircd_proto;
+ ExtensibleItem<bool> ssl;
+ ServiceReference<ModeLocks> mlocks;
/* Core message handlers */
Message::Away message_away;
@@ -938,103 +1359,149 @@ class ProtoInspIRCd20 : public Module
Message::Stats message_stats;
Message::Topic message_topic;
- /* InspIRCd 1.2 message handlers */
- ServiceAlias message_endburst, message_fjoin, message_fmode,
- message_ftopic, message_idle, message_mode,
- message_nick, message_opertype, message_rsquit, message_server,
- message_squit, message_time, message_uid;
-
/* Our message handlers */
IRCDMessageCapab message_capab;
IRCDMessageEncap message_encap;
+ IRCDMessageEndburst message_endburst;
IRCDMessageFHost message_fhost;
IRCDMessageFIdent message_fident;
+ IRCDMessageFJoin message_fjoin;
+ IRCDMessageFMode message_fmode;
+ IRCDMessageFTopic message_ftopic;
+ IRCDMessageIdle message_idle;
IRCDMessageMetadata message_metadata;
+ IRCDMessageMode message_mode;
+ IRCDMessageNick message_nick;
+ IRCDMessageOperType message_opertype;
+ IRCDMessageRSQuit message_rsquit;
IRCDMessageSave message_save;
+ IRCDMessageServer message_server;
+ IRCDMessageSQuit message_squit;
+ IRCDMessageTime message_time;
+ IRCDMessageUID message_uid;
bool use_server_side_topiclock, use_server_side_mlock;
void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value)
{
- UplinkSocket::Message(Me) << "METADATA " << c->name << " " << metadataname << " :" << value;
+ Uplink::Send(Me, "METADATA", c->name, metadataname, value);
}
public:
- ProtoInspIRCd20(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this),
- message_kill(this), message_motd(this), message_notice(this), message_part(this), message_ping(this),
- message_privmsg(this), message_quit(this), message_stats(this), message_topic(this),
-
- message_endburst("IRCDMessage", "inspircd20/endburst", "inspircd12/endburst"),
- message_fjoin("IRCDMessage", "inspircd20/fjoin", "inspircd12/fjoin"),
- message_fmode("IRCDMessage", "inspircd20/fmode", "inspircd12/fmode"),
- message_ftopic("IRCDMessage", "inspircd20/ftopic", "inspircd12/ftopic"),
- message_idle("IRCDMessage", "inspircd20/idle", "inspircd12/idle"),
- message_mode("IRCDMessage", "inspircd20/mode", "inspircd12/mode"),
- message_nick("IRCDMessage", "inspircd20/nick", "inspircd12/nick"),
- message_opertype("IRCDMessage", "inspircd20/opertype", "inspircd12/opertype"),
- message_rsquit("IRCDMessage", "inspircd20/rsquit", "inspircd12/rsquit"),
- message_server("IRCDMessage", "inspircd20/server", "inspircd12/server"),
- message_squit("IRCDMessage", "inspircd20/squit", "inspircd12/squit"),
- message_time("IRCDMessage", "inspircd20/time", "inspircd12/time"),
- message_uid("IRCDMessage", "inspircd20/uid", "inspircd12/uid"),
-
- message_capab(this), message_encap(this), message_fhost(this), message_fident(this), message_metadata(this, use_server_side_topiclock, use_server_side_mlock),
- message_save(this)
+ ProtoInspIRCd20(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::UserNickChange>(this)
+ , EventHook<Event::ChannelSync>(this)
+ , EventHook<Event::ChanRegistered>(this)
+ , EventHook<Event::DelChan>(this)
+ , EventHook<Event::MLockEvents>(this)
+ , EventHook<Event::SetChannelOption>(this)
+
+ , ircd_proto(this)
+ , ssl(this, "ssl")
+ , message_away(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_join(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_stats(this)
+ , message_topic(this)
+
+ , message_capab(this)
+ , message_encap(this)
+ , message_endburst(this)
+ , message_fhost(this)
+ , message_fident(this)
+ , message_fjoin(this)
+ , message_fmode(this)
+ , message_ftopic(this)
+ , message_idle(this)
+ , message_metadata(this, use_server_side_topiclock, use_server_side_mlock)
+ , message_mode(this)
+ , message_nick(this)
+ , message_opertype(this)
+ , message_rsquit(this)
+ , message_save(this)
+ , message_server(this)
+ , message_squit(this)
+ , message_time(this)
+ , message_uid(this)
{
-
- if (ModuleManager::LoadModule("inspircd12", User::Find(creator)) != MOD_ERR_OK)
- throw ModuleException("Unable to load inspircd12");
- m_insp12 = ModuleManager::FindModule("inspircd12");
- if (!m_insp12)
- throw ModuleException("Unable to find inspircd12");
- if (!insp12)
- throw ModuleException("No protocol interface for insp12");
- ModuleManager::DetachAll(m_insp12);
-
}
- ~ProtoInspIRCd20()
- {
- m_insp12 = ModuleManager::FindModule("inspircd12");
- ModuleManager::UnloadModule(m_insp12, NULL);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock");
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
+
+ for (int i = 0; i < conf->CountBlock("extban"); ++i)
+ {
+ Configuration::Block *extban = conf->GetBlock("extban", i);
+ Anope::string name = extban->Get<Anope::string>("name"),
+ type = extban->Get<Anope::string>("type"),
+ base = extban->Get<Anope::string>("base"),
+ character = extban->Get<Anope::string>("character");
+
+ ChannelMode *cm;
+
+ if (character.empty())
+ continue;
+
+ if (type == "channel")
+ cm = new InspIRCdExtban::ChannelMatcher(name, base, character[0]);
+ else if (type == "entry")
+ cm = new InspIRCdExtban::EntryMatcher(name, base, character[0]);
+ else if (type == "realname")
+ cm = new InspIRCdExtban::RealnameMatcher(name, base, character[0]);
+ else if (type == "account")
+ cm = new InspIRCdExtban::AccountMatcher(name, base, character[0]);
+ else if (type == "fingerprint")
+ cm = new InspIRCdExtban::FingerprintMatcher(name, base, character[0]);
+ else if (type == "unidentified")
+ cm = new InspIRCdExtban::UnidentifiedMatcher(name, base, character[0]);
+ else if (type == "server")
+ cm = new InspIRCdExtban::ServerMatcher(name, base, character[0]);
+ else
+ continue;
+
+ if (!ModeManager::AddChannelMode(cm))
+ delete cm;
+ }
}
- void OnUserNickChange(User *u, const Anope::string &) anope_override
+ void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
}
- void OnChannelSync(Channel *c) anope_override
+ void OnChannelSync(Channel *c) override
{
if (c->ci)
this->OnChanRegistered(c->ci);
}
- void OnChanRegistered(ChannelInfo *ci) anope_override
+ void OnChanRegistered(ChanServ::Channel *ci) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- if (use_server_side_mlock && ci->c && modelocks && !modelocks->GetMLockAsString(false).empty())
+ if (use_server_side_mlock && ci->c && mlocks && !mlocks->GetMLockAsString(ci, false).empty())
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
SendChannelMetadata(ci->c, "mlock", modes);
}
if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c)
{
- if (ci->HasExt("TOPICLOCK"))
+ if (ci->HasFieldS("TOPICLOCK"))
SendChannelMetadata(ci->c, "topiclock", "1");
}
}
- void OnDelChan(ChannelInfo *ci) anope_override
+ void OnDelChan(ChanServ::Channel *ci) override
{
if (use_server_side_mlock && ci->c)
SendChannelMetadata(ci->c, "mlock", "");
@@ -1043,35 +1510,33 @@ class ProtoInspIRCd20 : public Module
SendChannelMetadata(ci->c, "topiclock", "");
}
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && ci->c && mlocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
SendChannelMetadata(ci->c, "mlock", modes);
}
return EVENT_CONTINUE;
}
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnUnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && ci->c && mlocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
SendChannelMetadata(ci->c, "mlock", modes);
}
return EVENT_CONTINUE;
}
- EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChannelInfo *ci, const Anope::string &setting) anope_override
+ EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChanServ::Channel *ci, const Anope::string &setting) override
{
- if (cmd->name == "chanserv/topic" && ci->c)
+ if (cmd->GetName() == "chanserv/topic" && ci->c)
{
if (setting == "topiclock on")
SendChannelMetadata(ci->c, "topiclock", "1");
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index e7ae31fce..aa2c23a80 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -1,19 +1,28 @@
-/* ngIRCd Protocol module for Anope IRC Services
+/*
+ * Anope IRC Services
*
- * (C) 2011-2012, 2014 Alexander Barton <alex@barton.de>
- * (C) 2011-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2011-2012, 2014 Alexander Barton <alex@barton.de>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
class ngIRCdProto : public IRCDProto
{
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) override
{
IRCDProto::SendSVSKillInternal(source, user, buf);
user->KillInternal(source, buf);
@@ -30,64 +39,64 @@ class ngIRCdProto : public IRCDProto
MaxModes = 5;
}
- void SendAkill(User *u, XLine *x) anope_override
+ void SendAkill(User *u, XLine *x) override
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- UplinkSocket::Message(Me) << "GLINE " << x->mask << " " << timeleft << " :" << x->GetReason() << " (" << x->by << ")";
+ Uplink::Send(Me, "GLINE", x->GetMask(), timeleft, x->GetReason() + " (" + x->GetBy() + ")");
}
- void SendAkillDel(const XLine *x) anope_override
+ void SendAkillDel(XLine *x) override
{
- UplinkSocket::Message(Me) << "GLINE " << x->mask;
+ Uplink::Send(Me, "GLINE", x->GetMask());
}
- void SendChannel(Channel *c) anope_override
+ void SendChannel(Channel *c) override
{
- UplinkSocket::Message(Me) << "CHANINFO " << c->name << " +" << c->GetModes(true, true);
+ Uplink::Send(Me, "CHANINFO", c->name, "+" + c->GetModes(true, true));
}
// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "NICK " << u->nick << " 1 " << u->GetIdent() << " " << u->host << " 1 " << modes << " :" << u->realname;
+ Uplink::Send(Me, "NICK", u->nick, 1, u->GetIdent(), u->host, 1, modes, u->realname);
}
- void SendConnect() anope_override
+ void SendConnect() override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P";
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "0210-IRC+", "Anope|" + Anope::VersionShort(), "CLHMSo P");
/* Make myself known to myself in the serverlist */
SendServer(Me);
/* finish the enhanced server handshake and register the connection */
this->SendNumeric(376, "*", ":End of MOTD command");
}
- void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override
+ void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override
{
- UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick;
+ Uplink::Send(Me, "SVSNICK", u->nick, newnick);
}
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
}
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
}
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "WALLOPS :" << buf;
+ Uplink::Send(source, "WALLOPS", buf);
}
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override
{
- UplinkSocket::Message(user) << "JOIN " << c->name;
+ Uplink::Send(user, "JOIN", c->name);
if (status)
{
/* First save the channel status incase uc->Status == status */
@@ -99,7 +108,7 @@ class ngIRCdProto : public IRCDProto
if (uc != NULL)
uc->status.Clear();
- BotInfo *setter = BotInfo::Find(user->GetUID());
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
@@ -108,54 +117,56 @@ class ngIRCdProto : public IRCDProto
}
}
- void SendKickInternal(const MessageSource &source, const Channel *chan, User *user, const Anope::string &buf) anope_override
+ void SendKickInternal(const MessageSource &source, const Channel *chan, User *user, const Anope::string &buf) override
{
if (!buf.empty())
- UplinkSocket::Message(source) << "KICK " << chan->name << " " << user->nick << " :" << buf;
+ Uplink::Send(source, "KICK", chan->name, user->nick, buf);
else
- UplinkSocket::Message(source) << "KICK " << chan->name << " " << user->nick;
+ Uplink::Send(source, "KICK", chan->name, user->nick);
}
- void SendLogin(User *u, NickAlias *na) anope_override
+ void SendLogin(User *u, NickServ::Nick *na) override
{
- UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << na->nc->display;
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
- UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :";
- }
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
+ }
- void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "MODE " << dest->name << " " << buf;
+ IRCMessage message(source, "MODE", dest->name);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
- void SendPartInternal(User *u, const Channel *chan, const Anope::string &buf) anope_override
+ void SendPartInternal(User *u, const Channel *chan, const Anope::string &buf) override
{
if (!buf.empty())
- UplinkSocket::Message(u) << "PART " << chan->name << " :" << buf;
+ Uplink::Send(u, "PART", chan->name, buf);
else
- UplinkSocket::Message(u) << "PART " << chan->name;
+ Uplink::Send(u, "PART", chan->name);
}
/* SERVER name hop descript */
- void SendServer(const Server *server) anope_override
+ void SendServer(const Server *server) override
{
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
+ Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription());
}
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- UplinkSocket::Message(source) << "TOPIC " << c->name << " :" << c->topic;
+ Uplink::Send(source, "TOPIC", c->name, c->topic);
}
- void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) anope_override
+ void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override
{
if (!vIdent.empty())
- UplinkSocket::Message(Me) << "METADATA " << u->nick << " user :" << vIdent;
+ Uplink::Send(Me, "METADATA", u->nick, "user", vIdent);
- UplinkSocket::Message(Me) << "METADATA " << u->nick << " cloakhost :" << vhost;
+ Uplink::Send(Me, "METADATA", u->nick, "cloakhost", vhost);
if (!u->HasMode("CLOAK"))
{
u->SetMode(Config->GetClient("HostServ"), "CLOAK");
@@ -163,14 +174,16 @@ class ngIRCdProto : public IRCDProto
}
}
- void SendVhostDel(User *u) anope_override
+ void SendVhostDel(User *u) override
{
this->SendVhost(u, u->GetIdent(), "");
}
- Anope::string Format(const Anope::string &source, const Anope::string &message) anope_override
+ Anope::string Format(IRCMessage &message)
{
- return IRCDProto::Format(source.empty() ? Me->GetSID() : source, message);
+ if (message.GetSource().GetSource().empty())
+ message.SetSource(Me);
+ return IRCDProto::Format(message);
}
};
@@ -179,7 +192,7 @@ struct IRCDMessage005 : IRCDMessage
IRCDMessage005(Module *creator) : IRCDMessage(creator, "005", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
// Please see <http://www.irc.org/tech_docs/005.html> for details.
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
size_t pos;
Anope::string parameter, data;
@@ -220,7 +233,7 @@ struct IRCDMessage376 : IRCDMessage
*
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
}
};
@@ -246,7 +259,7 @@ struct IRCDMessageChaninfo : IRCDMessage
* a channel has no user limit (the parameter <modes> doesn't list the "l"
* channel mode). In this case <limit> should be "0".
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
bool created;
Channel *c = Channel::FindOrCreate(params[0], created);
@@ -288,7 +301,7 @@ struct IRCDMessageJoin : Message::Join
*
* if a user joins a new channel, the ircd sends <channelname>\7<umode>
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *user = source.GetUser();
size_t pos = params[0].find('\7');
@@ -338,7 +351,7 @@ struct IRCDMessageMetadata : IRCDMessage
* - "user": the user name (ident) of a client (can't be empty)
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = User::Find(params[0]);
if (!u)
@@ -348,14 +361,14 @@ struct IRCDMessageMetadata : IRCDMessage
}
if (params[1].equals_cs("accountname"))
{
- NickCore *nc = NickCore::Find(params[2]);
+ NickServ::Account *nc = NickServ::FindAccount(params[2]);
if (nc)
u->Login(nc);
}
else if (params[1].equals_cs("certfp"))
{
u->fingerprint = params[2];
- FOREACH_MOD(OnFingerprint, (u));
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
}
else if (params[1].equals_cs("cloakhost"))
{
@@ -389,7 +402,7 @@ struct IRCDMessageMode : IRCDMessage
* params[n] = parameters
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Anope::string modes = params[1];
@@ -436,7 +449,7 @@ struct IRCDMessageNick : IRCDMessage
* params[0] = newnick
*
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params.size() == 1)
{
@@ -477,7 +490,7 @@ struct IRCDMessageNJoin : IRCDMessage
*
* Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP,%test,+test2
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
std::list<Message::Join::SJoinUser> users;
@@ -502,7 +515,7 @@ struct IRCDMessageNJoin : IRCDMessage
continue;
}
users.push_back(sju);
- }
+ }
Message::Join::SJoin(source, params[0], 0, "", users);
}
@@ -517,7 +530,7 @@ struct IRCDMessagePong : IRCDMessage
* when receiving a new server and then finish sync once we
* get a pong back from that server.
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (!source.GetServer()->IsSynced())
source.GetServer()->Sync(false);
@@ -553,7 +566,7 @@ struct IRCDMessageServer : IRCDMessage
* params[3] = server description
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params.size() == 3)
{
@@ -580,7 +593,7 @@ struct IRCDMessageTopic : IRCDMessage
IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
// Received: :DukeP TOPIC #anope :test
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Channel *c = Channel::Find(params[0]);
if (!c)
@@ -595,6 +608,7 @@ struct IRCDMessageTopic : IRCDMessage
class ProtongIRCd : public Module
+ , public EventHook<Event::UserNickChange>
{
ngIRCdProto ircd_proto;
@@ -629,71 +643,46 @@ class ProtongIRCd : public Module
IRCDMessageServer message_server;
IRCDMessageTopic message_topic;
- void AddModes()
- {
- /* Add user modes */
- ModeManager::AddUserMode(new UserMode("NOCTCP", 'b'));
- ModeManager::AddUserMode(new UserMode("BOT", 'B'));
- ModeManager::AddUserMode(new UserMode("COMMONCHANS", 'C'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserModeOperOnly("PROTECTED", 'q'));
- ModeManager::AddUserMode(new UserModeOperOnly("RESTRICTED", 'r'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
-
- /* Add modes for ban, exception, and invite lists */
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
-
- /* Add channel user modes */
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3));
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4));
-
- /* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- ModeManager::AddChannelMode(new ChannelMode("OPERONLY", 'O'));
- ModeManager::AddChannelMode(new ChannelMode("PERM", 'P'));
- ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q'));
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V'));
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'z'));
- }
-
public:
- ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_capab(this), message_error(this), message_invite(this), message_kick(this), message_kill(this),
- message_motd(this), message_notice(this), message_part(this), message_ping(this), message_privmsg(this),
- message_squery(this, "SQUERY"), message_quit(this), message_squit(this), message_stats(this), message_time(this),
- message_version(this), message_whois(this),
-
- message_005(this), message_376(this), message_chaninfo(this), message_join(this), message_metadata(this),
- message_mode(this), message_nick(this), message_njoin(this), message_pong(this), message_server(this),
- message_topic(this)
+ ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::UserNickChange>(this)
+ , ircd_proto(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_squery(this, "SQUERY")
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_005(this)
+ , message_376(this)
+ , message_chaninfo(this)
+ , message_join(this)
+ , message_metadata(this)
+ , message_mode(this)
+ , message_nick(this)
+ , message_njoin(this)
+ , message_pong(this)
+ , message_server(this)
+ , message_topic(this)
{
Servers::Capab.insert("QS");
- this->AddModes();
-
}
- void OnUserNickChange(User *u, const Anope::string &) anope_override
+ void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveMode(Config->GetClient("NickServ"), "REGISTERED");
}
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index eeb22d4fe..02d2a4d6e 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -1,24 +1,37 @@
-/* Plexus 3+ IRCD functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+/* Dependencies: anope_protocol.hybrid */
+
#include "module.h"
+#include "modules/protocol/plexus.h"
+#include "modules/protocol/hybrid.h"
static Anope::string UplinkSID;
-static ServiceReference<IRCDProto> hybrid("IRCDProto", "hybrid");
-
class PlexusProto : public IRCDProto
{
+ ServiceReference<IRCDProto> hybrid; // XXX use moddeps + inheritance here
+
public:
PlexusProto(Module *creator) : IRCDProto(creator, "hybrid-7.2.3+plexus-3.0.1")
+ , hybrid("hybrid")
{
DefaultPseudoclientModes = "+oiU";
CanSVSNick = true;
@@ -34,28 +47,28 @@ class PlexusProto : public IRCDProto
MaxModes = 4;
}
- void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) anope_override { hybrid->SendSVSKillInternal(source, targ, reason); }
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); }
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
- void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); }
- void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); }
- void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); }
- void SendSGLine(User *u, const XLine *x) anope_override { hybrid->SendSGLine(u, x); }
- void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); }
- void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); }
- void SendServer(const Server *server) anope_override { hybrid->SendServer(server); }
- void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); }
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); }
- void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); }
-
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) override { hybrid->SendSVSKillInternal(source, targ, reason); }
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { hybrid->SendGlobalNotice(bi, dest, msg); }
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
+ void SendSQLine(User *u, XLine *x) override { hybrid->SendSQLine(u, x); }
+ void SendSQLineDel(XLine *x) override { hybrid->SendSQLineDel(x); }
+ void SendSGLineDel(XLine *x) override { hybrid->SendSGLineDel(x); }
+ void SendSGLine(User *u, XLine *x) override { hybrid->SendSGLine(u, x); }
+ void SendAkillDel(XLine *x) override { hybrid->SendAkillDel(x); }
+ void SendAkill(User *u, XLine *x) override { hybrid->SendAkill(u, x); }
+ void SendServer(const Server *server) override { hybrid->SendServer(server); }
+ void SendChannel(Channel *c) override { hybrid->SendChannel(c); }
+ void SendSVSHold(const Anope::string &nick, time_t t) override { hybrid->SendSVSHold(nick, t); }
+ void SendSVSHoldDel(const Anope::string &nick) override { hybrid->SendSVSHoldDel(nick); }
+
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "OPERWALL :" << buf;
+ Uplink::Send(source, "OPERWALL", buf);
}
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override
{
- UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :" << user->GetUID();
+ Uplink::Send(Me, "SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), user->GetUID());
if (status)
{
/* First save the channel status incase uc->Status == status */
@@ -67,7 +80,7 @@ class PlexusProto : public IRCDProto
if (uc != NULL)
uc->status.Clear();
- BotInfo *setter = BotInfo::Find(user->GetUID());
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
@@ -76,27 +89,28 @@ class PlexusProto : public IRCDProto
}
}
- void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override
+ void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override
{
- UplinkSocket::Message(Me) << "ENCAP " << u->server->GetName() << " SVSNICK " << u->GetUID() << " " << u->timestamp << " " << newnick << " " << when;
+ Uplink::Send(Me, "ENCAP", u->server->GetName(), "SVSNICK", u->GetUID(), u->timestamp, newnick, when);
}
- void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) anope_override
+ void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override
{
if (!ident.empty())
- UplinkSocket::Message(Me) << "ENCAP * CHGIDENT " << u->GetUID() << " " << ident;
- UplinkSocket::Message(Me) << "ENCAP * CHGHOST " << u->GetUID() << " " << host;
+ Uplink::Send(Me, "ENCAP", "*", "CHGIDENT", u->GetUID(), ident);
+ Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host);
u->SetMode(Config->GetClient("HostServ"), "CLOAK");
}
- void SendVhostDel(User *u) anope_override
+ void SendVhostDel(User *u) override
{
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK");
}
- void SendConnect() anope_override
+ void SendConnect() override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
+
/* CAPAB
* QS - Can handle quit storm removal
* EX - Can do channel +e exemptions
@@ -117,9 +131,11 @@ class PlexusProto : public IRCDProto
* ENCAP - Supports encapsulization of protocol messages
* SVS - Supports services protocol extensions
*/
- UplinkSocket::Message() << "CAPAB :QS EX CHW IE EOB KLN UNKLN GLN HUB KNOCK TBURST PARA ENCAP SVS";
+ Uplink::Send("CAPAB", "QS EX CHW IE EOB KLN UNKLN GLN HUB KNOCK TBURST PARA ENCAP SVS");
+
/* Make myself known to myself in the serverlist */
SendServer(Me);
+
/*
* SVINFO
* parv[0] = sender prefix
@@ -128,163 +144,148 @@ class PlexusProto : public IRCDProto
* parv[3] = server is standalone or connected to non-TS only
* parv[4] = server's idea of UTC time
*/
- UplinkSocket::Message() << "SVINFO 6 5 0 :" << Anope::CurTime;
+ Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 255.255.255.255 " << u->GetUID() << " 0 " << u->host << " :" << u->realname;
+ Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "255.255.255.255", u->GetUID(), 0, u->host, u->realname);
}
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "ENCAP * SVSMODE " << u->GetUID() << " " << u->timestamp << " " << buf;
+ Uplink::Send(source, "ENCAP", "*", "SVSMODE", u->GetUID(), u->timestamp, buf);
}
- void SendLogin(User *u, NickAlias *na) anope_override
+ void SendLogin(User *u, NickServ::Nick *na) override
{
- UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID() << " " << na->nc->display;
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay());
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
- UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID();
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), "");
}
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- UplinkSocket::Message(source) << "ENCAP * TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
+ Uplink::Send(source, "ENCAP", "*", "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
}
- void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
+ void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
{
- UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSJOIN " << user->GetUID() << " " << chan;
+ Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSJOIN", user->GetUID(), chan);
}
- void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
+ void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
{
- UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSPART " << user->GetUID() << " " << chan;
+ Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSPART", user->GetUID(), chan);
}
};
-struct IRCDMessageEncap : IRCDMessage
+void plexus::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ /*
+ * Received: :dev.anope.de ENCAP * SU DukePyrolator DukePyrolator
+ * params[0] = *
+ * params[1] = SU
+ * params[2] = nickname
+ * params[3] = account
+ */
+ if (params[1].equals_cs("SU"))
{
- /*
- * Received: :dev.anope.de ENCAP * SU DukePyrolator DukePyrolator
- * params[0] = *
- * params[1] = SU
- * params[2] = nickname
- * params[3] = account
- */
- if (params[1].equals_cs("SU"))
+ User *u = User::Find(params[2]);
+ NickServ::Account *nc = NickServ::FindAccount(params[3]);
+ if (u && nc)
{
- User *u = User::Find(params[2]);
- NickCore *nc = NickCore::Find(params[3]);
- if (u && nc)
- {
- u->Login(nc);
- }
+ u->Login(nc);
}
+ }
- /*
- * Received: :dev.anope.de ENCAP * CERTFP DukePyrolator :3F122A9CC7811DBAD3566BF2CEC3009007C0868F
- * params[0] = *
- * params[1] = CERTFP
- * params[2] = nickname
- * params[3] = fingerprint
- */
- else if (params[1].equals_cs("CERTFP"))
+ /*
+ * Received: :dev.anope.de ENCAP * CERTFP DukePyrolator :3F122A9CC7811DBAD3566BF2CEC3009007C0868F
+ * params[0] = *
+ * params[1] = CERTFP
+ * params[2] = nickname
+ * params[3] = fingerprint
+ */
+ else if (params[1].equals_cs("CERTFP"))
+ {
+ User *u = User::Find(params[2]);
+ if (u)
{
- User *u = User::Find(params[2]);
- if (u)
- {
- u->fingerprint = params[3];
- FOREACH_MOD(OnFingerprint, (u));
- }
+ u->fingerprint = params[3];
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
}
- return;
}
-};
+ return;
+}
struct IRCDMessagePass : IRCDMessage
{
IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
UplinkSID = params[3];
}
};
-struct IRCDMessageServer : IRCDMessage
+/* 0 1 2 */
+/* SERVER hades.arpa 1 :ircd-hybrid test server */
+void plexus::Server::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- /* 0 1 2 */
- /* SERVER hades.arpa 1 :ircd-hybrid test server */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* Servers other than our immediate uplink are introduced via SID */
- if (params[1] != "1")
- return;
-
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- }
-};
+ /* Servers other than our immediate uplink are introduced via SID */
+ if (params[1] != "1")
+ return;
-struct IRCDMessageUID : IRCDMessage
+ new ::Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
+}
+
+/*
+ params[0] = nick
+ params[1] = hop
+ params[2] = ts
+ params[3] = modes
+ params[4] = user
+ params[5] = host
+ params[6] = IP
+ params[7] = UID
+ params[8] = services stamp
+ params[9] = realhost
+ params[10] = info
+*/
+// :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB 0 192.168.0.5 :Adam
+void plexus::UID::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ /* An IP of 0 means the user is spoofed */
+ Anope::string ip = params[6];
+ if (ip == "0")
+ ip.clear();
- /*
- params[0] = nick
- params[1] = hop
- params[2] = ts
- params[3] = modes
- params[4] = user
- params[5] = host
- params[6] = IP
- params[7] = UID
- params[8] = services stamp
- params[9] = realhost
- params[10] = info
- */
- // :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB 0 192.168.0.5 :Adam
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ time_t ts;
+ try
{
- /* An IP of 0 means the user is spoofed */
- Anope::string ip = params[6];
- if (ip == "0")
- ip.clear();
-
- time_t ts;
- try
- {
- ts = convertTo<time_t>(params[2]);
- }
- catch (const ConvertException &)
- {
- ts = Anope::CurTime;
- }
-
- NickAlias *na = NULL;
- try
- {
- if (params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == ts)
- na = NickAlias::Find(params[0]);
- }
- catch (const ConvertException &) { }
- if (params[8] != "0" && !na)
- na = NickAlias::Find(params[8]);
+ ts = convertTo<time_t>(params[2]);
+ }
+ catch (const ConvertException &)
+ {
+ ts = Anope::CurTime;
+ }
- User::OnIntroduce(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? *na->nc : NULL);
+ NickServ::Nick *na = NULL;
+ try
+ {
+ if (params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == ts)
+ na = NickServ::FindNick(params[0]);
}
-};
+ catch (const ConvertException &) { }
+ if (params[8] != "0" && !na)
+ na = NickServ::FindNick(params[8]);
+
+ User::OnIntroduce(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? na->GetAccount() : NULL);
+}
class ProtoPlexus : public Module
{
@@ -312,108 +313,63 @@ class ProtoPlexus : public Module
Message::Topic message_topic;
Message::Version message_version;
Message::Whois message_whois;
-
- /* Hybrid message handlers */
- ServiceAlias message_bmask, message_eob, message_join, message_nick, message_sid, message_sjoin,
- message_tburst, message_tmode;
/* Our message handlers */
- IRCDMessageEncap message_encap;
+ hybrid::BMask message_bmask;
+ hybrid::EOB message_eob;
+ plexus::Encap message_encap;
+ hybrid::Join message_join;
+ hybrid::Nick message_nick;
IRCDMessagePass message_pass;
- IRCDMessageServer message_server;
- IRCDMessageUID message_uid;
-
- void AddModes()
- {
- /* Add user modes */
- ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a'));
- ModeManager::AddUserMode(new UserMode("NOCTCP", 'C'));
- ModeManager::AddUserMode(new UserMode("DEAF", 'D'));
- ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G'));
- ModeManager::AddUserMode(new UserMode("CALLERID", 'g'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N'));
- ModeManager::AddUserMode(new UserMode("PRIV", 'p'));
- ModeManager::AddUserMode(new UserModeOperOnly("ROUTING", 'q'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserModeNoone("SSL", 'S'));
- ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'U'));
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserModeNoone("WEBIRC", 'W'));
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z'));
-
- /* b/e/I */
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
-
- /* v/h/o/a/q */
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3));
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4));
-
- /* l/k */
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
-
- /* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode("BANDWIDTH", 'B'));
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'N'));
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'S'));
- ModeManager::AddChannelMode(new ChannelMode("PERM", 'z'));
- }
+ plexus::Server message_server;
+ hybrid::SID message_sid;
+ hybrid::SJoin message_sjoin;
+ hybrid::TBurst message_tburst;
+ hybrid::TMode message_tmode;
+ plexus::UID message_uid;
public:
- ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), message_kill(this),
- message_mode(this), message_motd(this), message_notice(this), message_part(this), message_ping(this), message_privmsg(this),
- message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), message_version(this),
- message_whois(this),
-
- message_bmask("IRCDMessage", "plexus/bmask", "hybrid/bmask"), message_eob("IRCDMessage", "plexus/eob", "hybrid/eob"),
- message_join("IRCDMessage", "plexus/join", "hybrid/join"), message_nick("IRCDMessage", "plexus/nick", "hybrid/nick"),
- message_sid("IRCDMessage", "plexus/sid", "hybrid/sid"),
- message_sjoin("IRCDMessage", "plexus/sjoin", "hybrid/sjoin"), message_tburst("IRCDMessage", "plexus/tburst", "hybrid/tburst"),
- message_tmode("IRCDMessage", "plexus/tmode", "hybrid/tmode"),
-
- message_encap(this), message_pass(this), message_server(this), message_uid(this)
+ ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_mode(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_topic(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_bmask(this)
+ , message_eob(this)
+ , message_encap(this)
+ , message_join(this)
+ , message_nick(this)
+ , message_pass(this)
+ , message_server(this)
+ , message_sid(this)
+ , message_sjoin(this)
+ , message_tburst(this)
+ , message_tmode(this)
+ , message_uid(this)
{
-
- if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK)
- throw ModuleException("Unable to load hybrid");
- m_hybrid = ModuleManager::FindModule("hybrid");
- if (!m_hybrid)
- throw ModuleException("Unable to find hybrid");
- if (!hybrid)
- throw ModuleException("No protocol interface for hybrid");
-
- this->AddModes();
- }
-
- ~ProtoPlexus()
- {
- m_hybrid = ModuleManager::FindModule("hybrid");
- ModuleManager::UnloadModule(m_hybrid, NULL);
}
};
+template<> void ModuleInfo<ProtoPlexus>(ModuleDef *def)
+{
+ def->Depends("hybrid");
+}
+
MODULE_INIT(ProtoPlexus)
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index d89bff602..223902457 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -1,24 +1,36 @@
-/* Ratbox IRCD functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2005-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
+/* Dependencies: anope_protocol.hybrid */
+
#include "module.h"
+#include "modules/protocol/hybrid.h"
+#include "modules/protocol/ratbox.h"
static Anope::string UplinkSID;
-static ServiceReference<IRCDProto> hybrid("IRCDProto", "hybrid");
-
class RatboxProto : public IRCDProto
{
+ ServiceReference<IRCDProto> hybrid; // XXX
public:
RatboxProto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+")
+ , hybrid("hybrid")
{
DefaultPseudoclientModes = "+oiS";
CanSNLine = true;
@@ -28,29 +40,30 @@ class RatboxProto : public IRCDProto
MaxModes = 4;
}
- void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) anope_override { hybrid->SendSVSKillInternal(source, targ, reason); }
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); }
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
- void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); }
- void SendSGLine(User *u, const XLine *x) anope_override { hybrid->SendSGLine(u, x); }
- void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); }
- void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); }
- void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); }
- void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); }
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); }
- void SendServer(const Server *server) anope_override { hybrid->SendServer(server); }
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override { hybrid->SendModeInternal(source, u, buf); }
- void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); }
- bool IsIdentValid(const Anope::string &ident) anope_override { return hybrid->IsIdentValid(ident); }
-
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) override { hybrid->SendSVSKillInternal(source, targ, reason); }
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { hybrid->SendGlobalNotice(bi, dest, msg); }
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
+ void SendSQLine(User *u, XLine *x) override { hybrid->SendSQLine(u, x); }
+ void SendSGLine(User *u, XLine *x) override { hybrid->SendSGLine(u, x); }
+ void SendSGLineDel(XLine *x) override { hybrid->SendSGLineDel(x); }
+ void SendAkill(User *u, XLine *x) override { hybrid->SendAkill(u, x); }
+ void SendAkillDel(XLine *x) override { hybrid->SendAkillDel(x); }
+ void SendSQLineDel(XLine *x) override { hybrid->SendSQLineDel(x); }
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override { hybrid->SendJoin(user, c, status); }
+ void SendServer(const Server *server) override { hybrid->SendServer(server); }
+ void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) override { hybrid->SendModeInternal(source, u, buf); }
+ void SendChannel(Channel *c) override { hybrid->SendChannel(c); }
+ bool IsIdentValid(const Anope::string &ident) override { return hybrid->IsIdentValid(ident); }
+
+ void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "OPERWALL :" << buf;
+ Uplink::Send(source, "OPERWALL", buf);
}
- void SendConnect() anope_override
+ void SendConnect() override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
+
/*
QS - Can handle quit storm removal
EX - Can do channel +e exemptions
@@ -61,9 +74,11 @@ class RatboxProto : public IRCDProto
TB - supports topic burst
ENCAP - supports ENCAP
*/
- UplinkSocket::Message() << "CAPAB :QS EX CHW IE GLN TB ENCAP";
+ Uplink::Send("CAPAB", "QS EX CHW IE GLN TB ENCAP");
+
/* Make myself known to myself in the serverlist */
SendServer(Me);
+
/*
* SVINFO
* parv[0] = sender prefix
@@ -72,31 +87,31 @@ class RatboxProto : public IRCDProto
* parv[3] = server is standalone or connected to non-TS only
* parv[4] = server's idea of UTC time
*/
- UplinkSocket::Message() << "SVINFO 6 3 0 :" << Anope::CurTime;
+ Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " :" << u->realname;
+ Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), u->realname);
}
- void SendLogin(User *u, NickAlias *na) anope_override
+ void SendLogin(User *u, NickServ::Nick *na) override
{
- if (na->nc->HasExt("UNCONFIRMED"))
+ if (na->GetAccount()->HasFieldS("UNCONFIRMED"))
return;
- UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID() << " " << na->nc->display;
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay());
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
- UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID();
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID());
}
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- BotInfo *bi = source.GetBot();
+ ServiceBot *bi = source.GetBot();
bool needjoin = c->FindUser(bi) == NULL;
if (needjoin)
@@ -114,116 +129,89 @@ class RatboxProto : public IRCDProto
}
};
-struct IRCDMessageEncap : IRCDMessage
+// Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam
+void ratbox::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 3) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- // Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ if (params[1] == "LOGIN" || params[1] == "SU")
{
- if (params[1] == "LOGIN" || params[1] == "SU")
- {
- User *u = source.GetUser();
-
- NickCore *nc = NickCore::Find(params[2]);
- if (!nc)
- return;
- u->Login(nc);
-
- /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if
- * their server isn't syncing) and then we receive this.. so tell them about it.
- */
- if (u->server->IsSynced())
- u->SendMessage(Config->GetClient("NickServ"), _("You have been logged in as \002%s\002."), nc->display.c_str());
- }
+ User *u = source.GetUser();
+
+ NickServ::Account *nc = NickServ::FindAccount(params[2]);
+ if (!nc)
+ return;
+ u->Login(nc);
+
+ /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if
+ * their server isn't syncing) and then we receive this.. so tell them about it.
+ */
+ if (u->server->IsSynced())
+ u->SendMessage(Config->GetClient("NickServ"), _("You have been logged in as \002%s\002."), nc->GetDisplay().c_str());
}
-};
+}
-struct IRCDMessageJoin : Message::Join
+void ratbox::Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageJoin(Module *creator) : Message::Join(creator, "JOIN") { }
+ if (params.size() == 1 && params[0] == "0")
+ return Message::Join::Run(source, params);
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.size() == 1 && params[0] == "0")
- return Message::Join::Run(source, params);
-
- if (params.size() < 2)
- return;
+ if (params.size() < 2)
+ return;
- std::vector<Anope::string> p = params;
- p.erase(p.begin());
+ std::vector<Anope::string> p = params;
+ p.erase(p.begin());
- return Message::Join::Run(source, p);
- }
-};
+ return Message::Join::Run(source, p);
+}
struct IRCDMessagePass : IRCDMessage
{
IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
UplinkSID = params[3];
}
};
-struct IRCDMessageServer : IRCDMessage
+// SERVER hades.arpa 1 :ircd-ratbox test server
+void ratbox::Server::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- // SERVER hades.arpa 1 :ircd-ratbox test server
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- // Servers other then our immediate uplink are introduced via SID
- if (params[1] != "1")
- return;
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
-
-struct IRCDMessageTBurst : IRCDMessage
+ // Servers other then our immediate uplink are introduced via SID
+ if (params[1] != "1")
+ return;
+ new ::Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
+ IRCD->SendPing(Me->GetName(), params[0]);
+}
+
+/*
+ * params[0] = channel
+ * params[1] = ts
+ * params[2] = topic OR who set the topic
+ * params[3] = topic if params[2] isn't the topic
+ */
+void ratbox::TB::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageTBurst(Module *creator) : IRCDMessage(creator, "TB", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- /*
- * params[0] = channel
- * params[1] = ts
- * params[2] = topic OR who set the topic
- * params[3] = topic if params[2] isn't the topic
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- time_t topic_time = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
- Channel *c = Channel::Find(params[0]);
+ time_t topic_time = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
+ Channel *c = Channel::Find(params[0]);
- if (!c)
- return;
+ if (!c)
+ return;
- const Anope::string &setter = params.size() == 4 ? params[2] : "",
- topic = params.size() == 4 ? params[3] : params[2];
+ const Anope::string &setter = params.size() == 4 ? params[2] : "",
+ topic = params.size() == 4 ? params[3] : params[2];
- c->ChangeTopicInternal(NULL, setter, topic, topic_time);
- }
-};
+ c->ChangeTopicInternal(NULL, setter, topic, topic_time);
+}
-struct IRCDMessageUID : IRCDMessage
+// :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB :Adam
+void ratbox::UID::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 9) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- // :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB :Adam
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- /* Source is always the server */
- User::OnIntroduce(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL);
- }
-};
+ /* Source is always the server */
+ User::OnIntroduce(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL);
+}
class ProtoRatbox : public Module
{
- Module *m_hybrid;
-
RatboxProto ircd_proto;
/* Core message handlers */
@@ -247,98 +235,62 @@ class ProtoRatbox : public Module
Message::Version message_version;
Message::Whois message_whois;
- /* Hybrid message handlers */
- ServiceAlias message_bmask, message_nick, message_pong, message_sid,
- message_sjoin, message_tmode;
-
/* Our message handlers */
- IRCDMessageEncap message_encap;
- IRCDMessageJoin message_join;
+ hybrid::BMask message_bmask;
+ ratbox::Encap message_encap;
+ ratbox::Join message_join;
+ hybrid::Nick message_nick;
IRCDMessagePass message_pass;
- IRCDMessageServer message_server;
- IRCDMessageTBurst message_tburst;
- IRCDMessageUID message_uid;
-
- void AddModes()
- {
- /* user modes */
- ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a'));
- ModeManager::AddUserMode(new UserModeOperOnly("BOT", 'b'));
- // c/C = con
- // d = debug?
- ModeManager::AddUserMode(new UserMode("DEAF", 'D'));
- // f = full?
- ModeManager::AddUserMode(new UserMode("CALLERID", 'g'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- // k = skill?
- ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l'));
- // n = nchange
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- // r = rej
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'S'));
- // u = unauth?
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- // x = external?
- // y = spy?
- ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z'));
- // Z = spy?
-
- /* b/e/I */
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
-
- /* v/h/o/a/q */
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1));
-
- /* l/k */
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
-
- /* channel modes */
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'r'));
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'S'));
- }
+ hybrid::Pong message_pong;
+ ratbox::Server message_server;
+ hybrid::SID message_sid;
+ hybrid::SJoin message_sjoin;
+ ratbox::TB message_tb;
+ hybrid::TMode message_tmode;
+ ratbox::UID message_uid;
public:
- ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this),
- message_kill(this), message_mode(this), message_motd(this), message_notice(this), message_part(this),
- message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), message_stats(this),
- message_time(this), message_topic(this), message_version(this), message_whois(this),
-
- message_bmask("IRCDMessage", "ratbox/bmask", "hybrid/bmask"), message_nick("IRCDMessage", "ratbox/nick", "hybrid/nick"),
- message_pong("IRCDMessage", "ratbox/pong", "hybrid/pong"), message_sid("IRCDMessage", "ratbox/sid", "hybrid/sid"),
- message_sjoin("IRCDMessage", "ratbox/sjoin", "hybrid/sjoin"), message_tmode("IRCDMessage", "ratbox/tmode", "hybrid/tmode"),
-
- message_encap(this), message_join(this), message_pass(this), message_server(this), message_tburst(this), message_uid(this)
- {
-
- if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK)
- throw ModuleException("Unable to load hybrid");
- m_hybrid = ModuleManager::FindModule("hybrid");
- if (!m_hybrid)
- throw ModuleException("Unable to find hybrid");
- if (!hybrid)
- throw ModuleException("No protocol interface for hybrid");
-
- this->AddModes();
- }
-
- ~ProtoRatbox()
+ ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_capab(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_mode(this)
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_topic(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_bmask(this)
+ , message_encap(this)
+ , message_join(this)
+ , message_nick(this)
+ , message_pass(this)
+ , message_pong(this)
+ , message_server(this)
+ , message_sid(this)
+ , message_sjoin(this)
+ , message_tb(this)
+ , message_tmode(this)
+ , message_uid(this)
{
- m_hybrid = ModuleManager::FindModule("hybrid");
- ModuleManager::UnloadModule(m_hybrid, NULL);
}
};
+template<> void ModuleInfo<ProtoRatbox>(ModuleDef *def)
+{
+ def->Depends("hybrid");
+}
+
MODULE_INIT(ProtoRatbox)
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index cff2f440b..d805e60cb 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -1,22 +1,33 @@
-/* Unreal IRCD 3.2.x functions
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
-#include "modules/cs_mode.h"
+#include "modules/chanserv/mode.h"
#include "modules/sasl.h"
+#include "modules/operserv/stats.h"
+
+static Anope::string UplinkSID;
class UnrealIRCdProto : public IRCDProto
{
public:
- UnrealIRCdProto(Module *creator) : IRCDProto(creator, "UnrealIRCd 3.2.x")
+ UnrealIRCdProto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4")
{
DefaultPseudoclientModes = "+Soiq";
CanSVSNick = true;
@@ -27,18 +38,19 @@ class UnrealIRCdProto : public IRCDProto
CanSQLine = true;
CanSZLine = true;
CanSVSHold = true;
- CanSVSO = true;
+ CanCertFP = true;
+ RequiresID = true;
MaxModes = 12;
}
private:
/* SVSNOOP */
- void SendSVSNOOP(const Server *server, bool set) anope_override
+ void SendSVSNOOP(const Server *server, bool set) override
{
- UplinkSocket::Message() << "SVSNOOP " << server->GetName() << " " << (set ? "+" : "-");
+ Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-");
}
- void SendAkillDel(const XLine *x) anope_override
+ void SendAkillDel(XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
return;
@@ -54,34 +66,34 @@ class UnrealIRCdProto : public IRCDProto
}
}
- UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by;
+ Uplink::Send("TKL", "-", "G", x->GetUser(), x->GetHost(), x->GetBy());
}
- void SendTopic(const MessageSource &source, Channel *c) anope_override
+ void SendTopic(const MessageSource &source, Channel *c) override
{
- UplinkSocket::Message(source) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
+ Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
}
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalNotice(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
}
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ void SendGlobalPrivmsg(ServiceBot *bi, const Server *dest, const Anope::string &msg) override
{
- UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
}
- void SendVhostDel(User *u) anope_override
+ void SendVhostDel(User *u) override
{
- BotInfo *HostServ = Config->GetClient("HostServ");
+ ServiceBot *HostServ = Config->GetClient("HostServ");
u->RemoveMode(HostServ, "CLOAK");
u->RemoveMode(HostServ, "VHOST");
ModeManager::ProcessModes();
u->SetMode(HostServ, "CLOAK");
}
- void SendAkill(User *u, XLine *x) anope_override
+ void SendAkill(User *u, XLine *x) override
{
if (x->IsRegex() || x->HasNickOrReal())
{
@@ -89,22 +101,28 @@ class UnrealIRCdProto : public IRCDProto
{
/* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->manager->Check(it->second, x))
+ if (x->GetManager()->Check(it->second, x))
this->SendAkill(it->second, x);
return;
}
- const XLine *old = x;
+ XLine *old = x;
- if (old->manager->HasEntry("*@" + u->host))
+ if (old->GetManager()->HasEntry("*@" + u->host))
return;
/* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- XLine *xline = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
- old->manager->AddXLine(xline);
- x = xline;
+ XLine *xl = Serialize::New<XLine *>();
+ xl->SetMask("*@" + u->host);
+ xl->SetBy(old->GetBy());
+ xl->SetExpires(old->GetExpires());
+ xl->SetReason(old->GetReason());
+ xl->SetID(old->GetID());
+
+ old->GetManager()->AddXLine(xl);
+ x = xl;
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
+ Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask();
}
/* ZLine if we can instead */
@@ -119,43 +137,45 @@ class UnrealIRCdProto : public IRCDProto
}
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- UplinkSocket::Message() << "TKL + G " << x->GetUser() << " " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
+ Uplink::Send("TKL", "+", "G", x->GetUser(), x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason());
}
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "SVSKILL " << user->nick << " :" << buf;
+ Uplink::Send(source, "SVSKILL", user->GetUID(), buf);
user->KillInternal(source, buf);
}
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
+ void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) override
{
- UplinkSocket::Message(source) << "SVS2MODE " << u->nick <<" " << buf;
+ IRCMessage message(source, "SVS2MODE", u->GetUID());
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
- void SendClientIntroduction(User *u) anope_override
+ void SendClientIntroduction(User *u) override
{
Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message() << "NICK " << u->nick << " 1 " << u->timestamp << " " << u->GetIdent() << " " << u->host << " " << u->server->GetName() << " 0 " << modes << " " << u->host << " * :" << u->realname;
+ Uplink::Send("UID", u->nick, 1, u->timestamp, u->GetIdent(), u->host, u->GetUID(), "*", modes, !u->vhost.empty() ? u->vhost : "*", !u->chost.empty() ? u->chost : "*", "*", u->realname);
}
/* SERVER name hop descript */
/* Unreal 3.2 actually sends some info about itself in the descript area */
- void SendServer(const Server *server) anope_override
+ void SendServer(const Server *server) override
{
if (!server->GetSID().empty() && server == Me)
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << server->GetSID() << " " << server->GetDescription();
+ Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription());
else
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
+ Uplink::Send("SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
}
/* JOIN */
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) override
{
- UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->nick;
+ Uplink::Send(Me, "SJOIN", c->creation_time, c->name, user->GetUID());
if (status)
{
/* First save the channel status incase uc->Status == status */
@@ -167,7 +187,7 @@ class UnrealIRCdProto : public IRCDProto
if (uc != NULL)
uc->status.Clear();
- BotInfo *setter = BotInfo::Find(user->GetUID());
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
for (size_t i = 0; i < cs.Modes().length(); ++i)
c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
@@ -178,9 +198,9 @@ class UnrealIRCdProto : public IRCDProto
/* unsqline
*/
- void SendSQLineDel(const XLine *x) anope_override
+ void SendSQLineDel(XLine *x) override
{
- UplinkSocket::Message() << "UNSQLINE " << x->mask;
+ Uplink::Send("UNSQLINE", x->GetMask());
}
/* SQLINE */
@@ -188,103 +208,88 @@ class UnrealIRCdProto : public IRCDProto
** - Unreal will translate this to TKL for us
**
*/
- void SendSQLine(User *, const XLine *x) anope_override
+ void SendSQLine(User *, XLine *x) override
{
- UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
- }
-
- /*
- ** svso
- ** parv[0] = sender prefix
- ** parv[1] = nick
- ** parv[2] = options
- */
- void SendSVSO(BotInfo *source, const Anope::string &nick, const Anope::string &flag) anope_override
- {
- UplinkSocket::Message(source) << "SVSO " << nick << " " << flag;
+ Uplink::Send("SQLINE", x->GetMask(), x->GetReason());
}
/* Functions that use serval cmd functions */
- void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) anope_override
+ void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override
{
if (!vIdent.empty())
- UplinkSocket::Message(Me) << "CHGIDENT " << u->nick << " " << vIdent;
+ Uplink::Send(Me, "CHGIDENT", u->GetUID(), vIdent);
if (!vhost.empty())
- UplinkSocket::Message(Me) << "CHGHOST " << u->nick << " " << vhost;
+ Uplink::Send(Me, "CHGHOST", u->GetUID(), vhost);
}
- void SendConnect() anope_override
+ void SendConnect() override
{
/*
NICKv2 = Nick Version 2
VHP = Sends hidden host
UMODE2 = sends UMODE2 on user modes
NICKIP = Sends IP on NICK
- TOKEN = Use tokens to talk
SJ3 = Supports SJOIN
NOQUIT = No Quit
TKLEXT = Extended TKL we don't use it but best to have it
- SJB64 = Base64 encoded time stamps
- ESVID = Allows storing account names as services stamp
MLOCK = Supports the MLOCK server command
VL = Version Info
- NS = Config->Numeric Server
+ SID = SID/UID mode
*/
- Anope::string protoctl = "NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL";
- if (!Me->GetSID().empty())
- protoctl += " VL";
- UplinkSocket::Message() << "PROTOCTL " << protoctl;
- UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink].password;
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password);
+ Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID");
+ Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort());
+ Uplink::Send("PROTOCTL", "SID=" + Me->GetSID());
SendServer(Me);
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) override
{
- UplinkSocket::Message() << "TKL + Q H " << nick << " " << Me->GetName() << " " << Anope::CurTime + t << " " << Anope::CurTime << " :Being held for registered user";
+ Uplink::Send("TKL", "+", "Q", "H", nick, Me->GetName(), Anope::CurTime + t, Anope::CurTime, "Being held for registered user");
}
/* SVSHOLD - release */
- void SendSVSHoldDel(const Anope::string &nick) anope_override
+ void SendSVSHoldDel(const Anope::string &nick) override
{
- UplinkSocket::Message() << "TKL - Q * " << nick << " " << Me->GetName();
+ Uplink::Send("TKL", "-", "Q", "*", nick, Me->GetName());
}
/* UNSGLINE */
/*
* SVSNLINE - :realname mask
*/
- void SendSGLineDel(const XLine *x) anope_override
+ void SendSGLineDel(XLine *x) override
{
- UplinkSocket::Message() << "SVSNLINE - :" << x->mask;
+ Uplink::Send("SVSNLINE", "-", x->GetMask());
}
/* UNSZLINE */
- void SendSZLineDel(const XLine *x) anope_override
+ void SendSZLineDel(XLine *x) override
{
- UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << x->by;
+ Uplink::Send("TKL", "-", "Z", "*", x->GetHost(), x->GetBy());
}
/* SZLINE */
- void SendSZLine(User *, const XLine *x) anope_override
+ void SendSZLine(User *, XLine *x) override
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- UplinkSocket::Message() << "TKL + Z * " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
+ Uplink::Send("TKL", "+", "Z", "*", x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason());
}
/* SGLINE */
/*
* SVSNLINE + reason_where_is_space :realname mask with spaces
*/
- void SendSGLine(User *, const XLine *x) anope_override
+ void SendSGLine(User *, XLine *x) override
{
Anope::string edited_reason = x->GetReason();
edited_reason = edited_reason.replace_all_cs(" ", "_");
- UplinkSocket::Message() << "SVSNLINE + " << edited_reason << " :" << x->mask;
+ Uplink::Send("SVSNLINE", "+", edited_reason, x->GetMask());
}
/* svsjoin
@@ -296,33 +301,33 @@ class UnrealIRCdProto : public IRCDProto
/* In older Unreal SVSJOIN and SVSNLINE tokens were mixed so SVSJOIN and SVSNLINE are broken
when coming from a none TOKEN'd server
*/
- void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
+ void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
{
if (!param.empty())
- UplinkSocket::Message(source) << "SVSJOIN " << user->GetUID() << " " << chan << " :" << param;
+ Uplink::Send(source, "SVSJOIN", user->GetUID(), chan, param);
else
- UplinkSocket::Message(source) << "SVSJOIN " << user->GetUID() << " " << chan;
+ Uplink::Send(source, "SVSJOIN", user->GetUID(), chan);
}
- void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
+ void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
{
if (!param.empty())
- UplinkSocket::Message(source) << "SVSPART " << user->GetUID() << " " << chan << " :" << param;
+ Uplink::Send(source, "SVSPART", user->GetUID(), chan, param);
else
- UplinkSocket::Message(source) << "SVSPART " << user->GetUID() << " " << chan;
+ Uplink::Send(source, "SVSPART", user->GetUID(), chan);
}
- void SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) anope_override
+ void SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) override
{
- UplinkSocket::Message(source) << "SWHOIS " << who << " :" << mask;
+ Uplink::Send(source, "SWHOIS", who, mask);
}
- void SendEOB() anope_override
+ void SendEOB() override
{
- UplinkSocket::Message(Me) << "EOS";
+ Uplink::Send(Me, "EOS");
}
- bool IsNickValid(const Anope::string &nick) anope_override
+ bool IsNickValid(const Anope::string &nick) override
{
if (nick.equals_ci("ircd") || nick.equals_ci("irc"))
return false;
@@ -330,7 +335,7 @@ class UnrealIRCdProto : public IRCDProto
return IRCDProto::IsNickValid(nick);
}
- bool IsChannelValid(const Anope::string &chan) anope_override
+ bool IsChannelValid(const Anope::string &chan) override
{
if (chan.find(':') != Anope::string::npos)
return false;
@@ -338,31 +343,31 @@ class UnrealIRCdProto : public IRCDProto
return IRCDProto::IsChannelValid(chan);
}
- bool IsExtbanValid(const Anope::string &mask) anope_override
+ bool IsExtbanValid(const Anope::string &mask) override
{
return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
}
- void SendLogin(User *u, NickAlias *na) anope_override
+ void SendLogin(User *u, NickServ::Nick *na) override
{
/* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */
- if (Servers::Capab.count("ESVID") > 0 && !na->nc->HasExt("UNCONFIRMED"))
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %s", na->nc->display.c_str());
+ if (Servers::Capab.count("ESVID") > 0 && !na->GetAccount()->HasFieldS("UNCONFIRMED"))
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %s", na->GetAccount()->GetDisplay().c_str());
else
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %d", u->signon);
}
- void SendLogout(User *u) anope_override
+ void SendLogout(User *u) override
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0");
}
- void SendChannel(Channel *c) anope_override
+ void SendChannel(Channel *c) override
{
/* Unreal does not support updating a channels TS without actually joining a user,
* so we will join and part us now
*/
- BotInfo *bi = c->ci->WhoSends();
+ ServiceBot *bi = c->ci->WhoSends();
if (!bi)
;
else if (c->FindUser(bi) == NULL)
@@ -377,24 +382,27 @@ class UnrealIRCdProto : public IRCDProto
}
}
- void SendSASLMessage(const SASL::Message &message) anope_override
+ void SendSASLMessage(const SASL::Message &message) override
{
size_t p = message.target.find('!');
if (p == Anope::string::npos)
return;
- UplinkSocket::Message(BotInfo::Find(message.source)) << "SASL " << message.target.substr(0, p) << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : " " + message.ext);
+ if (!message.ext.empty())
+ Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data, message.ext);
+ else
+ Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data);
}
- void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
+ void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override
{
size_t p = uid.find('!');
if (p == Anope::string::npos)
return;
- UplinkSocket::Message(Me) << "SVSLOGIN " << uid.substr(0, p) << " " << uid << " " << acc;
+ Uplink::Send(Me, "SVSLOGIN", uid.substr(0, p), uid, acc);
}
- bool IsIdentValid(const Anope::string &ident) anope_override
+ bool IsIdentValid(const Anope::string &ident) override
{
if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
return false;
@@ -426,13 +434,13 @@ class UnrealExtBan : public ChannelModeVirtual<ChannelModeList>
{
}
- ChannelMode *Wrap(Anope::string &param) anope_override
+ ChannelMode *Wrap(Anope::string &param) override
{
param = "~" + Anope::string(ext) + ":" + param;
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
}
- ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_override
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) override
{
if (cm->type != MODE_LIST || param.length() < 4 || param[0] != '~' || param[1] != ext || param[2] != ':')
return cm;
@@ -451,7 +459,7 @@ namespace UnrealExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string channel = mask.substr(3);
@@ -486,7 +494,7 @@ namespace UnrealExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
@@ -502,7 +510,7 @@ namespace UnrealExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
@@ -518,7 +526,7 @@ namespace UnrealExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
return u->HasMode("REGISTERED") && mask.equals_ci(u->nick);
@@ -532,14 +540,29 @@ namespace UnrealExtban
{
}
- bool Matches(User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
- return u->Account() && Anope::Match(u->Account()->display, real_mask);
+ return u->Account() && Anope::Match(u->Account()->GetDisplay(), real_mask);
}
};
+
+ class FingerprintMatcher : public UnrealExtBan
+ {
+ public:
+ FingerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
+ {
+ }
+
+ bool Matches(User *u, const Entry *e) override
+ {
+ const Anope::string &mask = e->GetMask();
+ Anope::string real_mask = mask.substr(3);
+ return !u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask);
+ }
+ };
}
class ChannelModeFlood : public ChannelModeParam
@@ -548,7 +571,7 @@ class ChannelModeFlood : public ChannelModeParam
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
/* Borrowed part of this check from UnrealIRCd */
- bool IsValid(Anope::string &value) const anope_override
+ bool IsValid(Anope::string &value) const override
{
if (value.empty())
return false;
@@ -559,7 +582,7 @@ class ChannelModeFlood : public ChannelModeParam
return true;
}
catch (const ConvertException &) { }
-
+
/* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
size_t end_bracket = value.find(']', 1);
if (end_bracket == Anope::string::npos)
@@ -600,180 +623,17 @@ class ChannelModeUnrealSSL : public ChannelMode
{
}
- bool CanSet(User *u) const anope_override
+ bool CanSet(User *u) const override
{
return false;
}
};
-struct IRCDMessageCapab : Message::Capab
-{
- IRCDMessageCapab(Module *creator) : Message::Capab(creator, "PROTOCTL") { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- for (unsigned i = 0; i < params.size(); ++i)
- {
- Anope::string capab = params[i];
-
- if (capab.find("CHANMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'b':
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
-
- ModeManager::AddChannelMode(new UnrealExtban::ChannelMatcher("CHANNELBAN", "BAN", 'c'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("JOINBAN", "BAN", 'j'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("NONICKBAN", "BAN", 'n'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("QUIET", "BAN", 'q'));
- ModeManager::AddChannelMode(new UnrealExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r'));
- ModeManager::AddChannelMode(new UnrealExtban::RegisteredMatcher("REGISTEREDBAN", "BAN", 'R'));
- ModeManager::AddChannelMode(new UnrealExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'a'));
- continue;
- case 'e':
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- continue;
- case 'I':
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'k':
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
- continue;
- case 'f':
- ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
- continue;
- case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- continue;
- case 'j':
- ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t], true));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'p':
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- continue;
- case 's':
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- continue;
- case 'm':
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- continue;
- case 'n':
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- continue;
- case 't':
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- continue;
- case 'i':
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- continue;
- case 'r':
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- continue;
- case 'R':
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- continue;
- case 'c':
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- continue;
- case 'O':
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- continue;
- case 'A':
- ModeManager::AddChannelMode(new ChannelModeOperOnly("ADMINONLY", 'A'));
- continue;
- case 'Q':
- ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q'));
- continue;
- case 'K':
- ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K'));
- continue;
- case 'V':
- ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V'));
- continue;
- case 'C':
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- continue;
- case 'u':
- ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u'));
- continue;
- case 'z':
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'z'));
- continue;
- case 'N':
- ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N'));
- continue;
- case 'S':
- ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S'));
- continue;
- case 'M':
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- continue;
- case 'T':
- ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T'));
- continue;
- case 'G':
- ModeManager::AddChannelMode(new ChannelMode("CENSOR", 'G'));
- continue;
- case 'Z':
- ModeManager::AddChannelMode(new ChannelModeUnrealSSL("", 'Z'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelMode("", modebuf[t]));
- }
- }
- }
- }
-
- Message::Capab::Run(source, params);
- }
-};
-
struct IRCDMessageChgHost : IRCDMessage
{
IRCDMessageChgHost(Module *creator) : IRCDMessage(creator, "CHGHOST", 2) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = User::Find(params[0]);
if (u)
@@ -785,7 +645,7 @@ struct IRCDMessageChgIdent : IRCDMessage
{
IRCDMessageChgIdent(Module *creator) : IRCDMessage(creator, "CHGIDENT", 2) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = User::Find(params[0]);
if (u)
@@ -797,7 +657,7 @@ struct IRCDMessageChgName : IRCDMessage
{
IRCDMessageChgName(Module *creator) : IRCDMessage(creator, "CHGNAME", 2) { }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = User::Find(params[0]);
if (u)
@@ -805,11 +665,39 @@ struct IRCDMessageChgName : IRCDMessage
}
};
+struct IRCDMessageMD : IRCDMessage
+{
+ IRCDMessageMD(Module *creator) : IRCDMessage(creator, "MD", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ const Anope::string &mdtype = params[0],
+ &obj = params[1],
+ &var = params[2],
+ &value = params.size() > 3 ? params[3] : "";
+
+ if (mdtype == "client")
+ {
+ User *u = User::Find(obj);
+
+ if (u == nullptr)
+ return;
+
+ if (var == "certfp" && !value.empty())
+ {
+ u->Extend<bool>("ssl", true);
+ u->fingerprint = value;
+ EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u);
+ }
+ }
+ }
+};
+
struct IRCDMessageMode : IRCDMessage
{
IRCDMessageMode(Module *creator, const Anope::string &mname) : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
bool server_source = source.GetServer() != NULL;
Anope::string modes = params[1];
@@ -854,9 +742,10 @@ struct IRCDMessageNetInfo : IRCDMessage
{
IRCDMessageNetInfo(Module *creator) : IRCDMessage(creator, "NETINFO", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
- UplinkSocket::Message() << "NETINFO " << MaxUserCount << " " << Anope::CurTime << " " << convertTo<int>(params[2]) << " " << params[3] << " 0 0 0 :" << params[7];
+ Stats *stats = Serialize::GetObject<Stats *>();
+ Uplink::Send("NETINFO", stats ? stats->GetMaxUserCount() : 0, Anope::CurTime, params[2], params[3], "0", "0", "0", params[7]);
}
};
@@ -884,7 +773,7 @@ struct IRCDMessageNick : IRCDMessage
** parv[0] = new nickname
** parv[1] = hopcount
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (params.size() == 11)
{
@@ -911,22 +800,22 @@ struct IRCDMessageNick : IRCDMessage
Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[5] << "?";
return;
}
-
- NickAlias *na = NULL;
+
+ NickServ::Nick *na = NULL;
if (params[6] == "0")
;
else if (params[6].is_pos_number_only())
{
if (convertTo<time_t>(params[6]) == user_ts)
- na = NickAlias::Find(params[0]);
+ na = NickServ::FindNick(params[0]);
}
else
{
- na = NickAlias::Find(params[6]);
+ na = NickServ::FindNick(params[6]);
}
- User::OnIntroduce(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? *na->nc : NULL);
+ User::OnIntroduce(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? na->GetAccount() : NULL);
}
else
source.GetUser()->ChangeNick(params[0]);
@@ -946,21 +835,43 @@ struct IRCDMessagePong : IRCDMessage
{
IRCDMessagePong(Module *creator) : IRCDMessage(creator, "PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
if (!source.GetServer()->IsSynced())
source.GetServer()->Sync(false);
}
};
+struct IRCDMessageProtoctl : Message::Capab
+{
+ IRCDMessageProtoctl(Module *creator) : Message::Capab(creator, "PROTOCTL") { }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ for (unsigned int i = 0; i < params.size(); ++i)
+ {
+ Anope::string capab = params[i];
+
+ if (!capab.find("SID="))
+ {
+ UplinkSID = capab.substr(4);
+ }
+ }
+
+ Message::Capab::Run(source, params);
+ }
+};
+
struct IRCDMessageSASL : IRCDMessage
{
+ ServiceReference<SASL::Service> sasl;
+
IRCDMessageSASL(Module *creator) : IRCDMessage(creator, "SASL", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
size_t p = params[1].find('!');
- if (!SASL::sasl || p == Anope::string::npos)
+ if (!sasl || p == Anope::string::npos)
return;
SASL::Message m;
@@ -970,7 +881,7 @@ struct IRCDMessageSASL : IRCDMessage
m.data = params[3];
m.ext = params.size() > 4 ? params[4] : "";
- SASL::sasl->ProcessMessage(m);
+ sasl->ProcessMessage(m);
}
};
@@ -978,7 +889,7 @@ struct IRCDMessageSDesc : IRCDMessage
{
IRCDMessageSDesc(Module *creator) : IRCDMessage(creator, "SDESC", 1) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
source.GetServer()->SetDescription(params[0]);
}
@@ -988,7 +899,7 @@ struct IRCDMessageSetHost : IRCDMessage
{
IRCDMessageSetHost(Module *creator) : IRCDMessage(creator, "SETHOST", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = source.GetUser();
@@ -1004,7 +915,7 @@ struct IRCDMessageSetIdent : IRCDMessage
{
IRCDMessageSetIdent(Module *creator) : IRCDMessage(creator, "SETIDENT", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = source.GetUser();
u->SetVIdent(params[0]);
@@ -1015,7 +926,7 @@ struct IRCDMessageSetName : IRCDMessage
{
IRCDMessageSetName(Module *creator) : IRCDMessage(creator, "SETNAME", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
User *u = source.GetUser();
u->SetRealname(params[0]);
@@ -1026,7 +937,7 @@ struct IRCDMessageServer : IRCDMessage
{
IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
@@ -1035,7 +946,7 @@ struct IRCDMessageServer : IRCDMessage
Anope::string desc;
spacesepstream(params[2]).GetTokenRemainder(desc, 1);
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, desc);
+ new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, desc, UplinkSID);
}
else
new Server(source.GetServer(), params[0], hops, params[2]);
@@ -1044,11 +955,25 @@ struct IRCDMessageServer : IRCDMessage
}
};
+struct IRCDMessageSID : IRCDMessage
+{
+ IRCDMessageSID(Module *creator) : IRCDMessage(creator, "SID", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
+
+ new Server(source.GetServer(), params[0], hops, params[3], params[2]);
+
+ IRCD->SendPing(Me->GetName(), params[0]);
+ }
+};
+
struct IRCDMessageSJoin : IRCDMessage
{
IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Anope::string modes;
if (params.size() >= 4)
@@ -1103,7 +1028,7 @@ struct IRCDMessageSJoin : IRCDMessage
users.push_back(sju);
}
}
-
+
time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
Message::Join::SJoin(source, params[1], ts, modes, users);
@@ -1142,7 +1067,7 @@ struct IRCDMessageTopic : IRCDMessage
** parv[2] = topic time
** parv[3] = topic text
*/
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Channel *c = Channel::Find(params[0]);
if (c)
@@ -1150,20 +1075,108 @@ struct IRCDMessageTopic : IRCDMessage
}
};
+/*
+ * parv[0] = nickname
+ * parv[1] = hopcount
+ * parv[2] = timestamp
+ * parv[3] = username
+ * parv[4] = hostname
+ * parv[5] = UID
+ * parv[6] = servicestamp
+ * parv[7] = umodes
+ * parv[8] = virthost, * if none
+ * parv[9] = cloaked host, * if none
+ * parv[10] = ip
+ * parv[11] = info
+ */
+struct IRCDMessageUID : IRCDMessage
+{
+ IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 12) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
+ {
+ Anope::string
+ nickname = params[0],
+ hopcount = params[1],
+ timestamp = params[2],
+ username = params[3],
+ hostname = params[4],
+ uid = params[5],
+ account = params[6],
+ umodes = params[7],
+ vhost = params[8],
+ chost = params[9],
+ ip = params[10],
+ info = params[11];
+
+ if (ip != "*")
+ {
+ Anope::string decoded_ip;
+ Anope::B64Decode(ip, decoded_ip);
+
+ sockaddrs ip_addr;
+ ip_addr.ntop(ip.length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
+ ip = ip_addr.addr();
+ }
+
+ if (vhost == "*")
+ vhost.clear();
+
+ if (chost == "*")
+ chost.clear();
+
+ time_t user_ts;
+ try
+ {
+ user_ts = convertTo<time_t>(timestamp);
+ }
+ catch (const ConvertException &)
+ {
+ user_ts = Anope::CurTime;
+ }
+
+ NickServ::Nick *na = NULL;
+
+ if (account == "0")
+ {
+ /* nothing */
+ }
+ else if (account.is_pos_number_only())
+ {
+ if (convertTo<time_t>(account) == user_ts)
+ na = NickServ::FindNick(nickname);
+ }
+ else
+ {
+ na = NickServ::FindNick(account);
+ }
+
+ User *u = User::OnIntroduce(nickname, username, hostname, vhost, ip, source.GetServer(), info, user_ts, umodes, uid, na ? na->GetAccount() : NULL);
+
+ if (u && !chost.empty() && chost != u->GetCloakedHost())
+ u->SetCloakedHost(chost);
+ }
+};
struct IRCDMessageUmode2 : IRCDMessage
{
IRCDMessageUmode2(Module *creator) : IRCDMessage(creator, "UMODE2", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
source.GetUser()->SetModesInternal(source, "%s", params[0].c_str());
}
};
class ProtoUnreal : public Module
+ , public EventHook<Event::UserNickChange>
+ , public EventHook<Event::ChannelSync>
+ , public EventHook<Event::ChanRegistered>
+ , public EventHook<Event::DelChan>
+ , public EventHook<Event::MLockEvents>
{
UnrealIRCdProto ircd_proto;
+ ServiceReference<ModeLocks> mlocks;
/* Core message handlers */
Message::Away message_away;
@@ -1185,148 +1198,171 @@ class ProtoUnreal : public Module
Message::Whois message_whois;
/* Our message handlers */
- IRCDMessageCapab message_capab;
IRCDMessageChgHost message_chghost;
IRCDMessageChgIdent message_chgident;
IRCDMessageChgName message_chgname;
+ IRCDMessageMD message_md;
IRCDMessageMode message_mode, message_svsmode, message_svs2mode;
IRCDMessageNetInfo message_netinfo;
IRCDMessageNick message_nick;
IRCDMessagePong message_pong;
+ IRCDMessageProtoctl message_protoctl;
IRCDMessageSASL message_sasl;
IRCDMessageSDesc message_sdesc;
IRCDMessageSetHost message_sethost;
IRCDMessageSetIdent message_setident;
IRCDMessageSetName message_setname;
IRCDMessageServer message_server;
+ IRCDMessageSID message_sid;
IRCDMessageSJoin message_sjoin;
IRCDMessageTopic message_topic;
+ IRCDMessageUID message_uid;
IRCDMessageUmode2 message_umode2;
bool use_server_side_mlock;
- void AddModes()
- {
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
- /* Unreal sends +q as * and +a as ~ */
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '~', 3));
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '*', 4));
-
- /* Add user modes */
- ModeManager::AddUserMode(new UserModeOperOnly("SERV_ADMIN", 'A'));
- ModeManager::AddUserMode(new UserMode("BOT", 'B'));
- ModeManager::AddUserMode(new UserModeOperOnly("CO_ADMIN", 'C'));
- ModeManager::AddUserMode(new UserMode("CENSOR", 'G'));
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H'));
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEIDLE", 'I'));
- ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("PROTECTED", 'S'));
- ModeManager::AddUserMode(new UserMode("NOCTCP", 'T'));
- ModeManager::AddUserMode(new UserMode("WEBTV", 'V'));
- ModeManager::AddUserMode(new UserModeOperOnly("WHOIS", 'W'));
- ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a'));
- ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
- ModeManager::AddUserMode(new UserModeOperOnly("GLOBOPS", 'g'));
- ModeManager::AddUserMode(new UserModeOperOnly("HELPOP", 'h'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserMode("PRIV", 'p'));
- ModeManager::AddUserMode(new UserModeOperOnly("GOD", 'q'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserModeNoone("VHOST", 't'));
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
- ModeManager::AddUserMode(new UserModeNoone("SSL", 'z'));
- }
-
public:
- ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this),
- message_kill(this), message_svskill(this, "SVSKILL"), message_motd(this), message_notice(this), message_part(this), message_ping(this),
- message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this),
- message_version(this), message_whois(this),
-
- message_capab(this), message_chghost(this), message_chgident(this), message_chgname(this), message_mode(this, "MODE"),
- message_svsmode(this, "SVSMODE"), message_svs2mode(this, "SVS2MODE"), message_netinfo(this), message_nick(this), message_pong(this),
- message_sasl(this), message_sdesc(this), message_sethost(this), message_setident(this), message_setname(this), message_server(this),
- message_sjoin(this), message_topic(this), message_umode2(this)
+ ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
+ , EventHook<Event::UserNickChange>(this, EventHook<Event::UserNickChange>::Priority::FIRST)
+ , EventHook<Event::ChannelSync>(this, EventHook<Event::ChannelSync>::Priority::FIRST)
+ , EventHook<Event::ChanRegistered>(this, EventHook<Event::ChanRegistered>::Priority::FIRST)
+ , EventHook<Event::DelChan>(this, EventHook<Event::DelChan>::Priority::FIRST)
+ , EventHook<Event::MLockEvents>(this, EventHook<Event::MLockEvents>::Priority::FIRST)
+ , ircd_proto(this)
+ , message_away(this)
+ , message_error(this)
+ , message_invite(this)
+ , message_join(this)
+ , message_kick(this)
+ , message_kill(this)
+ , message_svskill(this, "SVSKILL")
+ , message_motd(this)
+ , message_notice(this)
+ , message_part(this)
+ , message_ping(this)
+ , message_privmsg(this)
+ , message_quit(this)
+ , message_squit(this)
+ , message_stats(this)
+ , message_time(this)
+ , message_version(this)
+ , message_whois(this)
+
+ , message_chghost(this)
+ , message_chgident(this)
+ , message_chgname(this)
+ , message_md(this)
+ , message_mode(this, "MODE")
+ , message_svsmode(this, "SVSMODE")
+ , message_svs2mode(this, "SVS2MODE")
+ , message_netinfo(this)
+ , message_nick(this)
+ , message_pong(this)
+ , message_protoctl(this)
+ , message_sasl(this)
+ , message_sdesc(this)
+ , message_sethost(this)
+ , message_setident(this)
+ , message_setname(this)
+ , message_server(this)
+ , message_sid(this)
+ , message_sjoin(this)
+ , message_topic(this)
+ , message_uid(this)
+ , message_umode2(this)
+ {
+ }
+
+ void OnReload(Configuration::Conf *conf) override
{
+ use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
- this->AddModes();
- }
+ for (int i = 0; i < conf->CountBlock("extban"); ++i)
+ {
+ Configuration::Block *extban = conf->GetBlock("extban", i);
+ Anope::string name = extban->Get<Anope::string>("name"),
+ type = extban->Get<Anope::string>("type"),
+ base = extban->Get<Anope::string>("base"),
+ character = extban->Get<Anope::string>("character");
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
+ ChannelMode *cm;
- void OnReload(Configuration::Conf *conf) anope_override
- {
- use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
+ if (character.empty())
+ continue;
+
+ if (type == "channel")
+ cm = new UnrealExtban::ChannelMatcher(name, base, character[0]);
+ else if (type == "entry")
+ cm = new UnrealExtban::EntryMatcher(name, base, character[0]);
+ else if (type == "realname")
+ cm = new UnrealExtban::RealnameMatcher(name, base, character[0]);
+ else if (type == "registered")
+ cm = new UnrealExtban::RegisteredMatcher(name, base, character[0]);
+ else if (type == "account")
+ cm = new UnrealExtban::AccountMatcher(name, base, character[0]);
+ else if (type == "fingerprint")
+ cm = new UnrealExtban::FingerprintMatcher(name, base, character[0]);
+ else
+ continue;
+
+ if (!ModeManager::AddChannelMode(cm))
+ delete cm;
+ }
}
- void OnUserNickChange(User *u, const Anope::string &) anope_override
+ void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
if (Servers::Capab.count("ESVID") == 0)
IRCD->SendLogout(u);
}
- void OnChannelSync(Channel *c) anope_override
+ void OnChannelSync(Channel *c) override
{
if (!c->ci)
return;
- ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
- if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && modelocks)
+ if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && mlocks)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(c->ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
+ Uplink::Send(Me, "MLOCK", c->creation_time, c->ci->GetName(), modes);
}
}
- void OnChanRegistered(ChannelInfo *ci) anope_override
+ void OnChanRegistered(ChanServ::Channel *ci) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- if (!ci->c || !use_server_side_mlock || !modelocks || !Servers::Capab.count("MLOCK"))
+ if (!ci->c || !use_server_side_mlock || !mlocks || !Servers::Capab.count("MLOCK"))
return;
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), modes);
}
- void OnDelChan(ChannelInfo *ci) anope_override
+ void OnDelChan(ChanServ::Channel *ci) override
{
if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
return;
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :";
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), "");
}
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && mlocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), modes);
}
return EVENT_CONTINUE;
}
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ EventReturn OnUnMLock(ChanServ::Channel *ci, ModeLock *lock) override
{
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->GetName());
+ if (use_server_side_mlock && cm && mlocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ Anope::string modes = mlocks->GetMLockAsString(ci, false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
+ Uplink::Send(Me, "MLOCK", ci->c->creation_time, ci->GetName(), modes);
}
return EVENT_CONTINUE;
diff --git a/modules/protocol/unreal4.cpp b/modules/protocol/unreal4.cpp
deleted file mode 100644
index 6e5f6ec55..000000000
--- a/modules/protocol/unreal4.cpp
+++ /dev/null
@@ -1,1468 +0,0 @@
-/* Unreal IRCD 4 functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-#include "modules/sasl.h"
-
-static Anope::string UplinkSID;
-
-class UnrealIRCdProto : public IRCDProto
-{
- public:
- UnrealIRCdProto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4")
- {
- DefaultPseudoclientModes = "+Soiq";
- CanSVSNick = true;
- CanSVSJoin = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- CanSNLine = true;
- CanSQLine = true;
- CanSZLine = true;
- CanSVSHold = true;
- CanCertFP = true;
- RequiresID = true;
- MaxModes = 12;
- }
-
- private:
- /* SVSNOOP */
- void SendSVSNOOP(const Server *server, bool set) anope_override
- {
- UplinkSocket::Message() << "SVSNOOP " << server->GetSID() << " " << (set ? "+" : "-");
- }
-
- void SendAkillDel(const XLine *x) anope_override
- {
- if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr a(x->GetHost());
- if (a.valid())
- {
- IRCD->SendSZLineDel(x);
- return;
- }
- }
-
- UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by;
- }
-
- void SendTopic(const MessageSource &source, Channel *c) anope_override
- {
- UplinkSocket::Message(source) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
- }
-
- void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
- {
- UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
- }
-
- void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
- {
- UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
- }
-
- void SendVhostDel(User *u) anope_override
- {
- BotInfo *HostServ = Config->GetClient("HostServ");
- u->RemoveMode(HostServ, "CLOAK");
- u->RemoveMode(HostServ, "VHOST");
- ModeManager::ProcessModes();
- u->SetMode(HostServ, "CLOAK");
- }
-
- void SendAkill(User *u, XLine *x) anope_override
- {
- if (x->IsRegex() || x->HasNickOrReal())
- {
- if (!u)
- {
- /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->manager->Check(it->second, x))
- this->SendAkill(it->second, x);
- return;
- }
-
- const XLine *old = x;
-
- if (old->manager->HasEntry("*@" + u->host))
- return;
-
- /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- XLine *xline = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
- old->manager->AddXLine(xline);
- x = xline;
-
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
- }
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr a(x->GetHost());
- if (a.valid())
- {
- IRCD->SendSZLine(u, x);
- return;
- }
- }
-
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
- timeleft = 172800;
- UplinkSocket::Message() << "TKL + G " << x->GetUser() << " " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
- }
-
- void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
- {
- UplinkSocket::Message(source) << "SVSKILL " << user->GetUID() << " :" << buf;
- user->KillInternal(source, buf);
- }
-
- void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override
- {
- UplinkSocket::Message(source) << "SVS2MODE " << u->GetUID() <<" " << buf;
- }
-
- void SendClientIntroduction(User *u) anope_override
- {
- Anope::string modes = "+" + u->GetModes();
- UplinkSocket::Message(u->server) << "UID " << u->nick << " 1 " << u->timestamp << " " << u->GetIdent() << " " << u->host << " "
- << u->GetUID() << " * " << modes << " " << (!u->vhost.empty() ? u->vhost : "*") << " "
- << (!u->chost.empty() ? u->chost : "*") << " " << "*" << " :" << u->realname;
- }
-
- void SendServer(const Server *server) anope_override
- {
- if (server == Me)
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() + 1 << " :" << server->GetDescription();
- else
- UplinkSocket::Message(Me) << "SID " << server->GetName() << " " << server->GetHops() + 1 << " " << server->GetSID() << " :" << server->GetDescription();
- }
-
- /* JOIN */
- void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
- {
- UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->GetUID();
- if (status)
- {
- /* First save the channel status incase uc->Status == status */
- ChannelStatus cs = *status;
- /* If the user is internally on the channel with flags, kill them so that
- * the stacker will allow this.
- */
- ChanUserContainer *uc = c->FindUser(user);
- if (uc != NULL)
- uc->status.Clear();
-
- BotInfo *setter = BotInfo::Find(user->GetUID());
- for (size_t i = 0; i < cs.Modes().length(); ++i)
- c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
-
- if (uc != NULL)
- uc->status = cs;
- }
- }
-
- /* unsqline
- */
- void SendSQLineDel(const XLine *x) anope_override
- {
- UplinkSocket::Message() << "UNSQLINE " << x->mask;
- }
-
- /* SQLINE */
- /*
- ** - Unreal will translate this to TKL for us
- **
- */
- void SendSQLine(User *, const XLine *x) anope_override
- {
- UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
- }
-
- /* Functions that use serval cmd functions */
-
- void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) anope_override
- {
- if (!vIdent.empty())
- UplinkSocket::Message(Me) << "CHGIDENT " << u->GetUID() << " " << vIdent;
- if (!vhost.empty())
- UplinkSocket::Message(Me) << "CHGHOST " << u->GetUID() << " " << vhost;
- }
-
- void SendConnect() anope_override
- {
- /*
- NICKv2 = Nick Version 2
- VHP = Sends hidden host
- UMODE2 = sends UMODE2 on user modes
- NICKIP = Sends IP on NICK
- SJ3 = Supports SJOIN
- NOQUIT = No Quit
- TKLEXT = Extended TKL we don't use it but best to have it
- MLOCK = Supports the MLOCK server command
- VL = Version Info
- SID = SID/UID mode
- */
- UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink].password;
- UplinkSocket::Message() << "PROTOCTL " << "NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID";
- UplinkSocket::Message() << "PROTOCTL " << "EAUTH=" << Me->GetName() << ",,,Anope-" << Anope::VersionShort();
- UplinkSocket::Message() << "PROTOCTL " << "SID=" << Me->GetSID();
- SendServer(Me);
- }
-
- /* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick, time_t t) anope_override
- {
- UplinkSocket::Message() << "TKL + Q H " << nick << " " << Me->GetName() << " " << Anope::CurTime + t << " " << Anope::CurTime << " :Being held for registered user";
- }
-
- /* SVSHOLD - release */
- void SendSVSHoldDel(const Anope::string &nick) anope_override
- {
- UplinkSocket::Message() << "TKL - Q * " << nick << " " << Me->GetName();
- }
-
- /* UNSGLINE */
- /*
- * SVSNLINE - :realname mask
- */
- void SendSGLineDel(const XLine *x) anope_override
- {
- UplinkSocket::Message() << "SVSNLINE - :" << x->mask;
- }
-
- /* UNSZLINE */
- void SendSZLineDel(const XLine *x) anope_override
- {
- UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << x->by;
- }
-
- /* SZLINE */
- void SendSZLine(User *, const XLine *x) anope_override
- {
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->expires - Anope::CurTime;
- if (timeleft > 172800 || !x->expires)
- timeleft = 172800;
- UplinkSocket::Message() << "TKL + Z * " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
- }
-
- /* SGLINE */
- /*
- * SVSNLINE + reason_where_is_space :realname mask with spaces
- */
- void SendSGLine(User *, const XLine *x) anope_override
- {
- Anope::string edited_reason = x->GetReason();
- edited_reason = edited_reason.replace_all_cs(" ", "_");
- UplinkSocket::Message() << "SVSNLINE + " << edited_reason << " :" << x->mask;
- }
-
- /* svsjoin
- parv[0] - sender
- parv[1] - nick to make join
- parv[2] - channel to join
- parv[3] - (optional) channel key(s)
- */
- /* In older Unreal SVSJOIN and SVSNLINE tokens were mixed so SVSJOIN and SVSNLINE are broken
- when coming from a none TOKEN'd server
- */
- void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
- {
- if (!param.empty())
- UplinkSocket::Message() << "SVSJOIN " << user->GetUID() << " " << chan << " :" << param;
- else
- UplinkSocket::Message() << "SVSJOIN " << user->GetUID() << " " << chan;
- }
-
- void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) anope_override
- {
- if (!param.empty())
- UplinkSocket::Message() << "SVSPART " << user->GetUID() << " " << chan << " :" << param;
- else
- UplinkSocket::Message() << "SVSPART " << user->GetUID() << " " << chan;
- }
-
- void SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) anope_override
- {
- UplinkSocket::Message(source) << "SWHOIS " << who << " :" << mask;
- }
-
- void SendEOB() anope_override
- {
- UplinkSocket::Message(Me) << "EOS";
- }
-
- bool IsNickValid(const Anope::string &nick) anope_override
- {
- if (nick.equals_ci("ircd") || nick.equals_ci("irc"))
- return false;
-
- return IRCDProto::IsNickValid(nick);
- }
-
- bool IsChannelValid(const Anope::string &chan) anope_override
- {
- if (chan.find(':') != Anope::string::npos)
- return false;
-
- return IRCDProto::IsChannelValid(chan);
- }
-
- bool IsExtbanValid(const Anope::string &mask) anope_override
- {
- return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
- }
-
- void SendLogin(User *u, NickAlias *na) anope_override
- {
- /* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */
- if (Servers::Capab.count("ESVID") > 0 && !na->nc->HasExt("UNCONFIRMED"))
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %s", na->nc->display.c_str());
- else
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %d", u->signon);
- }
-
- void SendLogout(User *u) anope_override
- {
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0");
- }
-
- void SendChannel(Channel *c) anope_override
- {
- /* Unreal does not support updating a channels TS without actually joining a user,
- * so we will join and part us now
- */
- BotInfo *bi = c->ci->WhoSends();
- if (!bi)
- ;
- else if (c->FindUser(bi) == NULL)
- {
- bi->Join(c);
- bi->Part(c);
- }
- else
- {
- bi->Part(c);
- bi->Join(c);
- }
- }
-
- void SendSASLMessage(const SASL::Message &message) anope_override
- {
- size_t p = message.target.find('!');
- if (p == Anope::string::npos)
- return;
-
- UplinkSocket::Message(BotInfo::Find(message.source)) << "SASL " << message.target.substr(0, p) << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : " " + message.ext);
- }
-
- void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
- {
- size_t p = uid.find('!');
- if (p == Anope::string::npos)
- return;
- UplinkSocket::Message(Me) << "SVSLOGIN " << uid.substr(0, p) << " " << uid << " " << acc;
- }
-
- bool IsIdentValid(const Anope::string &ident) anope_override
- {
- if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
- return false;
-
- for (unsigned i = 0; i < ident.length(); ++i)
- {
- const char &c = ident[i];
-
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
- continue;
-
- if (c == '-' || c == '.' || c == '_')
- continue;
-
- return false;
- }
-
- return true;
- }
-};
-
-class UnrealExtBan : public ChannelModeVirtual<ChannelModeList>
-{
- char ext;
-
- public:
- UnrealExtBan(const Anope::string &mname, const Anope::string &basename, char extban) : ChannelModeVirtual<ChannelModeList>(mname, basename)
- , ext(extban)
- {
- }
-
- ChannelMode *Wrap(Anope::string &param) anope_override
- {
- param = "~" + Anope::string(ext) + ":" + param;
- return ChannelModeVirtual<ChannelModeList>::Wrap(param);
- }
-
- ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_override
- {
- if (cm->type != MODE_LIST || param.length() < 4 || param[0] != '~' || param[1] != ext || param[2] != ':')
- return cm;
-
- param = param.substr(3);
- return this;
- }
-};
-
-namespace UnrealExtban
-{
- class ChannelMatcher : public UnrealExtBan
- {
- public:
- ChannelMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- Anope::string channel = mask.substr(3);
-
- ChannelMode *cm = NULL;
- if (channel[0] != '#')
- {
- char modeChar = ModeManager::GetStatusChar(channel[0]);
- channel.erase(channel.begin());
- cm = ModeManager::FindChannelModeByChar(modeChar);
- if (cm != NULL && cm->type != MODE_STATUS)
- cm = NULL;
- }
-
- Channel *c = Channel::Find(channel);
- if (c != NULL)
- {
- ChanUserContainer *uc = c->FindUser(u);
- if (uc != NULL)
- if (cm == NULL || uc->status.HasMode(cm->mchar))
- return true;
- }
-
- return false;
- }
- };
-
- class EntryMatcher : public UnrealExtBan
- {
- public:
- EntryMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- Anope::string real_mask = mask.substr(3);
-
- return Entry(this->name, real_mask).Matches(u);
- }
- };
-
- class RealnameMatcher : public UnrealExtBan
- {
- public:
- RealnameMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- Anope::string real_mask = mask.substr(3);
-
- return Anope::Match(u->realname, real_mask);
- }
- };
-
- class RegisteredMatcher : public UnrealExtBan
- {
- public:
- RegisteredMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- return u->HasMode("REGISTERED") && mask.equals_ci(u->nick);
- }
- };
-
- class AccountMatcher : public UnrealExtBan
- {
- public:
- AccountMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- Anope::string real_mask = mask.substr(3);
-
- return u->Account() && Anope::Match(u->Account()->display, real_mask);
- }
- };
-
- class FingerprintMatcher : public UnrealExtBan
- {
- public:
- FingerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
- {
- }
-
- bool Matches(User *u, const Entry *e) anope_override
- {
- const Anope::string &mask = e->GetMask();
- Anope::string real_mask = mask.substr(3);
- return !u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask);
- }
- };
-}
-
-class ChannelModeFlood : public ChannelModeParam
-{
- public:
- ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
-
- /* Borrowed part of this check from UnrealIRCd */
- bool IsValid(Anope::string &value) const anope_override
- {
- if (value.empty())
- return false;
- try
- {
- Anope::string rest;
- if (value[0] != ':' && convertTo<unsigned>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<unsigned>(rest.substr(1), rest, false) > 0 && rest.empty())
- return true;
- }
- catch (const ConvertException &) { }
-
- /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
- size_t end_bracket = value.find(']', 1);
- if (end_bracket == Anope::string::npos)
- return false;
- Anope::string xbuf = value.substr(0, end_bracket);
- if (value[end_bracket + 1] != ':')
- return false;
- commasepstream args(xbuf.substr(1));
- Anope::string arg;
- while (args.GetToken(arg))
- {
- /* <number><1 letter>[optional: '#'+1 letter] */
- size_t p = 0;
- while (p < arg.length() && isdigit(arg[p]))
- ++p;
- if (p == arg.length() || !(arg[p] == 'c' || arg[p] == 'j' || arg[p] == 'k' || arg[p] == 'm' || arg[p] == 'n' || arg[p] == 't'))
- continue; /* continue instead of break for forward compatibility. */
- try
- {
- int v = arg.substr(0, p).is_number_only() ? convertTo<int>(arg.substr(0, p)) : 0;
- if (v < 1 || v > 999)
- return false;
- }
- catch (const ConvertException &)
- {
- return false;
- }
- }
-
- return true;
- }
-};
-
-class ChannelModeUnrealSSL : public ChannelMode
-{
- public:
- ChannelModeUnrealSSL(const Anope::string &n, char c) : ChannelMode(n, c)
- {
- }
-
- bool CanSet(User *u) const anope_override
- {
- return false;
- }
-};
-
-struct IRCDMessageCapab : Message::Capab
-{
- IRCDMessageCapab(Module *creator) : Message::Capab(creator, "PROTOCTL") { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- for (unsigned i = 0; i < params.size(); ++i)
- {
- Anope::string capab = params[i];
-
- if (capab.find("CHANMODES") != Anope::string::npos)
- {
- Anope::string modes(capab.begin() + 10, capab.end());
- commasepstream sep(modes);
- Anope::string modebuf;
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'b':
- ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
-
- ModeManager::AddChannelMode(new UnrealExtban::ChannelMatcher("CHANNELBAN", "BAN", 'c'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("JOINBAN", "BAN", 'j'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("NONICKBAN", "BAN", 'n'));
- ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("QUIET", "BAN", 'q'));
- ModeManager::AddChannelMode(new UnrealExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r'));
- ModeManager::AddChannelMode(new UnrealExtban::RegisteredMatcher("REGISTEREDBAN", "BAN", 'R'));
- ModeManager::AddChannelMode(new UnrealExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'a'));
- ModeManager::AddChannelMode(new UnrealExtban::FingerprintMatcher("SSLBAN", "BAN", 'S'));
- // also has O for opertype extban, but it doesn't send us users opertypes
- continue;
- case 'e':
- ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
- continue;
- case 'I':
- ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'k':
- ModeManager::AddChannelMode(new ChannelModeKey('k'));
- continue;
- case 'f':
- ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
- continue;
- case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t]));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t], true));
- }
- }
-
- sep.GetToken(modebuf);
- for (size_t t = 0, end = modebuf.length(); t < end; ++t)
- {
- switch (modebuf[t])
- {
- case 'p':
- ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
- continue;
- case 's':
- ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
- continue;
- case 'm':
- ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
- continue;
- case 'n':
- ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
- continue;
- case 't':
- ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
- continue;
- case 'i':
- ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
- continue;
- case 'r':
- ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
- continue;
- case 'R':
- ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
- continue;
- case 'c':
- ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
- continue;
- case 'O':
- ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
- continue;
- case 'Q':
- ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q'));
- continue;
- case 'K':
- ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K'));
- continue;
- case 'V':
- ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V'));
- continue;
- case 'C':
- ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
- continue;
- case 'z':
- ModeManager::AddChannelMode(new ChannelMode("SSL", 'z'));
- continue;
- case 'N':
- ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N'));
- continue;
- case 'S':
- ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S'));
- continue;
- case 'M':
- ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
- continue;
- case 'T':
- ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T'));
- continue;
- case 'G':
- ModeManager::AddChannelMode(new ChannelMode("CENSOR", 'G'));
- continue;
- case 'Z':
- ModeManager::AddChannelMode(new ChannelModeUnrealSSL("", 'Z'));
- continue;
- case 'd':
- // post delayed. means that channel is -D but invisible users still exist.
- continue;
- case 'D':
- ModeManager::AddChannelMode(new ChannelMode("DELAYEDJOIN", 'D'));
- continue;
- case 'P':
- ModeManager::AddChannelMode(new ChannelMode("PERM", 'P'));
- continue;
- default:
- ModeManager::AddChannelMode(new ChannelMode("", modebuf[t]));
- }
- }
- }
- else if (!capab.find("SID="))
- {
- UplinkSID = capab.substr(4);
- }
- }
-
- Message::Capab::Run(source, params);
- }
-};
-
-struct IRCDMessageChgHost : IRCDMessage
-{
- IRCDMessageChgHost(Module *creator) : IRCDMessage(creator, "CHGHOST", 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = User::Find(params[0]);
- if (u)
- u->SetDisplayedHost(params[1]);
- }
-};
-
-struct IRCDMessageChgIdent : IRCDMessage
-{
- IRCDMessageChgIdent(Module *creator) : IRCDMessage(creator, "CHGIDENT", 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = User::Find(params[0]);
- if (u)
- u->SetVIdent(params[1]);
- }
-};
-
-struct IRCDMessageChgName : IRCDMessage
-{
- IRCDMessageChgName(Module *creator) : IRCDMessage(creator, "CHGNAME", 2) { }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = User::Find(params[0]);
- if (u)
- u->SetRealname(params[1]);
- }
-};
-
-struct IRCDMessageMD : IRCDMessage
-{
- IRCDMessageMD(Module *creator) : IRCDMessage(creator, "MD", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &mdtype = params[0],
- &obj = params[1],
- &var = params[2],
- &value = params.size() > 3 ? params[3] : "";
-
- if (mdtype == "client")
- {
- User *u = User::Find(obj);
-
- if (u == NULL)
- return;
-
- if (var == "certfp" && !value.empty())
- {
- u->Extend<bool>("ssl");
- u->fingerprint = value;
- FOREACH_MOD(OnFingerprint, (u));
- }
- }
- }
-};
-
-struct IRCDMessageMode : IRCDMessage
-{
- IRCDMessageMode(Module *creator, const Anope::string &mname) : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- bool server_source = source.GetServer() != NULL;
- Anope::string modes = params[1];
- for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i)
- modes += " " + params[i];
-
- if (IRCD->IsChannelValid(params[0]))
- {
- Channel *c = Channel::Find(params[0]);
- time_t ts = 0;
-
- try
- {
- if (server_source)
- ts = convertTo<time_t>(params[params.size() - 1]);
- }
- catch (const ConvertException &) { }
-
- if (c)
- c->SetModesInternal(source, modes, ts);
- }
- else
- {
- User *u = User::Find(params[0]);
- if (u)
- u->SetModesInternal(source, "%s", params[1].c_str());
- }
- }
-};
-
-/* netinfo
- * argv[0] = max global count
- * argv[1] = time of end sync
- * argv[2] = unreal protocol using (numeric)
- * argv[3] = cloak-crc (> u2302)
- * argv[4] = free(**)
- * argv[5] = free(**)
- * argv[6] = free(**)
- * argv[7] = ircnet
- */
-struct IRCDMessageNetInfo : IRCDMessage
-{
- IRCDMessageNetInfo(Module *creator) : IRCDMessage(creator, "NETINFO", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- UplinkSocket::Message() << "NETINFO " << MaxUserCount << " " << Anope::CurTime << " " << convertTo<int>(params[2]) << " " << params[3] << " 0 0 0 :" << params[7];
- }
-};
-
-struct IRCDMessageNick : IRCDMessage
-{
- IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- /*
- ** NICK - new
- ** source = NULL
- ** parv[0] = nickname
- ** parv[1] = hopcount
- ** parv[2] = timestamp
- ** parv[3] = username
- ** parv[4] = hostname
- ** parv[5] = servername
- ** parv[6] = servicestamp
- ** parv[7] = umodes
- ** parv[8] = virthost, * if none
- ** parv[9] = ip
- ** parv[10] = info
- **
- ** NICK - change
- ** source = oldnick
- ** parv[0] = new nickname
- ** parv[1] = hopcount
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.size() == 11)
- {
- Anope::string ip;
- if (params[9] != "*")
- {
- Anope::string decoded_ip;
- Anope::B64Decode(params[9], decoded_ip);
-
- sockaddrs ip_addr;
- ip_addr.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
- ip = ip_addr.addr();
- }
-
- Anope::string vhost = params[8];
- if (vhost.equals_cs("*"))
- vhost.clear();
-
- time_t user_ts = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime;
-
- Server *s = Server::Find(params[5]);
- if (s == NULL)
- {
- Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[5] << "?";
- return;
- }
-
- NickAlias *na = NULL;
-
- if (params[6] == "0")
- ;
- else if (params[6].is_pos_number_only())
- {
- if (convertTo<time_t>(params[6]) == user_ts)
- na = NickAlias::Find(params[0]);
- }
- else
- {
- na = NickAlias::Find(params[6]);
- }
-
- User::OnIntroduce(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? *na->nc : NULL);
- }
- else
- source.GetUser()->ChangeNick(params[0]);
- }
-};
-
-/** This is here because:
- *
- * If we had three servers, A, B & C linked like so: A<->B<->C
- * If Anope is linked to A and B splits from A and then reconnects
- * B introduces itself, introduces C, sends EOS for C, introduces Bs clients
- * introduces Cs clients, sends EOS for B. This causes all of Cs clients to be introduced
- * with their server "not syncing". We now send a PING immediately when receiving a new server
- * and then finish sync once we get a pong back from that server.
- */
-struct IRCDMessagePong : IRCDMessage
-{
- IRCDMessagePong(Module *creator) : IRCDMessage(creator, "PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!source.GetServer()->IsSynced())
- source.GetServer()->Sync(false);
- }
-};
-
-struct IRCDMessageSASL : IRCDMessage
-{
- IRCDMessageSASL(Module *creator) : IRCDMessage(creator, "SASL", 4) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- size_t p = params[1].find('!');
- if (!SASL::sasl || p == Anope::string::npos)
- return;
-
- SASL::Message m;
- m.source = params[1];
- m.target = params[0];
- m.type = params[2];
- m.data = params[3];
- m.ext = params.size() > 4 ? params[4] : "";
-
- SASL::sasl->ProcessMessage(m);
- }
-};
-
-struct IRCDMessageSDesc : IRCDMessage
-{
- IRCDMessageSDesc(Module *creator) : IRCDMessage(creator, "SDESC", 1) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetServer()->SetDescription(params[0]);
- }
-};
-
-struct IRCDMessageSetHost : IRCDMessage
-{
- IRCDMessageSetHost(Module *creator) : IRCDMessage(creator, "SETHOST", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- /* When a user sets +x we receive the new host and then the mode change */
- if (u->HasMode("CLOAK"))
- u->SetDisplayedHost(params[0]);
- else
- u->SetCloakedHost(params[0]);
- }
-};
-
-struct IRCDMessageSetIdent : IRCDMessage
-{
- IRCDMessageSetIdent(Module *creator) : IRCDMessage(creator, "SETIDENT", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- u->SetVIdent(params[0]);
- }
-};
-
-struct IRCDMessageSetName : IRCDMessage
-{
- IRCDMessageSetName(Module *creator) : IRCDMessage(creator, "SETNAME", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- u->SetRealname(params[0]);
- }
-};
-
-struct IRCDMessageServer : IRCDMessage
-{
- IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
-
- if (params[1].equals_cs("1"))
- {
- Anope::string desc;
- spacesepstream(params[2]).GetTokenRemainder(desc, 1);
-
- new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, desc, UplinkSID);
- }
- else
- new Server(source.GetServer(), params[0], hops, params[2]);
-
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
-
-struct IRCDMessageSID : IRCDMessage
-{
- IRCDMessageSID(Module *creator) : IRCDMessage(creator, "SID", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
-
- new Server(source.GetServer(), params[0], hops, params[3], params[2]);
-
- IRCD->SendPing(Me->GetName(), params[0]);
- }
-};
-
-struct IRCDMessageSJoin : IRCDMessage
-{
- IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string modes;
- if (params.size() >= 4)
- for (unsigned i = 2; i < params.size() - 1; ++i)
- modes += " " + params[i];
- if (!modes.empty())
- modes.erase(modes.begin());
-
- std::list<Anope::string> bans, excepts, invites;
- std::list<Message::Join::SJoinUser> users;
-
- spacesepstream sep(params[params.size() - 1]);
- Anope::string buf;
- while (sep.GetToken(buf))
- {
- /* Ban */
- if (buf[0] == '&')
- {
- buf.erase(buf.begin());
- bans.push_back(buf);
- }
- /* Except */
- else if (buf[0] == '"')
- {
- buf.erase(buf.begin());
- excepts.push_back(buf);
- }
- /* Invex */
- else if (buf[0] == '\'')
- {
- buf.erase(buf.begin());
- invites.push_back(buf);
- }
- else
- {
- Message::Join::SJoinUser sju;
-
- /* Get prefixes from the nick */
- for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
- {
- sju.first.AddMode(ch);
- buf.erase(buf.begin());
- }
-
- sju.second = User::Find(buf);
- if (!sju.second)
- {
- Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
- continue;
- }
-
- users.push_back(sju);
- }
- }
-
- time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
- Message::Join::SJoin(source, params[1], ts, modes, users);
-
- if (!bans.empty() || !excepts.empty() || !invites.empty())
- {
- Channel *c = Channel::Find(params[1]);
-
- if (!c || c->creation_time != ts)
- return;
-
- ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"),
- *except = ModeManager::FindChannelModeByName("EXCEPT"),
- *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE");
-
- if (ban)
- for (std::list<Anope::string>::iterator it = bans.begin(), it_end = bans.end(); it != it_end; ++it)
- c->SetModeInternal(source, ban, *it);
- if (except)
- for (std::list<Anope::string>::iterator it = excepts.begin(), it_end = excepts.end(); it != it_end; ++it)
- c->SetModeInternal(source, except, *it);
- if (invex)
- for (std::list<Anope::string>::iterator it = invites.begin(), it_end = invites.end(); it != it_end; ++it)
- c->SetModeInternal(source, invex, *it);
- }
- }
-};
-
-struct IRCDMessageTopic : IRCDMessage
-{
- IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { }
-
- /*
- ** source = sender prefix
- ** parv[0] = channel name
- ** parv[1] = topic nickname
- ** parv[2] = topic time
- ** parv[3] = topic text
- */
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Channel *c = Channel::Find(params[0]);
- if (c)
- c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
- }
-};
-
-/*
- * parv[0] = nickname
- * parv[1] = hopcount
- * parv[2] = timestamp
- * parv[3] = username
- * parv[4] = hostname
- * parv[5] = UID
- * parv[6] = servicestamp
- * parv[7] = umodes
- * parv[8] = virthost, * if none
- * parv[9] = cloaked host, * if none
- * parv[10] = ip
- * parv[11] = info
- */
-struct IRCDMessageUID : IRCDMessage
-{
- IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 12) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string
- nickname = params[0],
- hopcount = params[1],
- timestamp = params[2],
- username = params[3],
- hostname = params[4],
- uid = params[5],
- account = params[6],
- umodes = params[7],
- vhost = params[8],
- chost = params[9],
- ip = params[10],
- info = params[11];
-
- if (ip != "*")
- {
- Anope::string decoded_ip;
- Anope::B64Decode(ip, decoded_ip);
-
- sockaddrs ip_addr;
- ip_addr.ntop(ip.length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
- ip = ip_addr.addr();
- }
-
- if (vhost == "*")
- vhost.clear();
-
- if (chost == "*")
- chost.clear();
-
- time_t user_ts;
- try
- {
- user_ts = convertTo<time_t>(timestamp);
- }
- catch (const ConvertException &)
- {
- user_ts = Anope::CurTime;
- }
-
- NickAlias *na = NULL;
-
- if (account == "0")
- {
- ;
- }
- else if (account.is_pos_number_only())
- {
- if (convertTo<time_t>(account) == user_ts)
- na = NickAlias::Find(nickname);
- }
- else
- {
- na = NickAlias::Find(account);
- }
-
- User *u = User::OnIntroduce(nickname, username, hostname, vhost, ip, source.GetServer(), info, user_ts, umodes, uid, na ? *na->nc : NULL);
-
- if (u && !chost.empty() && chost != u->GetCloakedHost())
- u->SetCloakedHost(chost);
- }
-};
-
-struct IRCDMessageUmode2 : IRCDMessage
-{
- IRCDMessageUmode2(Module *creator) : IRCDMessage(creator, "UMODE2", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
- {
- source.GetUser()->SetModesInternal(source, "%s", params[0].c_str());
- }
-};
-
-class ProtoUnreal : public Module
-{
- UnrealIRCdProto ircd_proto;
-
- /* Core message handlers */
- Message::Away message_away;
- Message::Error message_error;
- Message::Invite message_invite;
- Message::Join message_join;
- Message::Kick message_kick;
- Message::Kill message_kill, message_svskill;
- Message::MOTD message_motd;
- Message::Notice message_notice;
- Message::Part message_part;
- Message::Ping message_ping;
- Message::Privmsg message_privmsg;
- Message::Quit message_quit;
- Message::SQuit message_squit;
- Message::Stats message_stats;
- Message::Time message_time;
- Message::Version message_version;
- Message::Whois message_whois;
-
- /* Our message handlers */
- IRCDMessageCapab message_capab;
- IRCDMessageChgHost message_chghost;
- IRCDMessageChgIdent message_chgident;
- IRCDMessageChgName message_chgname;
- IRCDMessageMD message_md;
- IRCDMessageMode message_mode, message_svsmode, message_svs2mode;
- IRCDMessageNetInfo message_netinfo;
- IRCDMessageNick message_nick;
- IRCDMessagePong message_pong;
- IRCDMessageSASL message_sasl;
- IRCDMessageSDesc message_sdesc;
- IRCDMessageSetHost message_sethost;
- IRCDMessageSetIdent message_setident;
- IRCDMessageSetName message_setname;
- IRCDMessageServer message_server;
- IRCDMessageSID message_sid;
- IRCDMessageSJoin message_sjoin;
- IRCDMessageTopic message_topic;
- IRCDMessageUID message_uid;
- IRCDMessageUmode2 message_umode2;
-
- bool use_server_side_mlock;
-
- void AddModes()
- {
- ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
- ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
- ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
- /* Unreal sends +q as * and +a as ~ */
- ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '~', 3));
- ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '*', 4));
-
- /* Add user modes */
- ModeManager::AddUserMode(new UserMode("BOT", 'B'));
- ModeManager::AddUserMode(new UserMode("CENSOR", 'G'));
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H'));
- ModeManager::AddUserMode(new UserModeOperOnly("HIDEIDLE", 'I'));
- ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
- ModeManager::AddUserMode(new UserModeOperOnly("PROTECTED", 'S'));
- ModeManager::AddUserMode(new UserMode("NOCTCP", 'T'));
- ModeManager::AddUserMode(new UserMode("WEBTV", 'V'));
- ModeManager::AddUserMode(new UserModeOperOnly("WHOIS", 'W'));
- ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
- ModeManager::AddUserMode(new UserModeOperOnly("GLOBOPS", 'g'));
- ModeManager::AddUserMode(new UserModeOperOnly("HELPOP", 'h'));
- ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
- ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o'));
- ModeManager::AddUserMode(new UserMode("PRIV", 'p'));
- ModeManager::AddUserMode(new UserModeOperOnly("GOD", 'q'));
- ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r'));
- ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's'));
- ModeManager::AddUserMode(new UserModeNoone("VHOST", 't'));
- ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
- ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
- ModeManager::AddUserMode(new UserModeNoone("SSL", 'z'));
- }
-
- public:
- ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
- ircd_proto(this),
- message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this),
- message_kill(this), message_svskill(this, "SVSKILL"), message_motd(this), message_notice(this), message_part(this), message_ping(this),
- message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this),
- message_version(this), message_whois(this),
-
- message_capab(this), message_chghost(this), message_chgident(this), message_chgname(this), message_md(this), message_mode(this, "MODE"),
- message_svsmode(this, "SVSMODE"), message_svs2mode(this, "SVS2MODE"), message_netinfo(this), message_nick(this), message_pong(this),
- message_sasl(this), message_sdesc(this), message_sethost(this), message_setident(this), message_setname(this), message_server(this),
- message_sid(this), message_sjoin(this), message_topic(this), message_uid(this), message_umode2(this)
- {
-
- this->AddModes();
- }
-
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
- {
- u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
- if (Servers::Capab.count("ESVID") == 0)
- IRCD->SendLogout(u);
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (!c->ci)
- return;
-
- ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
- if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && modelocks)
- {
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- if (!ci->c || !use_server_side_mlock || !modelocks || !Servers::Capab.count("MLOCK"))
- return;
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
- }
-
- void OnDelChan(ChannelInfo *ci) anope_override
- {
- if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
- return;
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :";
- }
-
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
- {
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
- {
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
- {
- ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
- ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
- {
- Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
- UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(ProtoUnreal)
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
deleted file mode 100644
index 9c56116b7..000000000
--- a/modules/pseudoclients/chanserv.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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/cs_mode.h"
-
-inline static Anope::string BotModes()
-{
- return Config->GetModule("botserv")->Get<Anope::string>("botmodes",
- Config->GetModule("chanserv")->Get<Anope::string>("botmodes", "o")
- );
-}
-
-class ChanServCore : public Module, public ChanServService
-{
- Reference<BotInfo> ChanServ;
- std::vector<Anope::string> defaults;
- ExtensibleItem<bool> inhabit;
- ExtensibleRef<bool> persist;
- bool always_lower;
-
- public:
- ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- ChanServService(this), inhabit(this, "inhabit"), persist("PERSIST"), always_lower(false)
- {
- }
-
- void Hold(Channel *c) anope_override
- {
- /** A timer used to keep the BotServ bot/ChanServ in the channel
- * after kicking the last user in a channel
- */
- class ChanServTimer : public Timer
- {
- Reference<BotInfo> &ChanServ;
- ExtensibleItem<bool> &inhabit;
- Reference<Channel> c;
-
- public:
- /** Constructor
- * @param chan The channel
- */
- ChanServTimer(Reference<BotInfo> &cs, ExtensibleItem<bool> &i, Module *m, Channel *chan) : Timer(m, Config->GetModule(m)->Get<time_t>("inhabit", "15s")), ChanServ(cs), inhabit(i), c(chan)
- {
- if (!ChanServ || !c)
- return;
- inhabit.Set(c, true);
- if (!c->ci || !c->ci->bi)
- ChanServ->Join(c);
- else if (!c->FindUser(c->ci->bi))
- c->ci->bi->Join(c);
-
- /* Set +ntsi to prevent rejoin */
- c->SetMode(NULL, "NOEXTERNAL");
- c->SetMode(NULL, "TOPIC");
- c->SetMode(NULL, "SECRET");
- c->SetMode(NULL, "INVITE");
- }
-
- /** Called when the delay is up
- * @param The current time
- */
- void Tick(time_t) anope_override
- {
- if (!c)
- return;
-
- /* In the event we don't part */
- c->RemoveMode(NULL, "SECRET");
- c->RemoveMode(NULL, "INVITE");
-
- inhabit.Unset(c); /* now we're done changing modes, unset inhabit */
-
- if (!c->ci || !c->ci->bi)
- {
- if (ChanServ)
- ChanServ->Part(c);
- }
- /* If someone has rejoined this channel in the meantime, don't part the bot */
- else if (c->users.size() <= 1)
- c->ci->bi->Part(c);
- }
- };
-
- if (inhabit.HasExt(c))
- return;
-
- new ChanServTimer(ChanServ, inhabit, this->owner, c);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &channick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (channick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(channick, true);
- if (!bi)
- throw ConfigException(Module::name + ": no bot named " + channick);
-
- ChanServ = bi;
-
- spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy")).GetTokens(defaults);
- if (defaults.empty())
- {
- defaults.push_back("KEEPTOPIC");
- defaults.push_back("CS_SECURE");
- defaults.push_back("SECUREFOUNDER");
- defaults.push_back("SIGNKICK");
- }
- else if (defaults[0].equals_ci("none"))
- defaults.clear();
-
- always_lower = conf->GetModule(this)->Get<bool>("always_lower_ts");
- }
-
- void OnBotDelete(BotInfo *bi) anope_override
- {
- if (bi == ChanServ)
- ChanServ = NULL;
- }
-
- EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
- {
- if (bi == ChanServ && Config->GetModule(this)->Get<bool>("opersonly") && !u->HasMode("OPER"))
- {
- u->SendMessage(bi, ACCESS_DENIED);
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnDelCore(NickCore *nc) anope_override
- {
- std::deque<ChannelInfo *> chans;
- nc->GetChannelReferences(chans);
- int max_reg = Config->GetModule(this)->Get<int>("maxregistered");
-
- for (unsigned i = 0; i < chans.size(); ++i)
- {
- ChannelInfo *ci = chans[i];
-
- if (ci->GetFounder() == nc)
- {
- NickCore *newowner = NULL;
- if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->channelcount < max_reg))
- newowner = ci->GetSuccessor();
- else
- {
- const ChanAccess *highest = NULL;
- for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
- {
- const ChanAccess *ca = ci->GetAccess(j);
- NickCore *anc = ca->GetAccount();
-
- if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc))
- continue;
- if (!highest || *ca > *highest)
- highest = ca;
- }
- if (highest)
- newowner = highest->GetAccount();
- }
-
- if (newowner)
- {
- Log(LOG_NORMAL, "chanserv/drop", ChanServ) << "Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to " << newowner->display;
- ci->SetFounder(newowner);
- ci->SetSuccessor(NULL);
- }
- else
- {
- Log(LOG_NORMAL, "chanserv/drop", ChanServ) << "Deleting channel " << ci->name << " owned by deleted nick " << nc->display;
-
- delete ci;
- continue;
- }
- }
-
- if (ci->GetSuccessor() == nc)
- ci->SetSuccessor(NULL);
-
- for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
- {
- const ChanAccess *ca = ci->GetAccess(j);
-
- if (ca->GetAccount() == nc)
- {
- delete ci->EraseAccess(j);
- break;
- }
- }
-
- for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
- {
- const AutoKick *akick = ci->GetAkick(j);
- if (akick->nc == nc)
- {
- ci->EraseAkick(j);
- break;
- }
- }
- }
- }
-
- void OnDelChan(ChannelInfo *ci) anope_override
- {
- /* remove access entries that are this channel */
-
- std::deque<Anope::string> chans;
- ci->GetChannelReferences(chans);
-
- for (unsigned i = 0; i < chans.size(); ++i)
- {
- ChannelInfo *c = ChannelInfo::Find(chans[i]);
- if (!c)
- continue;
-
- for (unsigned j = 0; j < c->GetAccessCount(); ++j)
- {
- ChanAccess *a = c->GetAccess(j);
-
- if (a->Mask().equals_ci(ci->name))
- {
- delete a;
- break;
- }
- }
- }
-
- if (ci->c)
- {
- ci->c->RemoveMode(ci->WhoSends(), "REGISTERED", "", false);
-
- const Anope::string &require = Config->GetModule(this)->Get<const Anope::string>("require");
- if (!require.empty())
- ci->c->SetModes(ci->WhoSends(), false, "-%s", require.c_str());
- }
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *ChanServ)
- return EVENT_CONTINUE;
- 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"),
- ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), source.command.c_str());
- return EVENT_CONTINUE;
- }
-
- void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *ChanServ)
- return;
- time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
- if (chanserv_expire >= 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."), chanserv_expire / 86400);
- if (source.IsServicesOper())
- source.Reply(_(" \n"
- "Services Operators can also, depending on their access drop\n"
- "any channel, view (and modify) the access, levels and akick\n"
- "lists and settings for any channel."));
- }
-
- void OnCheckModes(Reference<Channel> &c) anope_override
- {
- if (!c)
- return;
-
- if (c->ci)
- c->SetMode(c->ci->WhoSends(), "REGISTERED", "", false);
- else
- c->RemoveMode(c->ci->WhoSends(), "REGISTERED", "", false);
-
- const Anope::string &require = Config->GetModule(this)->Get<const Anope::string>("require");
- if (!require.empty())
- {
- if (c->ci)
- c->SetModes(c->ci->WhoSends(), false, "+%s", require.c_str());
- else
- c->SetModes(c->ci->WhoSends(), false, "-%s", require.c_str());
- }
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- /* Set default chan flags */
- for (unsigned i = 0; i < defaults.size(); ++i)
- ci->Extend<bool>(defaults[i].upper());
- }
-
- EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_override
- {
- if (Config->GetModule(this)->Get<const Anope::string>("nomlock").find(cm->mchar) != Anope::string::npos
- || Config->GetModule(this)->Get<const Anope::string>("require").find(cm->mchar) != Anope::string::npos)
- return EVENT_STOP;
- return EVENT_CONTINUE;
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- bool perm = c->HasMode("PERM") || (c->ci && persist && persist->HasExt(c->ci));
- if (!perm && !c->botchannel && (c->users.empty() || (c->users.size() == 1 && c->users.begin()->second->user->server == Me)))
- {
- this->Hold(c);
- }
- }
-
- void OnLog(Log *l) anope_override
- {
- if (l->type == LOG_CHANNEL)
- l->bi = ChanServ;
- }
-
- void OnExpireTick() anope_override
- {
- time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
-
- if (!chanserv_expire || Anope::NoExpire || Anope::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 (Anope::CurTime - ci->last_used >= chanserv_expire)
- {
- if (ci->c)
- {
- time_t last_used = ci->last_used;
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
- ci->AccessFor(cit->second->user);
- expire = last_used == ci->last_used;
- }
- else
- expire = true;
- }
-
- FOREACH_MOD(OnPreChanExpire, (ci, expire));
-
- if (expire)
- {
- Log(LOG_NORMAL, "chanserv/expire", ChanServ) << "Expiring channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
- FOREACH_MOD(OnChanExpire, (ci));
- delete ci;
- }
- }
- }
-
- EventReturn OnCheckDelete(Channel *c) anope_override
- {
- /* Do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
- if (inhabit.HasExt(c))
- return EVENT_STOP;
-
- return EVENT_CONTINUE;
- }
-
- void OnPreUplinkSync(Server *serv) anope_override
- {
- if (!persist)
- return;
- /* Find all persistent channels and create them, as we are about to finish burst to our uplink */
- for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- ChannelInfo *ci = it->second;
- if (persist->HasExt(ci))
- {
- bool c;
- ci->c = Channel::FindOrCreate(ci->name, c, ci->time_registered);
-
- if (ModeManager::FindChannelModeByName("PERM") != NULL)
- {
- if (c)
- IRCD->SendChannel(ci->c);
- ci->c->SetMode(NULL, "PERM");
- }
- else
- {
- if (!ci->bi)
- ci->WhoSends()->Assign(NULL, ci);
- if (ci->c->FindUser(ci->bi) == NULL)
- {
- ChannelStatus status(BotModes());
- ci->bi->Join(ci->c, &status);
- }
- }
- }
- }
-
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- if (!persist || !ci->c)
- return;
- /* Mark the channel as persistent */
- if (ci->c->HasMode("PERM"))
- persist->Set(ci);
- /* Persist may be in def cflags, set it here */
- else if (persist->HasExt(ci))
- ci->c->SetMode(NULL, "PERM");
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (always_lower && c->ci && c->creation_time > c->ci->time_registered)
- {
- Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
- c->creation_time = c->ci->time_registered;
- IRCD->SendChannel(c);
- c->Reset();
- }
- }
-
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (!always_lower && Anope::CurTime == c->creation_time && c->ci && setter.GetUser() && !setter.GetUser()->server->IsULined())
- {
- ChanUserContainer *cu = c->FindUser(setter.GetUser());
- ChannelMode *cm = ModeManager::FindChannelModeByName("OP");
- if (cu && cm && !cu->status.HasMode(cm->mchar))
- {
- /* Our -o and their mode change crossing, bounce their mode */
- c->RemoveMode(c->ci->WhoSends(), mode, param);
- /* We don't set mlocks until after the join has finished processing, it will stack with this change,
- * so there isn't much for the user to remove except -nt etc which is likely locked anyway.
- */
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- time_t chanserv_expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
- if (!ci->HasExt("CS_NO_EXPIRE") && chanserv_expire && !Anope::NoExpire && ci->last_used != Anope::CurTime)
- info[_("Expires")] = Anope::strftime(ci->last_used + chanserv_expire, source.GetAccount());
- }
-
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
- {
- if (always_lower)
- // Since we always lower the TS, the other side will remove the modes if the channel ts lowers, so we don't
- // have to worry about it
- take_modes = false;
- else if (ModeManager::FindChannelModeByName("REGISTERED"))
- // Otherwise if the registered channel mode exists, we should remove modes if the channel is not +r
- take_modes = !chan->HasMode("REGISTERED");
- }
-};
-
-MODULE_INIT(ChanServCore)
-
diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp
deleted file mode 100644
index 065627cb2..000000000
--- a/modules/pseudoclients/global.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Global core functions
- *
- * (C) 2003-2016 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 GlobalCore : public Module, public GlobalService
-{
- Reference<BotInfo> Global;
-
- void ServerGlobal(BotInfo *sender, Server *s, const Anope::string &message)
- {
- if (s != Me && !s->IsJuped())
- s->Notice(sender, message);
- for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
- this->ServerGlobal(sender, s->GetLinks()[i], message);
- }
-
- public:
- GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- GlobalService(this)
- {
- }
-
- void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message) anope_override
- {
- if (Me->GetLinks().empty())
- return;
- if (!sender)
- sender = Global;
- if (!sender)
- return;
-
- Anope::string rmessage;
-
- if (!source.empty() && !Config->GetModule("global")->Get<bool>("anonymousglobal"))
- rmessage = "[" + source + "] " + message;
- else
- rmessage = message;
-
- this->ServerGlobal(sender, Servers::GetUplink(), rmessage);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &glnick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (glnick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(glnick, true);
- if (!bi)
- throw ConfigException(Module::name + ": no bot named " + glnick);
-
- Global = bi;
- }
-
- void OnRestart() anope_override
- {
- const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown");
- if (!gl.empty())
- this->SendGlobal(Global, "", gl);
- }
-
- void OnShutdown() anope_override
- {
- const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown");
- if (!gl.empty())
- this->SendGlobal(Global, "", gl);
- }
-
- void OnNewServer(Server *s) anope_override
- {
- const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycleup");
- if (!gl.empty() && !Me->IsSynced())
- s->Notice(Global, gl);
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *Global)
- return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), Global->nick.c_str());
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(GlobalCore)
-
diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp
deleted file mode 100644
index bb0f7e839..000000000
--- a/modules/pseudoclients/hostserv.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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 HostServCore : public Module
-{
- Reference<BotInfo> HostServ;
- public:
- HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &hsnick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (hsnick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(hsnick, true);
- if (!bi)
- throw ConfigException(Module::name + ": no bot named " + hsnick);
-
- HostServ = bi;
- }
-
- void OnUserLogin(User *u) anope_override
- {
- if (!IRCD->CanSetVHost)
- return;
-
- const NickAlias *na = NickAlias::Find(u->nick);
- if (!na || na->nc != u->Account() || !na->HasVhost())
- na = NickAlias::Find(u->Account()->display);
- if (!na || !na->HasVhost())
- return;
-
- if (u->vhost.empty() || !u->vhost.equals_cs(na->GetVhostHost()) || (!na->GetVhostIdent().empty() && !u->GetVIdent().equals_cs(na->GetVhostIdent())))
- {
- IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
-
- u->vhost = na->GetVhostHost();
- u->UpdateHost();
-
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- u->SetVIdent(na->GetVhostIdent());
-
- if (HostServ)
- {
- if (!na->GetVhostIdent().empty())
- u->SendMessage(HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- u->SendMessage(HostServ, _("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
- }
- }
- }
-
- void OnNickUpdate(User *u) anope_override
- {
- this->OnUserLogin(u);
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *HostServ)
- return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), HostServ->nick.c_str());
- return EVENT_CONTINUE;
- }
-
- void OnSetVhost(NickAlias *na) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("activate_on_set"))
- {
- User *u = User::Find(na->nick);
-
- if (u && u->Account() == na->nc)
- {
- IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
-
- u->vhost = na->GetVhostHost();
- u->UpdateHost();
-
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- u->SetVIdent(na->GetVhostIdent());
-
- if (HostServ)
- {
- if (!na->GetVhostIdent().empty())
- u->SendMessage(HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- u->SendMessage(HostServ, _("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
- }
- }
- }
- }
-
- void OnDeleteVhost(NickAlias *na) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("activate_on_set"))
- {
- User *u = User::Find(na->nick);
-
- if (u && u->Account() == na->nc)
- IRCD->SendVhostDel(u);
- }
- }
-};
-
-MODULE_INIT(HostServCore)
-
diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp
deleted file mode 100644
index 37e9545aa..000000000
--- a/modules/pseudoclients/memoserv.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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 MemoServCore : public Module, public MemoServService
-{
- Reference<BotInfo> MemoServ;
-
- bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
- {
- Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()),
- message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
-
- subject = subject.replace_all_cs("%n", nc->display);
- subject = subject.replace_all_cs("%s", m->sender);
- subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
- subject = subject.replace_all_cs("%t", m->text);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
-
- message = message.replace_all_cs("%n", nc->display);
- message = message.replace_all_cs("%s", m->sender);
- message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
- message = message.replace_all_cs("%t", m->text);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
-
- return Mail::Send(nc, subject, message);
- }
-
- public:
- MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- MemoServService(this)
- {
- }
-
- MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) anope_override
- {
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(target, ischan);
-
- if (mi == NULL)
- return MEMO_INVALID_TARGET;
-
- User *sender = User::Find(source, true);
- if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force)
- {
- time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
- if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime)
- return MEMO_TOO_FAST;
- else if (!mi->memomax)
- return MEMO_TARGET_FULL;
- else if (mi->memomax > 0 && mi->memos->size() >= static_cast<unsigned>(mi->memomax))
- return MEMO_TARGET_FULL;
- else if (mi->HasIgnore(sender))
- return MEMO_SUCCESS;
- }
-
- if (sender != NULL)
- sender->lastmemosend = Anope::CurTime;
-
- Memo *m = new Memo();
- m->mi = mi;
- mi->memos->push_back(m);
- m->owner = target;
- m->sender = source;
- m->time = Anope::CurTime;
- m->text = message;
- m->unread = true;
-
- FOREACH_MOD(OnMemoSend, (source, target, mi, m));
-
- if (ischan)
- {
- ChannelInfo *ci = ChannelInfo::Find(target);
-
- if (ci->c)
- {
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *cu = it->second;
-
- if (ci->AccessFor(cu->user).HasPriv("MEMO"))
- {
- if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE"))
- cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size());
- }
- }
- }
- }
- else
- {
- NickCore *nc = NickAlias::Find(target)->nc;
-
- if (nc->HasExt("MEMO_RECEIVE"))
- {
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- const NickAlias *na = nc->aliases->at(i);
- User *user = User::Find(na->nick, true);
- if (user && user->IsIdentified())
- user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size());
- }
- }
-
- /* let's get out the mail if set in the nickcore - certus */
- if (nc->HasExt("MEMO_MAIL"))
- SendMemoMail(nc, mi, m);
- }
-
- return MEMO_SUCCESS;
- }
-
- void Check(User *u)
- {
- const NickCore *nc = u->Account();
- if (!nc)
- return;
-
- unsigned i = 0, end = nc->memos.memos->size(), newcnt = 0;
- for (; i < end; ++i)
- if (nc->memos.GetMemo(i)->unread)
- ++newcnt;
- if (newcnt > 0)
- u->SendMessage(MemoServ, newcnt == 1 ? _("You have 1 new memo.") : _("You have %d new memos."), newcnt);
- if (nc->memos.memomax > 0 && nc->memos.memos->size() >= static_cast<unsigned>(nc->memos.memomax))
- {
- if (nc->memos.memos->size() > static_cast<unsigned>(nc->memos.memomax))
- u->SendMessage(MemoServ, _("You are over your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->memos.memomax);
- else
- u->SendMessage(MemoServ, _("You have reached your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->memos.memomax);
- }
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (msnick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(msnick, true);
- if (!bi)
- throw ConfigException(Module::name + ": no bot named " + msnick);
-
- MemoServ = bi;
- }
-
- void OnNickCoreCreate(NickCore *nc) anope_override
- {
- nc->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- ci->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
- }
-
- void OnBotDelete(BotInfo *bi) anope_override
- {
- if (bi == MemoServ)
- MemoServ = NULL;
- }
-
- void OnNickIdentify(User *u) anope_override
- {
- this->Check(u);
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (c->ci && !c->ci->memos.memos->empty() && c->ci->AccessFor(u).HasPriv("MEMO"))
- {
- if (c->ci->memos.memos->size() == 1)
- u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
- else
- u->SendMessage(MemoServ, _("There are \002%d\002 memos on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
- }
- }
-
- void OnUserAway(User *u, const Anope::string &message) anope_override
- {
- if (message.empty())
- this->Check(u);
- }
-
- void OnNickUpdate(User *u) anope_override
- {
- this->Check(u);
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *MemoServ)
- return EVENT_CONTINUE;
- source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
- "messages to other IRC users, whether they are online at\n"
- "the time or not, or to channels(*). Both the sender's\n"
- "nickname and the target nickname or channel must be\n"
- "registered in order to send a memo.\n"
- "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
- return EVENT_CONTINUE;
- }
-
- void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *MemoServ)
- return;
- source.Reply(_(" \n"
- "Type \002%s%s HELP \037command\037\002 for help on any of the\n"
- "above commands."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str());
- }
-};
-
-MODULE_INIT(MemoServCore)
-
diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp
deleted file mode 100644
index 9049a0fe1..000000000
--- a/modules/pseudoclients/nickserv.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 NickServCollide;
-static std::set<NickServCollide *> collides;
-
-/** Timer for colliding nicks to force people off of nicknames
- */
-class NickServCollide : public Timer
-{
- NickServService *service;
- Reference<User> u;
- time_t ts;
- Reference<NickAlias> na;
-
- public:
- NickServCollide(Module *me, NickServService *nss, User *user, NickAlias *nick, time_t delay) : Timer(me, delay), service(nss), u(user), ts(user->timestamp), na(nick)
- {
- collides.insert(this);
- }
-
- ~NickServCollide()
- {
- collides.erase(this);
- }
-
- User *GetUser()
- {
- return u;
- }
-
- NickAlias *GetNick()
- {
- return na;
- }
-
- void Tick(time_t t) anope_override
- {
- if (!u || !na)
- return;
- /* If they identified or don't exist anymore, don't kill them. */
- if (u->Account() == na->nc || u->timestamp > ts)
- return;
-
- service->Collide(u, na);
- }
-};
-
-/** Timer for removing HELD status from nicks.
- */
-class NickServHeld : public Timer
-{
- Reference<NickAlias> na;
- Anope::string nick;
- public:
- NickServHeld(Module *me, NickAlias *n, long l) : Timer(me, l), na(n), nick(na->nick)
- {
- n->Extend<bool>("HELD");
- }
-
- void Tick(time_t)
- {
- if (na)
- na->Shrink<bool>("HELD");
- }
-};
-
-class NickServRelease;
-static Anope::map<NickServRelease *> NickServReleases;
-
-/** Timer for releasing nicks to be available for use
- */
-class NickServRelease : public User, public Timer
-{
- Anope::string nick;
-
- public:
- NickServRelease(Module *me, NickAlias *na, time_t delay) : User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"),
- Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", "services.localhost.net"), "", "", Me, "Services Enforcer", Anope::CurTime, "", IRCD->UID_Retrieve(), NULL), Timer(me, delay), nick(na->nick)
- {
- /* Erase the current release timer and use the new one */
- Anope::map<NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
- if (nit != NickServReleases.end())
- {
- IRCD->SendQuit(nit->second, "");
- delete nit->second;
- }
-
- NickServReleases.insert(std::make_pair(this->nick, this));
-
- IRCD->SendClientIntroduction(this);
- }
-
- ~NickServRelease()
- {
- IRCD->SendQuit(this, "");
- NickServReleases.erase(this->nick);
- }
-
- void Tick(time_t t) anope_override { }
-};
-
-class NickServCore : public Module, public NickServService
-{
- Reference<BotInfo> NickServ;
- std::vector<Anope::string> defaults;
- ExtensibleItem<bool> held, collided;
-
- void OnCancel(User *u, NickAlias *na)
- {
- if (collided.HasExt(na))
- {
- collided.Unset(na);
-
- new NickServHeld(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
-
- if (IRCD->CanSVSHold)
- IRCD->SendSVSHold(na->nick, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
- else
- new NickServRelease(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m"));
- }
- }
-
- public:
- NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- NickServService(this), held(this, "HELD"), collided(this, "COLLIDED")
- {
- }
-
- ~NickServCore()
- {
- OnShutdown();
- }
-
- void OnShutdown() anope_override
- {
- /* On shutdown, restart, or mod unload, remove all of our holds for nicks (svshold or qlines)
- * because some IRCds do not allow us to have these automatically expire
- */
- for (nickalias_map::const_iterator it = NickAliasList->begin(); it != NickAliasList->end(); ++it)
- this->Release(it->second);
- }
-
- void OnRestart() anope_override
- {
- OnShutdown();
- }
-
- void Validate(User *u) anope_override
- {
- NickAlias *na = NickAlias::Find(u->nick);
- if (!na)
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnNickValidate, MOD_RESULT, (u, na));
- if (MOD_RESULT == EVENT_STOP)
- {
- this->Collide(u, na);
- return;
- }
- else if (MOD_RESULT == EVENT_ALLOW)
- return;
-
- if (!na->nc->HasExt("NS_SECURE") && u->IsRecognized())
- {
- na->last_seen = Anope::CurTime;
- na->last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_realname = u->realname;
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- return;
-
- bool on_access = u->IsRecognized(false);
-
- if (on_access || !na->nc->HasExt("KILL_IMMED"))
- {
- if (na->nc->HasExt("NS_SECURE"))
- u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
- else
- u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
- }
- if (na->nc->HasExt("KILLPROTECT") && !on_access)
- {
- if (na->nc->HasExt("KILL_IMMED"))
- {
- u->SendMessage(NickServ, FORCENICKCHANGE_NOW);
- this->Collide(u, na);
- }
- else if (na->nc->HasExt("KILL_QUICK"))
- {
- time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "20s");
- u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str());
- new NickServCollide(this, this, u, na, killquick);
- }
- else
- {
- time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "60s");
- u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str());
- new NickServCollide(this, this, u, na, kill);
- }
- }
-
- }
-
- void OnUserLogin(User *u) anope_override
- {
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && *na->nc == u->Account() && !Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !na->nc->HasExt("UNCONFIRMED"))
- u->SetMode(NickServ, "REGISTERED");
-
- const Anope::string &modesonid = Config->GetModule(this)->Get<Anope::string>("modesonid");
- if (!modesonid.empty())
- u->SetModes(NickServ, "%s", modesonid.c_str());
- }
-
- void Collide(User *u, NickAlias *na) anope_override
- {
- if (na)
- collided.Set(na);
-
- if (IRCD->CanSVSNick)
- {
- unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
- const Anope::string &guestprefix = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
-
- Anope::string guestnick;
-
- int i = 0;
- do
- {
- guestnick = guestprefix + stringify(static_cast<uint16_t>(rand()));
- if (guestnick.length() > nicklen)
- guestnick = guestnick.substr(0, nicklen);
- }
- while (User::Find(guestnick) && i++ < 10);
-
- if (i == 11)
- u->Kill(*NickServ, "Services nickname-enforcer kill");
- else
- {
- u->SendMessage(*NickServ, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str());
- IRCD->SendForceNickChange(u, guestnick, Anope::CurTime);
- }
- }
- else
- u->Kill(*NickServ, "Services nickname-enforcer kill");
- }
-
- void Release(NickAlias *na) anope_override
- {
- if (held.HasExt(na))
- {
- if (IRCD->CanSVSHold)
- IRCD->SendSVSHoldDel(na->nick);
- else
- {
- User *u = User::Find(na->nick);
- if (u && u->server == Me)
- {
- u->Quit();
- }
- }
-
- held.Unset(na);
- }
- collided.Unset(na); /* clear pending collide */
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &nsnick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (nsnick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(nsnick, true);
- if (!bi)
- throw ConfigException(Module::name + ": no bot named " + nsnick);
-
- NickServ = bi;
-
- spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "ns_secure memo_signon memo_receive")).GetTokens(defaults);
- if (defaults.empty())
- {
- defaults.push_back("NS_SECURE");
- defaults.push_back("MEMO_SIGNON");
- defaults.push_back("MEMO_RECEIVE");
- }
- else if (defaults[0].equals_ci("none"))
- defaults.clear();
- }
-
- void OnDelNick(NickAlias *na) anope_override
- {
- User *u = User::Find(na->nick);
- if (u && u->Account() == na->nc)
- {
- IRCD->SendLogout(u);
- u->RemoveMode(NickServ, "REGISTERED");
- u->Logout();
- }
- }
-
- void OnDelCore(NickCore *nc) anope_override
- {
- Log(NickServ, "nick") << "Deleting nickname group " << nc->display;
-
- /* Clean up this nick core from any users online */
- for (std::list<User *>::iterator it = nc->users.begin(); it != nc->users.end();)
- {
- User *user = *it++;
- IRCD->SendLogout(user);
- user->RemoveMode(NickServ, "REGISTERED");
- user->Logout();
- FOREACH_MOD(OnNickLogout, (user));
- }
- nc->users.clear();
- }
-
- void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override
- {
- Log(LOG_NORMAL, "nick", NickServ) << "Changing " << nc->display << " nickname group display to " << newdisplay;
- }
-
- void OnNickIdentify(User *u) anope_override
- {
- Configuration::Block *block = Config->GetModule(this);
-
- if (block->Get<bool>("modeonid", "yes"))
-
- for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
- {
- ChanUserContainer *cc = it->second;
- Channel *c = cc->chan;
- if (c)
- c->SetCorrectModes(u, true);
- }
-
- const Anope::string &modesonid = block->Get<const Anope::string>("modesonid");
- if (!modesonid.empty())
- u->SetModes(NickServ, "%s", modesonid.c_str());
-
- if (block->Get<bool>("forceemail", "yes") && u->Account()->email.empty())
- {
- u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n"
- "This e-mail will allow you to retrieve your password in\n"
- "case you forget it."));
- u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n"
- "Your privacy is respected; this e-mail won't be given to\n"
- "any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
- }
-
- for (std::set<NickServCollide *>::iterator it = collides.begin(); it != collides.end(); ++it)
- {
- NickServCollide *c = *it;
- if (c->GetUser() == u && c->GetNick() && c->GetNick()->nc == u->Account())
- {
- delete c;
- break;
- }
- }
- }
-
- void OnNickGroup(User *u, NickAlias *target) anope_override
- {
- if (!target->nc->HasExt("UNCONFIRMED"))
- u->SetMode(NickServ, "REGISTERED");
- }
-
- void OnNickUpdate(User *u) anope_override
- {
- for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
- {
- ChanUserContainer *cc = it->second;
- Channel *c = cc->chan;
- if (c)
- c->SetCorrectModes(u, true);
- }
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (u->Quitting() || !u->server->IsSynced() || u->server->IsULined())
- return;
-
- const NickAlias *na = NickAlias::Find(u->nick);
-
- const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string>("unregistered_notice");
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na && !u->Account())
- u->SendMessage(NickServ, unregistered_notice.replace_all_cs("%n", u->nick));
- else if (na && !u->IsIdentified(true))
- this->Validate(u);
- }
-
- void OnPostUserLogoff(User *u) anope_override
- {
- NickAlias *na = NickAlias::Find(u->nick);
- if (na)
- OnCancel(u, na);
- }
-
- void OnServerSync(Server *s) anope_override
- {
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
-
- if (u->server == s)
- {
- if (u->HasMode("REGISTERED") && !u->IsIdentified(true))
- u->RemoveMode(NickServ, "REGISTERED");
- if (!u->IsIdentified())
- this->Validate(u);
- }
- }
- }
-
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
- {
- NickAlias *old_na = NickAlias::Find(oldnick), *na = NickAlias::Find(u->nick);
- /* If the new nick isn't registered or it's registered and not yours */
- if (!na || na->nc != u->Account())
- {
- /* Remove +r, but keep an account associated with the user */
- u->RemoveMode(NickServ, "REGISTERED");
-
- this->Validate(u);
- }
- else
- {
- /* Reset +r and re-send account (even though it really should be set at this point) */
- IRCD->SendLogin(u, na);
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && na->nc == u->Account() && !na->nc->HasExt("UNCONFIRMED"))
- u->SetMode(NickServ, "REGISTERED");
- Log(u, "", NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display;
- }
-
- if (!u->nick.equals_ci(oldnick) && old_na)
- OnCancel(u, old_na);
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (u->server->IsSynced() && mname == "REGISTERED" && !u->IsIdentified(true))
- u->RemoveMode(NickServ, mname);
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *NickServ)
- return EVENT_CONTINUE;
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- source.Reply(_("\002%s\002 allows you to register a nickname and\n"
- "prevent others from using it. The following\n"
- "commands allow for registration and maintenance of\n"
- "nicknames; to use them, type \002%s%s \037command\037\002.\n"
- "For more information on a specific command, type\n"
- "\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
- else
- source.Reply(_("\002%s\002 allows you to register an account.\n"
- "The following commands allow for registration and maintenance of\n"
- "accounts; to use them, type \002%s%s \037command\037\002.\n"
- "For more information on a specific command, type\n"
- "\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
- return EVENT_CONTINUE;
- }
-
- void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *NickServ)
- return;
- if (source.IsServicesOper())
- source.Reply(_(" \n"
- "Services Operators can also drop any nickname without needing\n"
- "to identify for the nick, and may view the access list for\n"
- "any nickname."));
- time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
- if (nickserv_expire >= 86400)
- source.Reply(_(" \n"
- "Accounts that are not used anymore are subject to\n"
- "the automatic expiration, i.e. they will be deleted\n"
- "after %d days if not used."), nickserv_expire / 86400);
- source.Reply(_(" \n"
- "\002NOTICE:\002 This service is intended to provide a way for\n"
- "IRC users to ensure their identity is not compromised.\n"
- "It is \002NOT\002 intended to facilitate \"stealing\" of\n"
- "nicknames or other malicious actions. Abuse of %s\n"
- "will result in, at minimum, loss of the abused\n"
- "nickname(s)."), NickServ->nick.c_str());
- }
-
- void OnNickCoreCreate(NickCore *nc)
- {
- /* Set default flags */
- for (unsigned i = 0; i < defaults.size(); ++i)
- nc->Extend<bool>(defaults[i].upper());
- }
-
- void OnUserQuit(User *u, const Anope::string &msg)
- {
- if (u->server && !u->server->GetQuitReason().empty() && Config->GetModule(this)->Get<bool>("hidenetsplitquit"))
- return;
-
- /* Update last quit and last seen for the user */
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && !na->nc->HasExt("NS_SUSPENDED") && (u->IsRecognized() || u->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = msg;
- }
- }
-
- void OnExpireTick() anope_override
- {
- if (Anope::NoExpire || Anope::ReadOnly)
- return;
-
- time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
- {
- NickAlias *na = it->second;
- ++it;
-
- User *u = User::Find(na->nick, true);
- if (u && (u->IsIdentified(true) || u->IsRecognized()))
- na->last_seen = Anope::CurTime;
-
- bool expire = false;
-
- if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire)
- expire = true;
-
- FOREACH_MOD(OnPreNickExpire, (na, expire));
-
- if (expire)
- {
- Log(LOG_NORMAL, "nickserv/expire", NickServ) << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " << (na->nc->email.empty() ? "none" : na->nc->email) << ")";
- FOREACH_MOD(OnNickExpire, (na));
- delete na;
- }
- }
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!na->nc->HasExt("UNCONFIRMED"))
- {
- time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "21d");
- if (!na->HasExt("NS_NO_EXPIRE") && nickserv_expire && !Anope::NoExpire && (source.HasPriv("nickserv/auspex") || na->last_seen != Anope::CurTime))
- info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire, source.GetAccount());
- }
- else
- {
- time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
- info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire, source.GetAccount());
- }
- }
-};
-
-MODULE_INIT(NickServCore)
-
diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp
deleted file mode 100644
index f443aed95..000000000
--- a/modules/pseudoclients/operserv.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 SGLineManager : public XLineManager
-{
- public:
- SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { }
-
- void OnMatch(User *u, XLine *x) anope_override
- {
- this->Send(u, x);
- }
-
- void OnExpire(const XLine *x) anope_override
- {
- Log(Config->GetClient("OperServ"), "expire/akill") << "AKILL on \002" << x->mask << "\002 has expired";
- }
-
- void Send(User *u, XLine *x) anope_override
- {
- IRCD->SendAkill(u, x);
- }
-
- void SendDel(XLine *x) anope_override
- {
- IRCD->SendAkillDel(x);
- }
-
- bool Check(User *u, const XLine *x) anope_override
- {
- if (x->regex)
- {
- Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname;
- return x->regex->Matches(uh) || x->regex->Matches(nuhr);
- }
-
- if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick()))
- return false;
-
- if (!x->GetUser().empty() && !Anope::Match(u->GetIdent(), x->GetUser()))
- return false;
-
- if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal()))
- return false;
-
- if (x->c && x->c->match(u->ip))
- return true;
-
- if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip.addr(), x->GetHost()))
- return true;
-
- return false;
- }
-};
-
-class SQLineManager : public XLineManager
-{
- ServiceReference<NickServService> nickserv;
-
- public:
- SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q'), nickserv("NickServService", "NickServ") { }
-
- void OnMatch(User *u, XLine *x) anope_override
- {
- this->Send(u, x);
- }
-
- void OnExpire(const XLine *x) anope_override
- {
- Log(Config->GetClient("OperServ"), "expire/sqline") << "SQLINE on \002" << x->mask << "\002 has expired";
- }
-
- void Send(User *u, XLine *x) anope_override
- {
- if (!IRCD->CanSQLine)
- {
- if (!u)
- ;
- else if (nickserv)
- nickserv->Collide(u, NULL);
- else
- u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
- }
- else if (x->IsRegex())
- {
- if (u)
- u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
- }
- else if (x->mask[0] != '#' || IRCD->CanSQLineChannel)
- {
- IRCD->SendSQLine(u, x);
- /* If it is an oper, assume they're walking it, otherwise kill for good measure */
- if (u && !u->HasMode("OPER"))
- u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
- }
- }
-
- void SendDel(XLine *x) anope_override
- {
- if (!IRCD->CanSQLine || x->IsRegex())
- ;
- else if (x->mask[0] != '#' || IRCD->CanSQLineChannel)
- IRCD->SendSQLineDel(x);
- }
-
- bool Check(User *u, const XLine *x) anope_override
- {
- if (x->regex)
- return x->regex->Matches(u->nick);
- return Anope::Match(u->nick, x->mask);
- }
-
- XLine *CheckChannel(Channel *c)
- {
- for (std::vector<XLine *>::const_iterator it = this->GetList().begin(), it_end = this->GetList().end(); it != it_end; ++it)
- {
- XLine *x = *it;
-
- if (x->regex)
- {
- if (x->regex->Matches(c->name))
- return x;
- }
- else
- {
- if (x->mask.empty() || x->mask[0] != '#')
- continue;
-
- if (Anope::Match(c->name, x->mask, false, true))
- return x;
- }
- }
- return NULL;
- }
-};
-
-class SNLineManager : public XLineManager
-{
- public:
- SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { }
-
- void OnMatch(User *u, XLine *x) anope_override
- {
- this->Send(u, x);
- }
-
- void OnExpire(const XLine *x) anope_override
- {
- Log(Config->GetClient("OperServ"), "expire/snline") << "SNLINE on \002" << x->mask << "\002 has expired";
- }
-
- void Send(User *u, XLine *x) anope_override
- {
- if (IRCD->CanSNLine && !x->IsRegex())
- IRCD->SendSGLine(u, x);
-
- if (u)
- u->Kill(Config->GetClient("OperServ"), "SNLined: " + x->reason);
- }
-
- void SendDel(XLine *x) anope_override
- {
- if (IRCD->CanSNLine && !x->IsRegex())
- IRCD->SendSGLineDel(x);
- }
-
- bool Check(User *u, const XLine *x) anope_override
- {
- if (x->regex)
- return x->regex->Matches(u->realname);
- return Anope::Match(u->realname, x->mask, false, true);
- }
-};
-
-class OperServCore : public Module
-{
- Reference<BotInfo> OperServ;
- SGLineManager sglines;
- SQLineManager sqlines;
- SNLineManager snlines;
-
- public:
- OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- sglines(this), sqlines(this), snlines(this)
- {
-
- /* Yes, these are in this order for a reason. Most violent->least violent. */
- XLineManager::RegisterXLineManager(&sglines);
- XLineManager::RegisterXLineManager(&sqlines);
- XLineManager::RegisterXLineManager(&snlines);
- }
-
- ~OperServCore()
- {
- this->sglines.Clear();
- this->sqlines.Clear();
- this->snlines.Clear();
-
- XLineManager::UnregisterXLineManager(&sglines);
- XLineManager::UnregisterXLineManager(&sqlines);
- XLineManager::UnregisterXLineManager(&snlines);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- const Anope::string &osnick = conf->GetModule(this)->Get<const Anope::string>("client");
-
- if (osnick.empty())
- throw ConfigException(this->name + ": <client> must be defined");
-
- BotInfo *bi = BotInfo::Find(osnick, true);
- if (!bi)
- throw ConfigException(this->name + ": no bot named " + osnick);
-
- OperServ = bi;
- }
-
- EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
- {
- if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly"))
- {
- u->SendMessage(bi, ACCESS_DENIED);
- Log(bi, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)";
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnServerQuit(Server *server) anope_override
- {
- if (server->IsJuped())
- Log(server, "squit", OperServ) << "Received SQUIT for juped server " << server->GetName();
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (mname == "OPER")
- Log(u, "oper", OperServ) << "is now an IRC operator.";
- }
-
- void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (mname == "OPER")
- Log(u, "oper", OperServ) << "is no longer an IRC operator";
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (!u->Quitting() && !exempt)
- XLineManager::CheckAll(u);
- }
-
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
- {
- if (!u->HasMode("OPER"))
- this->sqlines.CheckAllXLines(u);
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- XLine *x = this->sqlines.CheckChannel(c);
- if (x)
- {
- this->sqlines.OnMatch(u, x);
- reason = x->reason;
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!params.empty() || source.c || source.service != *OperServ)
- return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), OperServ->nick.c_str());
- return EVENT_CONTINUE;
- }
-
- void OnLog(Log *l) anope_override
- {
- if (l->type == LOG_SERVER)
- l->bi = OperServ;
- }
-};
-
-MODULE_INIT(OperServCore)
-
diff --git a/modules/m_redis.cpp b/modules/redis.cpp
index d8398c1b5..7a519a4e7 100644
--- a/modules/m_redis.cpp
+++ b/modules/redis.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -25,10 +36,10 @@ class RedisSocket : public BinarySocket, public ConnectionSocket
~RedisSocket();
- void OnConnect() anope_override;
- void OnError(const Anope::string &error) anope_override;
+ void OnConnect() override;
+ void OnError(const Anope::string &error) override;
- bool Read(const char *buffer, size_t l) anope_override;
+ bool Read(const char *buffer, size_t l) override;
};
class Transaction : public Interface
@@ -51,7 +62,7 @@ class Transaction : public Interface
}
}
- void OnResult(const Reply &r) anope_override
+ void OnResult(const Reply &r) override
{
/* This is a multi bulk reply of the results of the queued commands
* in this transaction
@@ -165,13 +176,6 @@ class MyRedisService : public Provider
this->Send(s, i, args);
}
- void SendCommand(RedisSocket *s, Interface *i, const Anope::string &str)
- {
- std::vector<Anope::string> args;
- spacesepstream(str).GetTokens(args);
- this->SendCommand(s, i, args);
- }
-
void Send(Interface *i, const std::vector<std::pair<const char *, size_t> > &args)
{
if (!sock)
@@ -183,7 +187,7 @@ class MyRedisService : public Provider
this->Send(sock, i, args);
}
- void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) anope_override
+ void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) override
{
std::vector<std::pair<const char *, size_t> > args;
for (unsigned j = 0; j < cmds.size(); ++j)
@@ -191,15 +195,14 @@ class MyRedisService : public Provider
this->Send(i, args);
}
- void SendCommand(Interface *i, const Anope::string &str) anope_override
+ void SendCommand(Interface *i, const Anope::string &str) override
{
std::vector<Anope::string> args;
spacesepstream(str).GetTokens(args);
this->SendCommand(i, args);
}
- public:
- bool BlockAndProcess() anope_override
+ bool BlockAndProcess() override
{
this->sock->ProcessWrite();
this->sock->SetBlocking(true);
@@ -208,7 +211,7 @@ class MyRedisService : public Provider
return !this->sock->interfaces.empty();
}
- void Subscribe(Interface *i, const Anope::string &pattern) anope_override
+ void Subscribe(Interface *i, const Anope::string &ch) override
{
if (sub == NULL)
{
@@ -216,21 +219,19 @@ class MyRedisService : public Provider
sub->Connect(host, port);
}
- std::vector<Anope::string> args;
- args.push_back("PSUBSCRIBE");
- args.push_back(pattern);
+ std::vector<Anope::string> args = { "SUBSCRIBE", ch };
this->SendCommand(sub, NULL, args);
- sub->subinterfaces[pattern] = i;
+ sub->subinterfaces[ch] = i;
}
- void Unsubscribe(const Anope::string &pattern) anope_override
+ void Unsubscribe(const Anope::string &pattern) override
{
if (sub)
sub->subinterfaces.erase(pattern);
}
- void StartTransaction() anope_override
+ void StartTransaction() override
{
if (in_transaction)
throw CoreException();
@@ -239,7 +240,7 @@ class MyRedisService : public Provider
in_transaction = true;
}
- void CommitTransaction() anope_override
+ void CommitTransaction() override
{
/* The result of the transaction comes back to the reply of EXEC as a multi bulk.
* The reply to the individual commands that make up the transaction when executed
@@ -273,20 +274,15 @@ RedisSocket::~RedisSocket()
void RedisSocket::OnConnect()
{
- Log() << "redis: Successfully connected to " << provider->name << (this == this->provider->sub ? " (sub)" : "");
+ Log() << "redis: Successfully connected to " << provider->GetName() << (this == this->provider->sub ? " (sub)" : "");
this->provider->SendCommand(NULL, "CLIENT SETNAME Anope");
this->provider->SendCommand(NULL, "SELECT " + stringify(provider->db));
-
- if (this != this->provider->sub)
- {
- this->provider->SendCommand(this, NULL, "CONFIG SET notify-keyspace-events KA");
- }
}
void RedisSocket::OnError(const Anope::string &error)
{
- Log() << "redis: Error on " << provider->name << (this == this->provider->sub ? " (sub)" : "") << ": " << error;
+ Log() << "redis: Error on " << provider->GetName() << (this == this->provider->sub ? " (sub)" : "") << ": " << error;
}
size_t RedisSocket::ParseReply(Reply &r, const char *buffer, size_t l)
@@ -467,17 +463,9 @@ bool RedisSocket::Read(const char *buffer, size_t l)
if (this == provider->sub)
{
- if (r.multi_bulk.size() == 4)
- {
- /* pmessage
- * pattern subscribed to
- * __keyevent@0__:set
- * key
- */
- std::map<Anope::string, Interface *>::iterator it = this->subinterfaces.find(r.multi_bulk[1]->bulk);
- if (it != this->subinterfaces.end())
- it->second->OnResult(r);
- }
+ std::map<Anope::string, Interface *>::iterator it = this->subinterfaces.find(r.multi_bulk[1]->bulk);
+ if (it != this->subinterfaces.end())
+ it->second->OnResult(r);
}
else
{
@@ -519,11 +507,13 @@ bool RedisSocket::Read(const char *buffer, size_t l)
class ModuleRedis : public Module
+ , public EventHook<Event::ModuleUnload>
{
std::map<Anope::string, MyRedisService *> services;
public:
ModuleRedis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , EventHook<Event::ModuleUnload>(this)
{
}
@@ -542,7 +532,7 @@ class ModuleRedis : public Module
}
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Configuration::Block *block = conf->GetModule(this);
std::vector<Anope::string> new_services;
@@ -551,8 +541,8 @@ class ModuleRedis : public Module
{
Configuration::Block *redis = block->GetBlock("redis", i);
- const Anope::string &n = redis->Get<const Anope::string>("name"),
- &ip = redis->Get<const Anope::string>("ip");
+ const Anope::string &n = redis->Get<Anope::string>("name"),
+ &ip = redis->Get<Anope::string>("ip");
int port = redis->Get<int>("port");
unsigned db = redis->Get<unsigned>("db");
@@ -566,12 +556,12 @@ class ModuleRedis : public Module
Provider *p = it->second;
++it;
- if (std::find(new_services.begin(), new_services.end(), p->name) == new_services.end())
+ if (std::find(new_services.begin(), new_services.end(), p->GetName()) == new_services.end())
delete it->second;
}
}
- void OnModuleUnload(User *, Module *m) anope_override
+ void OnModuleUnload(User *, Module *m) override
{
for (std::map<Anope::string, MyRedisService *>::iterator it = services.begin(); it != services.end(); ++it)
{
diff --git a/modules/m_rewrite.cpp b/modules/rewrite.cpp
index e4ce46c3a..c4c5575e8 100644
--- a/modules/m_rewrite.cpp
+++ b/modules/rewrite.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -20,7 +31,7 @@ struct Rewrite
for (unsigned i = 0; i < sm.size(); ++i)
if (i >= message.size() || (sm[i] != "$" && !sm[i].equals_ci(message[i])))
return false;
-
+
return true;
}
@@ -71,7 +82,7 @@ struct Rewrite
}
static std::vector<Rewrite> rewrites;
-
+
static Rewrite *Find(const Anope::string &client, const Anope::string &cmd)
{
for (unsigned i = 0; i < rewrites.size(); ++i)
@@ -106,7 +117,7 @@ class RewriteCommand : public Command
public:
RewriteCommand(Module *creator) : Command(creator, "rewrite", 0, 0) { }
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
std::vector<Anope::string> full_params = params;
full_params.insert(full_params.begin(), source.command);
@@ -116,7 +127,7 @@ class RewriteCommand : public Command
{
Anope::string new_message = r->Process(source, full_params);
Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'";
- source.service = BotInfo::Find(r->client, true);
+ source.service = ServiceBot::Find(r->client, true);
if (!source.service)
return;
Command::Run(source, new_message);
@@ -125,7 +136,7 @@ class RewriteCommand : public Command
Log() << "m_rewrite: Unable to rewrite '" << source.command << (!params.empty() ? " " + params[0] : "") << "'";
}
- void OnServHelp(CommandSource &source) anope_override
+ void OnServHelp(CommandSource &source) override
{
Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
if (r != NULL && !r->desc.empty())
@@ -135,7 +146,7 @@ class RewriteCommand : public Command
}
}
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
if (r != NULL && !r->desc.empty())
@@ -154,11 +165,12 @@ class ModuleRewrite : public Module
RewriteCommand cmdrewrite;
public:
- ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA), cmdrewrite(this)
+ ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA)
+ , cmdrewrite(this)
{
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
Rewrite::rewrites.clear();
@@ -171,10 +183,10 @@ class ModuleRewrite : public Module
Rewrite rw;
- rw.client = block->Get<const Anope::string>("service");
- rw.source_message = block->Get<const Anope::string>("rewrite_source");
- rw.target_message = block->Get<const Anope::string>("rewrite_target");
- rw.desc = block->Get<const Anope::string>("rewrite_description");
+ rw.client = block->Get<Anope::string>("service");
+ rw.source_message = block->Get<Anope::string>("rewrite_source");
+ rw.target_message = block->Get<Anope::string>("rewrite_target");
+ rw.desc = block->Get<Anope::string>("rewrite_description");
if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty())
continue;
diff --git a/modules/sasl.cpp b/modules/sasl.cpp
new file mode 100644
index 000000000..f07026b9e
--- /dev/null
+++ b/modules/sasl.cpp
@@ -0,0 +1,391 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/sasl.h"
+#include "modules/nickserv/cert.h"
+
+using namespace SASL;
+
+class Plain : public Mechanism
+{
+ public:
+ Plain(SASL::Service *s, Module *o) : Mechanism(s, o, "PLAIN") { }
+
+ void ProcessMessage(Session *sess, const SASL::Message &m) override
+ {
+ if (m.type == "S")
+ {
+ GetService()->SendMessage(sess, "C", "+");
+ }
+ else if (m.type == "C")
+ {
+ Anope::string decoded;
+ Anope::B64Decode(m.data, decoded);
+
+ size_t p = decoded.find('\0');
+ if (p == Anope::string::npos)
+ {
+ GetService()->Fail(sess);
+ delete sess;
+ return;
+ }
+ decoded = decoded.substr(p + 1);
+
+ p = decoded.find('\0');
+ if (p == Anope::string::npos)
+ {
+ GetService()->Fail(sess);
+ delete sess;
+ return;
+ }
+
+ Anope::string acc = decoded.substr(0, p),
+ pass = decoded.substr(p + 1);
+
+ if (!NickServ::service || acc.empty() || pass.empty() || !IRCD->IsNickValid(acc) || pass.find_first_of("\r\n") != Anope::string::npos)
+ {
+ GetService()->Fail(sess);
+ delete sess;
+ return;
+ }
+
+ NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new IdentifyRequestListener(GetService(), m.source), this->GetOwner(), acc, pass);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req);
+ req->Dispatch();
+ }
+ }
+};
+
+class External : public Mechanism
+{
+ ServiceReference<CertService> certs;
+
+ struct Session : SASL::Session
+ {
+ Anope::string cert;
+
+ Session(SASL::Service *s, Mechanism *m, const Anope::string &u) : SASL::Session(s, m, u) { }
+ };
+
+ public:
+ External(SASL::Service *s, Module *o) : Mechanism(s, o, "EXTERNAL")
+ , certs("certs")
+ {
+ if (!IRCD || !IRCD->CanCertFP)
+ throw ModuleException("No CertFP");
+ }
+
+ Session* CreateSession(const Anope::string &uid) override
+ {
+ return new Session(this->GetService(), this, uid);
+ }
+
+ void ProcessMessage(SASL::Session *sess, const SASL::Message &m) override
+ {
+ Session *mysess = anope_dynamic_static_cast<Session *>(sess);
+
+ if (m.type == "S")
+ {
+ mysess->cert = m.ext;
+
+ GetService()->SendMessage(sess, "C", "+");
+ }
+ else if (m.type == "C")
+ {
+ if (!certs || mysess->cert.empty())
+ {
+ GetService()->Fail(sess);
+ delete sess;
+ return;
+ }
+
+ NickServ::Account *nc = certs->FindAccountFromCert(mysess->cert);
+ if (!nc || nc->HasFieldS("NS_SUSPENDED"))
+ {
+ Log(Config->GetClient("NickServ"), "sasl") << "A user failed to identify using certificate " << mysess->cert << " using SASL EXTERNAL";
+ GetService()->Fail(sess);
+ delete sess;
+ return;
+ }
+
+ Log(Config->GetClient("NickServ"), "sasl") << "A user identified to account " << nc->GetDisplay() << " using SASL EXTERNAL";
+ GetService()->Succeed(sess, nc);
+ delete sess;
+ }
+ }
+};
+
+class SASLService : public SASL::Service, public Timer
+{
+ std::map<Anope::string, SASL::Session *> sessions;
+
+ public:
+ SASLService(Module *o) : SASL::Service(o), Timer(o, 60, Anope::CurTime, true) { }
+
+ ~SASLService()
+ {
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end(); it++)
+ delete it->second;
+ }
+
+ void ProcessMessage(const SASL::Message &m) override
+ {
+ if (m.target != "*")
+ {
+ Server *s = Server::Find(m.target);
+ if (s != Me)
+ {
+ User *u = User::Find(m.target);
+ if (!u || u->server != Me)
+ return;
+ }
+ }
+
+ Session* &session = sessions[m.source];
+
+ if (m.type == "S")
+ {
+ ServiceReference<Mechanism> mech(m.data);
+ if (!mech)
+ {
+ Session tmp(this, NULL, m.source);
+
+ this->SendMechs(&tmp);
+ this->Fail(&tmp);
+ return;
+ }
+
+ if (!session)
+ session = mech->CreateSession(m.source);
+ }
+ else if (m.type == "D")
+ {
+ delete session;
+ sessions.erase(m.source);
+ return;
+ }
+
+ if (session && session->mech)
+ session->mech->ProcessMessage(session, m);
+ }
+
+ Anope::string GetAgent() override
+ {
+ Anope::string agent = Config->GetModule(Service::GetOwner())->Get<Anope::string>("agent", "NickServ");
+ ServiceBot *bi = Config->GetClient(agent);
+ if (bi)
+ agent = bi->GetUID();
+ return agent;
+ }
+
+ Session* GetSession(const Anope::string &uid) override
+ {
+ std::map<Anope::string, Session *>::iterator it = sessions.find(uid);
+ if (it != sessions.end())
+ return it->second;
+ return NULL;
+ }
+
+ void RemoveSession(Session *sess) override
+ {
+ sessions.erase(sess->uid);
+ }
+
+ void DeleteSessions(Mechanism *mech, bool da) override
+ {
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
+ {
+ std::map<Anope::string, Session *>::iterator del = it++;
+ if (*del->second->mech == mech)
+ {
+ if (da)
+ this->SendMessage(del->second, "D", "A");
+ delete del->second;
+ }
+ }
+ }
+
+ void SendMessage(Session *session, const Anope::string &mtype, const Anope::string &data) override
+ {
+ SASL::Message msg;
+ msg.source = this->GetAgent();
+ msg.target = session->uid;
+ msg.type = mtype;
+ msg.data = data;
+
+ IRCD->SendSASLMessage(msg);
+ }
+
+ void Succeed(Session *session, NickServ::Account *nc) override
+ {
+ // If the user is already introduced then we log them in now.
+ // Otherwise, we send an SVSLOGIN to log them in later.
+ User *user = User::Find(session->uid);
+ NickServ::Nick *na = NickServ::FindNick(nc->GetDisplay());
+ if (user)
+ {
+ user->Identify(na);
+ }
+ else
+ {
+ IRCD->SendSVSLogin(session->uid, nc->GetDisplay(), na->GetVhostIdent(), na->GetVhostHost());
+ }
+ this->SendMessage(session, "D", "S");
+ }
+
+ void Fail(Session *session) override
+ {
+ this->SendMessage(session, "D", "F");
+ }
+
+ void SendMechs(Session *session) override
+ {
+ std::vector<Mechanism *> mechs = ServiceManager::Get()->FindServices<Mechanism *>();
+
+ Anope::string buf;
+ for (unsigned j = 0; j < mechs.size(); ++j)
+ buf += "," + mechs[j]->GetName();
+
+ this->SendMessage(session, "M", buf.empty() ? "" : buf.substr(1));
+ }
+
+ void Tick(time_t) override
+ {
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
+ {
+ Anope::string key = it->first;
+ Session *s = it->second;
+ ++it;
+
+ if (!s || !s->mech || s->created + 60 < Anope::CurTime)
+ {
+ delete s;
+ sessions.erase(key);
+ }
+ }
+ }
+};
+
+void IdentifyRequestListener::OnSuccess(NickServ::IdentifyRequest *req)
+{
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
+ if (!na || na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ return OnFail(req);
+
+ unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
+ if (maxlogins && na->GetAccount()->users.size() >= maxlogins)
+ return OnFail(req);
+
+ Session *s = service->GetSession(uid);
+ if (s)
+ {
+ Log(Config->GetClient("NickServ"), "sasl") << "A user identified to account " << req->GetAccount() << " using SASL";
+ service->Succeed(s, na->GetAccount());
+ delete s;
+ }
+}
+
+void IdentifyRequestListener::OnFail(NickServ::IdentifyRequest *req)
+{
+ Session *s = service->GetSession(uid);
+ if (s)
+ {
+ service->Fail(s);
+ delete s;
+ }
+
+ Anope::string accountstatus;
+ NickServ::Nick *na = NickServ::FindNick(req->GetAccount());
+ if (!na)
+ accountstatus = "nonexistent ";
+ else if (na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ accountstatus = "suspended ";
+
+ Log(Config->GetClient("NickServ"), "sasl") << "A user failed to identify for " << accountstatus << "account " << req->GetAccount() << " using SASL";
+}
+
+class ModuleSASL : public Module
+ , public EventHook<Event::ModuleLoad>
+ , public EventHook<Event::ModuleUnload>
+ , public EventHook<Event::PreUplinkSync>
+{
+ SASLService sasl;
+
+ Plain plain;
+ External *external = nullptr;
+
+ std::vector<Anope::string> mechs;
+
+ void CheckMechs()
+ {
+ std::vector<Anope::string> names;
+ for (Mechanism *mech : ServiceManager::Get()->FindServices<Mechanism *>())
+ names.push_back(mech->GetName());
+
+ if (mechs == names)
+ return;
+
+ mechs = names;
+
+ // If we are connected to the network then broadcast the mechlist.
+ if (Me && Me->IsSynced())
+ IRCD->SendSASLMechanisms(mechs);
+ }
+
+ public:
+ ModuleSASL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , EventHook<Event::ModuleLoad>(this)
+ , EventHook<Event::ModuleUnload>(this)
+ , EventHook<Event::PreUplinkSync>(this)
+ , sasl(this)
+ , plain(&sasl, this)
+ {
+ try
+ {
+ external = new External(&sasl, this);
+ }
+ catch (ModuleException &) { }
+
+ CheckMechs();
+ }
+
+ ~ModuleSASL()
+ {
+ delete external;
+ }
+
+ void OnModuleLoad(User *, Module *) override
+ {
+ CheckMechs();
+ }
+
+ void OnModuleUnload(User *, Module *) override
+ {
+ CheckMechs();
+ }
+
+ void OnPreUplinkSync(Server *) override
+ {
+ // We have not yet sent a mechanism list so always do it here.
+ IRCD->SendSASLMechanisms(mechs);
+ }
+};
+
+MODULE_INIT(ModuleSASL)
diff --git a/modules/third/language/CMakeLists.txt b/modules/third/language/CMakeLists.txt
index 85278f5be..6a7891475 100644
--- a/modules/third/language/CMakeLists.txt
+++ b/modules/third/language/CMakeLists.txt
@@ -2,7 +2,7 @@
if(GETTEXT_FOUND)
# Get all of the .po files
file(GLOB LANG_SRCS_PO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.*.po")
- sort_list(LANG_SRCS_PO)
+ list(SORT LANG_SRCS_PO)
foreach(LANG_PO ${LANG_SRCS_PO})
# Get the domain for this language file
@@ -26,13 +26,13 @@ if(GETTEXT_FOUND)
# Add to cpack ignored files if not on Windows.
if(NOT WIN32)
add_to_cpack_ignored_files("${LANG_MO}")
- endif(NOT WIN32)
+ endif()
# Install the new language file
- install(CODE "FILE(MAKE_DIRECTORY ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES/)")
+ install(CODE "file(MAKE_DIRECTORY ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES/)")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG_MO} DESTINATION ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES RENAME ${LANG_DOMAIN}.mo PERMISSIONS ${PERMS})
- endforeach(LANG_PO)
+ endforeach()
# Generate languages, depends on the mo files
add_custom_target(module_language DEPENDS ${LANG_SRCS_MO})
-endif(GETTEXT_FOUND)
+endif()
diff --git a/modules/webcpanel/pages/chanserv/access.cpp b/modules/webcpanel/pages/chanserv/access.cpp
index 93f8b082a..c98ae45c8 100644
--- a/modules/webcpanel/pages/chanserv/access.cpp
+++ b/modules/webcpanel/pages/chanserv/access.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -12,7 +24,7 @@ WebCPanel::ChanServ::Access::Access(const Anope::string &cat, const Anope::strin
{
}
-bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
TemplateFileServer Page("chanserv/access.html");
const Anope::string &chname = message.get_data["channel"];
@@ -25,7 +37,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
return true;
}
- ChannelInfo *ci = ChannelInfo::Find(chname);
+ ::ChanServ::Channel *ci = ::ChanServ::Find(chname);
if (!ci)
{
@@ -34,8 +46,8 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
return true;
}
- AccessGroup u_access = ci->AccessFor(na->nc);
- bool has_priv = na->nc->IsServicesOper() && na->nc->o->ot->HasPriv("chanserv/access/modify");
+ ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount());
+ bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/access/modify");
if (!u_access.HasPriv("ACCESS_LIST") && !has_priv)
{
@@ -51,11 +63,11 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
if (message.get_data["del"].empty() == false && message.get_data["mask"].empty() == false)
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/access", params, replacements);
}
else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false)
{
@@ -64,55 +76,55 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
if (provider == "chanserv/access")
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("ADD");
params.push_back(message.post_data["mask"]);
params.push_back(message.post_data["access"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/access", params, replacements);
}
else if (provider == "chanserv/xop")
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("ADD");
params.push_back(message.post_data["mask"]);
- WebPanel::RunCommandWithName(na->nc, "ChanServ", "chanserv/xop", message.post_data["access"], params, replacements);
+ WebPanel::RunCommandWithName(na->GetAccount(), "ChanServ", "chanserv/xop", message.post_data["access"], params, replacements);
}
else if (provider == "chanserv/flags")
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("MODIFY");
params.push_back(message.post_data["mask"]);
params.push_back(message.post_data["access"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/flags", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/flags", params, replacements);
}
}
}
/* command might have invalidated u_access */
- u_access = ci->AccessFor(na->nc);
+ u_access = ci->AccessFor(na->GetAccount());
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
replacements["ACCESS_CHANGE"] = u_access.HasPriv("ACCESS_CHANGE") ? "YES" : "NO";
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
- ChanAccess *access = ci->GetAccess(i);
+ ::ChanServ::ChanAccess *access = ci->GetAccess(i);
replacements["MASKS"] = HTTPUtils::Escape(access->Mask());
replacements["ACCESSES"] = HTTPUtils::Escape(access->AccessSerialize());
- replacements["CREATORS"] = HTTPUtils::Escape(access->creator);
+ replacements["CREATORS"] = HTTPUtils::Escape(access->GetCreator());
}
- if (Service::FindService("Command", "chanserv/access"))
+ if (ServiceManager::Get()->FindService("Command", "chanserv/access"))
replacements["PROVIDERS"] = "chanserv/access";
- if (Service::FindService("Command", "chanserv/xop"))
+ if (ServiceManager::Get()->FindService("Command", "chanserv/xop"))
replacements["PROVIDERS"] = "chanserv/xop";
- if (Service::FindService("Command", "chanserv/flags"))
+ if (ServiceManager::Get()->FindService("Command", "chanserv/flags"))
replacements["PROVIDERS"] = "chanserv/flags";
Page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/chanserv/access.h b/modules/webcpanel/pages/chanserv/access.h
index fac203eee..288d976ae 100644
--- a/modules/webcpanel/pages/chanserv/access.h
+++ b/modules/webcpanel/pages/chanserv/access.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,9 +28,9 @@ class Access : public WebPanelProtectedPage
public:
Access(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
- std::set<Anope::string> GetData() anope_override;
+ std::set<Anope::string> GetData() override;
};
}
diff --git a/modules/webcpanel/pages/chanserv/akick.cpp b/modules/webcpanel/pages/chanserv/akick.cpp
index 8a6a09d4d..eb1c81f5a 100644
--- a/modules/webcpanel/pages/chanserv/akick.cpp
+++ b/modules/webcpanel/pages/chanserv/akick.cpp
@@ -1,18 +1,31 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
#include "utils.h"
+#include "modules/chanserv/akick.h"
WebCPanel::ChanServ::Akick::Akick(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
{
}
-bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
const Anope::string &chname = message.get_data["channel"];
TemplateFileServer Page("chanserv/akick.html");
@@ -25,7 +38,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
return true;
}
- ChannelInfo *ci = ChannelInfo::Find(chname);
+ ::ChanServ::Channel *ci = ::ChanServ::Find(chname);
if (!ci)
{
@@ -34,8 +47,8 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
return true;
}
- AccessGroup u_access = ci->AccessFor(na->nc);
- bool has_priv = na->nc->IsServicesOper() && na->nc->o->ot->HasPriv("chanserv/access/modify");
+ ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount());
+ bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/access/modify");
if (!u_access.HasPriv("AKICK") && !has_priv)
{
@@ -49,36 +62,36 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
if (message.get_data["del"].empty() == false && message.get_data["mask"].empty() == false)
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/akick", params, replacements);
}
else if (message.post_data["mask"].empty() == false)
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("ADD");
params.push_back(message.post_data["mask"]);
if (message.post_data["reason"].empty() == false)
params.push_back(message.post_data["reason"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/akick", params, replacements);
}
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
- AutoKick *akick = ci->GetAkick(i);
+ AutoKick *ak = ci->GetAkick(i);
- if (akick->nc)
- replacements["MASKS"] = HTTPUtils::Escape(akick->nc->display);
+ if (ak->GetAccount())
+ replacements["MASKS"] = HTTPUtils::Escape(ak->GetAccount()->GetDisplay());
else
- replacements["MASKS"] = HTTPUtils::Escape(akick->mask);
- replacements["CREATORS"] = HTTPUtils::Escape(akick->creator);
- replacements["REASONS"] = HTTPUtils::Escape(akick->reason);
+ replacements["MASKS"] = HTTPUtils::Escape(ak->GetMask());
+ replacements["CREATORS"] = HTTPUtils::Escape(ak->GetCreator());
+ replacements["REASONS"] = HTTPUtils::Escape(ak->GetReason());
}
Page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/chanserv/akick.h b/modules/webcpanel/pages/chanserv/akick.h
index 393f79853..ff1730bc7 100644
--- a/modules/webcpanel/pages/chanserv/akick.h
+++ b/modules/webcpanel/pages/chanserv/akick.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,9 +28,9 @@ class Akick : public WebPanelProtectedPage
public:
Akick(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
- std::set<Anope::string> GetData() anope_override;
+ std::set<Anope::string> GetData() override;
};
}
diff --git a/modules/webcpanel/pages/chanserv/drop.cpp b/modules/webcpanel/pages/chanserv/drop.cpp
index e2c131f7a..cc5fa4026 100644
--- a/modules/webcpanel/pages/chanserv/drop.cpp
+++ b/modules/webcpanel/pages/chanserv/drop.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -13,7 +25,7 @@ WebCPanel::ChanServ::Drop::Drop(const Anope::string &cat, const Anope::string &u
}
-bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
if (message.post_data.count("channel") > 0 && message.post_data.count("confChan") > 0)
@@ -25,23 +37,18 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str
params.push_back(channel);
params.push_back(channel);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/drop", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/drop", params, replacements);
}
else
replacements["MESSAGES"] = "Invalid Confirmation";
}
- std::deque<ChannelInfo *> queue;
- na->nc->GetChannelReferences(queue);
- for (unsigned i = 0; i < queue.size(); ++i)
- {
- ChannelInfo *ci = queue[i];
- if ((ci->HasExt("SECUREFOUNDER") ? ci->AccessFor(na->nc).founder : ci->AccessFor(na->nc).HasPriv("FOUNDER")) || (na->nc->IsServicesOper() && na->nc->o->ot->HasCommand("chanserv/drop")))
+ for (::ChanServ::Channel *ci : na->GetAccount()->GetRefs<::ChanServ::Channel *>())
+ if ((ci->HasFieldS("SECUREFOUNDER") ? ci->AccessFor(na->GetAccount()).founder : ci->AccessFor(na->GetAccount()).HasPriv("FOUNDER")) || (na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasCommand("chanserv/drop")))
{
- replacements["CHANNEL_NAMES"] = ci->name;
- replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->name);
+ replacements["CHANNEL_NAMES"] = ci->GetName();
+ replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->GetName());
}
- }
if (message.get_data.count("channel") > 0)
{
diff --git a/modules/webcpanel/pages/chanserv/drop.h b/modules/webcpanel/pages/chanserv/drop.h
index f50d9428c..1a4f49a25 100644
--- a/modules/webcpanel/pages/chanserv/drop.h
+++ b/modules/webcpanel/pages/chanserv/drop.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ namespace WebCPanel
public:
Drop(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
diff --git a/modules/webcpanel/pages/chanserv/info.cpp b/modules/webcpanel/pages/chanserv/info.cpp
index 856cc9b50..b7c1a5cef 100644
--- a/modules/webcpanel/pages/chanserv/info.cpp
+++ b/modules/webcpanel/pages/chanserv/info.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -12,7 +24,7 @@ WebCPanel::ChanServ::Info::Info(const Anope::string &cat, const Anope::string &u
{
}
-bool WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
const Anope::string &chname = message.get_data["channel"];
diff --git a/modules/webcpanel/pages/chanserv/info.h b/modules/webcpanel/pages/chanserv/info.h
index b1108b11c..91974a707 100644
--- a/modules/webcpanel/pages/chanserv/info.h
+++ b/modules/webcpanel/pages/chanserv/info.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Info : public WebPanelProtectedPage
public:
Info(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/chanserv/modes.cpp b/modules/webcpanel/pages/chanserv/modes.cpp
index 8e77c0287..da7ad0803 100644
--- a/modules/webcpanel/pages/chanserv/modes.cpp
+++ b/modules/webcpanel/pages/chanserv/modes.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -12,7 +24,7 @@ WebCPanel::ChanServ::Modes::Modes(const Anope::string &cat, const Anope::string
{
}
-bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
const Anope::string &chname = message.get_data["channel"];
const Anope::string &mode = message.get_data["m"];
@@ -27,7 +39,7 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st
}
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
- ChannelInfo *ci = ChannelInfo::Find(chname);
+ ::ChanServ::Channel *ci = ::ChanServ::Find(chname);
if (!ci)
{
@@ -39,13 +51,13 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st
if (!c)
{
- replacements["MESSAGES"] = Anope::printf(CHAN_X_NOT_IN_USE, chname.c_str());
+ replacements["MESSAGES"] = Anope::printf(_("Channel \002%s\002 doesn't exist."), chname.c_str());
Page.Serve(server, page_name, client, message, reply, replacements);
return true;
}
- AccessGroup u_access = ci->AccessFor(na->nc);
- bool has_priv = na->nc->IsServicesOper() && na->nc->o->ot->HasPriv("chanserv/administration");
+ ::ChanServ::AccessGroup u_access = ci->AccessFor(na->GetAccount());
+ bool has_priv = na->GetAccount()->IsServicesOper() && na->GetAccount()->o->GetType()->HasPriv("chanserv/administration");
if (!u_access.HasPriv("MODE") && !has_priv)
{
@@ -78,20 +90,20 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st
if (message.get_data["del"].empty() == false && message.get_data["mask"].empty() == false)
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("SET");
params.push_back("-" + Anope::string(cm->mchar));
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/mode", params, replacements);
}
else if (message.post_data["mask"].empty() == false)
{
std::vector<Anope::string> params;
- params.push_back(ci->name);
+ params.push_back(ci->GetName());
params.push_back("SET");
params.push_back("+" + Anope::string(cm->mchar));
params.push_back(message.post_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "ChanServ", "chanserv/mode", params, replacements);
}
std::vector<Anope::string> v = c->GetModeList(cm->name);
diff --git a/modules/webcpanel/pages/chanserv/modes.h b/modules/webcpanel/pages/chanserv/modes.h
index 5f752d203..2b4985b30 100644
--- a/modules/webcpanel/pages/chanserv/modes.h
+++ b/modules/webcpanel/pages/chanserv/modes.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,9 +28,9 @@ class Modes : public WebPanelProtectedPage
public:
Modes(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
- std::set<Anope::string> GetData() anope_override;
+ std::set<Anope::string> GetData() override;
};
}
diff --git a/modules/webcpanel/pages/chanserv/set.cpp b/modules/webcpanel/pages/chanserv/set.cpp
index 84b31d50e..d3cca72cc 100644
--- a/modules/webcpanel/pages/chanserv/set.cpp
+++ b/modules/webcpanel/pages/chanserv/set.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -12,7 +24,7 @@ WebCPanel::ChanServ::Set::Set(const Anope::string &cat, const Anope::string &u)
{
}
-bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
const Anope::string &chname = message.get_data["channel"];
bool can_set = false;
@@ -26,7 +38,7 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
return true;
}
- ChannelInfo *ci = ChannelInfo::Find(chname);
+ ::ChanServ::Channel *ci = ::ChanServ::Find(chname);
if (!ci)
{
@@ -36,7 +48,7 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
replacements["OKAY"];
- if (ci->AccessFor(na->nc).HasPriv("SET"))
+ if (ci->AccessFor(na->GetAccount()).HasPriv("SET"))
{
replacements["CAN_SET"];
can_set = true;
@@ -44,101 +56,101 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
if (can_set && message.post_data.empty() == false)
{
- if (ci->HasExt("KEEPTOPIC") != message.post_data.count("keeptopic"))
+ if (ci->HasFieldS("KEEPTOPIC") != message.post_data.count("keeptopic"))
{
- if (!ci->HasExt("KEEPTOPIC"))
- ci->Extend<bool>("KEEPTOPIC");
+ if (!ci->HasFieldS("KEEPTOPIC"))
+ ci->SetS<bool>("KEEPTOPIC", true);
else
- ci->Shrink<bool>("KEEPTOPIC");
+ ci->UnsetS<bool>("KEEPTOPIC");
replacements["MESSAGES"] = "Secure updated";
}
- if (ci->HasExt("PEACE") != message.post_data.count("peace"))
+ if (ci->HasFieldS("PEACE") != message.post_data.count("peace"))
{
- if (!ci->HasExt("PEACE"))
- ci->Extend<bool>("PEACE");
+ if (!ci->HasFieldS("PEACE"))
+ ci->SetS<bool>("PEACE", true);
else
- ci->Shrink<bool>("PEACE");
+ ci->UnsetS<bool>("PEACE");
replacements["MESSAGES"] = "Peace updated";
}
- if (ci->HasExt("CS_PRIVATE") != message.post_data.count("private"))
+ if (ci->HasFieldS("CS_PRIVATE") != message.post_data.count("private"))
{
- if (!ci->HasExt("CS_PRIVATE"))
- ci->Extend<bool>("CS_PRIVATE");
+ if (!ci->HasFieldS("CS_PRIVATE"))
+ ci->SetS<bool>("CS_PRIVATE", true);
else
- ci->Shrink<bool>("CS_PRIVATE");
+ ci->UnsetS<bool>("CS_PRIVATE");
replacements["MESSAGES"] = "Private updated";
}
- if (ci->HasExt("RESTRICTED") != message.post_data.count("restricted"))
+ if (ci->HasFieldS("RESTRICTED") != message.post_data.count("restricted"))
{
- if (!ci->HasExt("RESTRICTED"))
- ci->Extend<bool>("RESTRICTED");
+ if (!ci->HasFieldS("RESTRICTED"))
+ ci->SetS<bool>("RESTRICTED", true);
else
- ci->Shrink<bool>("RESTRICTED");
+ ci->UnsetS<bool>("RESTRICTED");
replacements["MESSAGES"] = "Restricted updated";
}
- if (ci->HasExt("CS_SECURE") != message.post_data.count("secure"))
+ if (ci->HasFieldS("CS_SECURE") != message.post_data.count("secure"))
{
- if (!ci->HasExt("CS_SECURE"))
- ci->Extend<bool>("CS_SECURE");
+ if (!ci->HasFieldS("CS_SECURE"))
+ ci->SetS<bool>("CS_SECURE", true);
else
- ci->Shrink<bool>("CS_SECURE");
+ ci->UnsetS<bool>("CS_SECURE");
replacements["MESSAGES"] = "Secure updated";
}
- if (ci->HasExt("SECUREOPS") != message.post_data.count("secureops"))
+ if (ci->HasFieldS("SECUREOPS") != message.post_data.count("secureops"))
{
- if (!ci->HasExt("SECUREOPS"))
- ci->Extend<bool>("SECUREOPS");
+ if (!ci->HasFieldS("SECUREOPS"))
+ ci->SetS<bool>("SECUREOPS", true);
else
- ci->Shrink<bool>("SECUREOPS");
+ ci->UnsetS<bool>("SECUREOPS");
replacements["MESSAGES"] = "Secureops updated";
}
- if (ci->HasExt("TOPICLOCK") != message.post_data.count("topiclock"))
+ if (ci->HasFieldS("TOPICLOCK") != message.post_data.count("topiclock"))
{
- if (!ci->HasExt("TOPICLOCK"))
- ci->Extend<bool>("TOPICLOCK");
+ if (!ci->HasFieldS("TOPICLOCK"))
+ ci->SetS<bool>("TOPICLOCK", true);
else
- ci->Shrink<bool>("TOPICLOCK");
+ ci->UnsetS<bool>("TOPICLOCK");
replacements["MESSAGES"] = "Topiclock updated";
}
}
- replacements["CHANNEL"] = HTTPUtils::Escape(ci->name);
- replacements["CHANNEL_ESCAPED"] = HTTPUtils::URLEncode(ci->name);
+ replacements["CHANNEL"] = HTTPUtils::Escape(ci->GetName());
+ replacements["CHANNEL_ESCAPED"] = HTTPUtils::URLEncode(ci->GetName());
if (ci->GetFounder())
- replacements["FOUNDER"] = ci->GetFounder()->display;
+ replacements["FOUNDER"] = ci->GetFounder()->GetDisplay();
if (ci->GetSuccessor())
- replacements["SUCCESSOR"] = ci->GetSuccessor()->display;
- replacements["TIME_REGISTERED"] = Anope::strftime(ci->time_registered, na->nc);
- replacements["LAST_USED"] = Anope::strftime(ci->last_used, na->nc);
+ replacements["SUCCESSOR"] = ci->GetSuccessor()->GetDisplay();
+ replacements["TIME_REGISTERED"] = Anope::strftime(ci->GetTimeRegistered(), na->GetAccount());
+ replacements["LAST_USED"] = Anope::strftime(ci->GetLastUsed(), na->GetAccount());
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
- if (!ci->last_topic.empty())
+ if (!ci->GetLastTopic().empty())
{
- replacements["LAST_TOPIC"] = HTTPUtils::Escape(ci->last_topic);
- replacements["LAST_TOPIC_SETTER"] = HTTPUtils::Escape(ci->last_topic_setter);
+ replacements["LAST_TOPIC"] = HTTPUtils::Escape(ci->GetLastTopic());
+ replacements["LAST_TOPIC_SETTER"] = HTTPUtils::Escape(ci->GetLastTopicSetter());
}
if (can_set)
{
- if (ci->HasExt("KEEPTOPIC"))
+ if (ci->HasFieldS("KEEPTOPIC"))
replacements["KEEPTOPIC"];
- if (ci->HasExt("PEACE"))
+ if (ci->HasFieldS("PEACE"))
replacements["PEACE"];
- if (ci->HasExt("CS_PRIVATE"))
+ if (ci->HasFieldS("CS_PRIVATE"))
replacements["PRIVATE"];
- if (ci->HasExt("RESTRICTED"))
+ if (ci->HasFieldS("RESTRICTED"))
replacements["RESTRICTED"];
- if (ci->HasExt("CS_SECURE"))
+ if (ci->HasFieldS("CS_SECURE"))
replacements["SECURE"];
- if (ci->HasExt("SECUREOPS"))
+ if (ci->HasFieldS("SECUREOPS"))
replacements["SECUREOPS"];
- if (ci->HasExt("TOPICLOCK"))
+ if (ci->HasFieldS("TOPICLOCK"))
replacements["TOPICLOCK"];
}
diff --git a/modules/webcpanel/pages/chanserv/set.h b/modules/webcpanel/pages/chanserv/set.h
index bc88d13c6..5a1b05346 100644
--- a/modules/webcpanel/pages/chanserv/set.h
+++ b/modules/webcpanel/pages/chanserv/set.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,9 +28,9 @@ class Set : public WebPanelProtectedPage
public:
Set(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
- std::set<Anope::string> GetData() anope_override;
+ std::set<Anope::string> GetData() override;
};
}
diff --git a/modules/webcpanel/pages/chanserv/utils.cpp b/modules/webcpanel/pages/chanserv/utils.cpp
index 5c055f722..bdf0b92ec 100644
--- a/modules/webcpanel/pages/chanserv/utils.cpp
+++ b/modules/webcpanel/pages/chanserv/utils.cpp
@@ -1,17 +1,29 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
namespace
{
- bool ChannelSort(ChannelInfo *ci1, ChannelInfo *ci2)
+ bool ChannelSort(ChanServ::Channel *ci1, ChanServ::Channel *ci2)
{
- return ci::less()(ci1->name, ci2->name);
+ return ci::less()(ci1->GetName(), ci2->GetName());
}
}
@@ -21,21 +33,18 @@ namespace WebCPanel
namespace ChanServ
{
-void BuildChanList(NickAlias *na, TemplateFileServer::Replacements &replacements)
+void BuildChanList(::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
- std::deque<ChannelInfo *> queue;
- na->nc->GetChannelReferences(queue);
- std::sort(queue.begin(), queue.end(), ChannelSort);
+ std::vector<::ChanServ::Channel *> chans = na->GetAccount()->GetRefs<::ChanServ::Channel *>();
+ std::sort(chans.begin(), chans.end(), ChannelSort);
- for (unsigned i = 0; i < queue.size(); ++i)
+ for (::ChanServ::Channel *ci : chans)
{
- ChannelInfo *ci = queue[i];
-
- if (na->nc != ci->GetFounder() && ci->AccessFor(na->nc).empty())
+ if (na->GetAccount() != ci->GetFounder() && ci->AccessFor(na->GetAccount()).empty())
continue;
- replacements["CHANNEL_NAMES"] = ci->name;
- replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->name);
+ replacements["CHANNEL_NAMES"] = ci->GetName();
+ replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->GetName());
}
}
diff --git a/modules/webcpanel/pages/chanserv/utils.h b/modules/webcpanel/pages/chanserv/utils.h
index d5a794c61..8ad1f3c9e 100644
--- a/modules/webcpanel/pages/chanserv/utils.h
+++ b/modules/webcpanel/pages/chanserv/utils.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -11,7 +23,7 @@ namespace WebCPanel
namespace ChanServ
{
-extern void BuildChanList(NickAlias *, TemplateFileServer::Replacements &);
+extern void BuildChanList(::NickServ::Nick *, TemplateFileServer::Replacements &);
}
diff --git a/modules/webcpanel/pages/confirm.cpp b/modules/webcpanel/pages/confirm.cpp
index bb0412f7e..c8c4e0bbd 100644
--- a/modules/webcpanel/pages/confirm.cpp
+++ b/modules/webcpanel/pages/confirm.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../webcpanel.h"
diff --git a/modules/webcpanel/pages/confirm.h b/modules/webcpanel/pages/confirm.h
index f1e95062d..ba0c367dd 100644
--- a/modules/webcpanel/pages/confirm.h
+++ b/modules/webcpanel/pages/confirm.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "modules/httpd.h"
@@ -15,7 +27,7 @@ class Confirm : public WebPanelPage
public:
Confirm(const Anope::string &u) : WebPanelPage(u) { }
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) override;
};
}
diff --git a/modules/webcpanel/pages/hostserv/request.cpp b/modules/webcpanel/pages/hostserv/request.cpp
index 5ceb178d2..0230ba8fa 100644
--- a/modules/webcpanel/pages/hostserv/request.cpp
+++ b/modules/webcpanel/pages/hostserv/request.cpp
@@ -1,24 +1,36 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
-WebCPanel::HostServ::Request::Request(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage (cat, u)
+WebCPanel::HostServ::Request::Request(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage (cat, u)
{
}
-bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
if (message.post_data.count("req") > 0)
{
std::vector<Anope::string> params;
params.push_back(HTTPUtils::URLDecode(message.post_data["req"]));
- WebPanel::RunCommand(na->nc->display, na->nc, "HostServ", "hostserv/request", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "HostServ", "hostserv/request", params, replacements, "CMDR");
}
if (na->HasVhost())
@@ -28,7 +40,7 @@ bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope::
else
replacements["VHOST"] = na->GetVhostHost();
}
- if (ServiceReference<Command>("Command", "hostserv/request"))
+ if (ServiceReference<Command>("hostserv/request"))
replacements["CAN_REQUEST"] = "YES";
TemplateFileServer page("hostserv/request.html");
page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/hostserv/request.h b/modules/webcpanel/pages/hostserv/request.h
index 5dafd15fd..e9bf6b23b 100644
--- a/modules/webcpanel/pages/hostserv/request.h
+++ b/modules/webcpanel/pages/hostserv/request.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Request : public WebPanelProtectedPage
public:
Request(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/index.cpp b/modules/webcpanel/pages/index.cpp
index 1375c3c13..0436f73af 100644
--- a/modules/webcpanel/pages/index.cpp
+++ b/modules/webcpanel/pages/index.cpp
@@ -1,13 +1,26 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../webcpanel.h"
+#include "modules/nickserv.h"
-class WebpanelRequest : public IdentifyRequest
+class WebpanelRequest : public NickServ::IdentifyRequestListener
{
HTTPReply reply;
HTTPMessage message;
@@ -17,22 +30,22 @@ class WebpanelRequest : public IdentifyRequest
TemplateFileServer::Replacements replacements;
public:
- WebpanelRequest(Module *o, HTTPReply &r, HTTPMessage &m, HTTPProvider *s, const Anope::string &p_n, HTTPClient *c, TemplateFileServer::Replacements &re, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(o, user, pass), reply(r), message(m), server(s), page_name(p_n), client(c), replacements(re) { }
+ WebpanelRequest(HTTPReply &r, HTTPMessage &m, HTTPProvider *s, const Anope::string &p_n, HTTPClient *c, TemplateFileServer::Replacements &re) : reply(r), message(m), server(s), page_name(p_n), client(c), replacements(re) { }
- void OnSuccess() anope_override
+ void OnSuccess(NickServ::IdentifyRequest *req) override
{
if (!client || !server)
return;
- NickAlias *na = NickAlias::Find(this->GetAccount());
+ ::NickServ::Nick *na = ::NickServ::FindNick(req->GetAccount());
if (!na)
{
- this->OnFail();
+ this->OnFail(req);
return;
}
- if (na->nc->HasExt("NS_SUSPENDED"))
+ if (na->GetAccount()->HasFieldS("NS_SUSPENDED"))
{
- this->OnFail();
+ this->OnFail(req);
return;
}
@@ -51,12 +64,12 @@ class WebpanelRequest : public IdentifyRequest
{
HTTPReply::cookie c;
- c.push_back(std::make_pair("account", na->nick));
+ c.push_back(std::make_pair("account", na->GetNick()));
c.push_back(std::make_pair("Path", "/"));
reply.cookies.push_back(c);
}
- {
+ {
HTTPReply::cookie c;
c.push_back(std::make_pair("id", id));
c.push_back(std::make_pair("Path", "/"));
@@ -69,7 +82,7 @@ class WebpanelRequest : public IdentifyRequest
client->SendReply(&reply);
}
- void OnFail() anope_override
+ void OnFail(NickServ::IdentifyRequest *req) override
{
if (!client || !server)
return;
@@ -88,12 +101,12 @@ bool WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page
replacements["TITLE"] = page_title;
- if (!user.empty() && !pass.empty())
+ if (!user.empty() && !pass.empty() && ::NickServ::service)
{
- // Rate limit check.
+ // XXX Rate limit check.
- WebpanelRequest *req = new WebpanelRequest(me, reply, message, server, page_name, client, replacements, user, pass);
- FOREACH_MOD(OnCheckAuthentication, (NULL, req));
+ ::NickServ::IdentifyRequest *req = ::NickServ::service->CreateIdentifyRequest(new WebpanelRequest(reply, message, server, page_name, client, replacements), me, user, pass);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req);
req->Dispatch();
return false;
}
diff --git a/modules/webcpanel/pages/index.h b/modules/webcpanel/pages/index.h
index 99f6da7b9..2e296a81e 100644
--- a/modules/webcpanel/pages/index.h
+++ b/modules/webcpanel/pages/index.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "modules/httpd.h"
@@ -15,7 +27,7 @@ class Index : public WebPanelPage
public:
Index(const Anope::string &u) : WebPanelPage(u) { }
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) override;
};
}
diff --git a/modules/webcpanel/pages/logout.cpp b/modules/webcpanel/pages/logout.cpp
index 2b98e3431..5d32c3c22 100644
--- a/modules/webcpanel/pages/logout.cpp
+++ b/modules/webcpanel/pages/logout.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../webcpanel.h"
@@ -11,7 +23,7 @@ WebCPanel::Logout::Logout(const Anope::string &u) : WebPanelProtectedPage("", u)
{
}
-bool WebCPanel::Logout::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::Logout::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
na->Shrink<Anope::string>("webcpanel_id");
na->Shrink<Anope::string>("webcpanel_ip");
diff --git a/modules/webcpanel/pages/logout.h b/modules/webcpanel/pages/logout.h
index 8492d7a26..4fb70d2b2 100644
--- a/modules/webcpanel/pages/logout.h
+++ b/modules/webcpanel/pages/logout.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -13,7 +25,7 @@ class Logout : public WebPanelProtectedPage
public:
Logout(const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/memoserv/memos.cpp b/modules/webcpanel/pages/memoserv/memos.cpp
index d4335f749..76f4d676e 100644
--- a/modules/webcpanel/pages/memoserv/memos.cpp
+++ b/modules/webcpanel/pages/memoserv/memos.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -11,45 +23,46 @@ WebCPanel::MemoServ::Memos::Memos(const Anope::string &cat, const Anope::string
{
}
-bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
const Anope::string &chname = message.get_data["channel"];
- ChannelInfo *ci;
- const MemoInfo *mi;
- Memo *m;
+ ::ChanServ::Channel *ci;
+ ::MemoServ::MemoInfo *mi;
+ ::MemoServ::Memo *m;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- ci = it->second;
-
- if (ci->AccessFor(na->nc).HasPriv("MEMO"))
+ if (::ChanServ::service)
+ for (auto& it : ::ChanServ::service->GetChannels())
{
- replacements["CHANNEL_NAMES"] = ci->name;
- replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->name);
+ ci = it.second;
+
+ if (ci->AccessFor(na->GetAccount()).HasPriv("MEMO"))
+ {
+ replacements["CHANNEL_NAMES"] = ci->GetName();
+ replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->GetName());
+ }
}
- }
if (chname.empty())
{
replacements["MESSAGES"] = "No Channel specified, displaying the memos for your Nick";
- mi = &na->nc->memos;
+ mi = na->GetAccount()->GetMemos();
}
else
{
- ci = ChannelInfo::Find(chname);
+ ci = ::ChanServ::Find(chname);
if (ci)
{
replacements["MESSAGES"] = "Displaying the memos for " + chname + ".";
- mi = &ci->memos;
-
- replacements["CHANNEL_NAME"] = ci->name;
- replacements["ESCAPED_CHANNEL_NAME"] = HTTPUtils::URLEncode(ci->name);
+ mi = ci->GetMemos();
}
else
{
replacements["MESSAGES"] = "Channel " + chname + " not found, displaying the memos for your nick";
- mi = &na->nc->memos;
+ mi = na->GetAccount()->GetMemos();
}
+
+ replacements["CHANNEL_NAME"] = ci->GetName();
+ replacements["ESCAPED_CHANNEL_NAME"] = HTTPUtils::URLEncode(ci->GetName());
}
if (message.post_data.count("receiver") > 0 && message.post_data.count("message") > 0)
{
@@ -57,7 +70,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"]));
params.push_back(HTTPUtils::URLDecode(message.post_data["message"]));
- WebPanel::RunCommand(na->nc->display, na->nc, "MemoServ", "memoserv/send", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "MemoServ", "memoserv/send", params, replacements, "CMDR");
}
if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0)
{
@@ -66,7 +79,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
params.push_back(chname);
params.push_back(message.get_data["number"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "MemoServ", "memoserv/del", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "MemoServ", "memoserv/del", params, replacements, "CMDR");
}
if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0)
{
@@ -84,29 +97,30 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
if (number > 0)
{
- m = mi->GetMemo(number-1);
+ m = mi ? mi->GetMemo(number-1) : nullptr;
if (!m)
replacements["MESSAGES"] = "ERROR - invalid memo number.";
else if (message.get_data["read"] == "1")
- m->unread = false;
+ m->SetUnread(false);
else if (message.get_data["read"] == "2")
- m->unread = true;
+ m->SetUnread(true);
}
}
- for (unsigned i = 0; i < mi->memos->size(); ++i)
- {
- m = mi->GetMemo(i);
- replacements["NUMBER"] = stringify(i+1);
- replacements["SENDER"] = m->sender;
- replacements["TIME"] = Anope::strftime(m->time);
- replacements["TEXT"] = HTTPUtils::Escape(m->text);
- if (m->unread)
- replacements["UNREAD"] = "YES";
- else
- replacements["UNREAD"] = "NO";
- }
+ if (mi)
+ for (unsigned i = 0; i < mi->GetMemos().size(); ++i)
+ {
+ m = mi->GetMemo(i);
+ replacements["NUMBER"] = stringify(i+1);
+ replacements["SENDER"] = m->GetSender();
+ replacements["TIME"] = Anope::strftime(m->GetTime());
+ replacements["TEXT"] = HTTPUtils::Escape(m->GetText());
+ if (m->GetUnread())
+ replacements["UNREAD"] = "YES";
+ else
+ replacements["UNREAD"] = "NO";
+ }
TemplateFileServer page("memoserv/memos.html");
page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/memoserv/memos.h b/modules/webcpanel/pages/memoserv/memos.h
index edab4fa20..68da44ca9 100644
--- a/modules/webcpanel/pages/memoserv/memos.h
+++ b/modules/webcpanel/pages/memoserv/memos.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Memos : public WebPanelProtectedPage
public:
Memos(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/nickserv/access.cpp b/modules/webcpanel/pages/nickserv/access.cpp
index 9a0add123..fa9c650f2 100644
--- a/modules/webcpanel/pages/nickserv/access.cpp
+++ b/modules/webcpanel/pages/nickserv/access.cpp
@@ -1,17 +1,30 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
+#include "modules/nickserv/access.h"
WebCPanel::NickServ::Access::Access(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
{
}
-bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
if (message.post_data.count("access") > 0)
{
@@ -19,7 +32,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
params.push_back("ADD");
params.push_back(message.post_data["access"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "NickServ", "nickserv/access", params, replacements);
}
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
{
@@ -27,11 +40,11 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "NickServ", "nickserv/access", params, replacements);
}
- for (unsigned i = 0; i < na->nc->access.size(); ++i)
- replacements["ACCESS"] = na->nc->access[i];
+ for (NickAccess *a : na->GetAccount()->GetRefs<NickAccess *>())
+ replacements["ACCESS"] = a->GetMask();
TemplateFileServer page("nickserv/access.html");
page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/nickserv/access.h b/modules/webcpanel/pages/nickserv/access.h
index 3bc2ff6ec..885671600 100644
--- a/modules/webcpanel/pages/nickserv/access.h
+++ b/modules/webcpanel/pages/nickserv/access.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Access : public WebPanelProtectedPage
public:
Access(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/nickserv/alist.cpp b/modules/webcpanel/pages/nickserv/alist.cpp
index d5b331f4f..f950cf63a 100644
--- a/modules/webcpanel/pages/nickserv/alist.cpp
+++ b/modules/webcpanel/pages/nickserv/alist.cpp
@@ -1,54 +1,64 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
-static bool ChannelSort(ChannelInfo *ci1, ChannelInfo *ci2)
+static bool ChannelSort(ChanServ::Channel *ci1, ChanServ::Channel *ci2)
{
- return ci::less()(ci1->name, ci2->name);
+ return ci::less()(ci1->GetName(), ci2->GetName());
}
WebCPanel::NickServ::Alist::Alist(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
{
}
-bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
- std::deque<ChannelInfo *> queue;
- na->nc->GetChannelReferences(queue);
- std::sort(queue.begin(), queue.end(), ChannelSort);
+ std::vector<::ChanServ::Channel *> chans = na->GetAccount()->GetRefs<::ChanServ::Channel *>();
+ std::sort(chans.begin(), chans.end(), ChannelSort);
int chan_count = 0;
- for (unsigned q = 0; q < queue.size(); ++q)
+ for (::ChanServ::Channel *ci : chans)
{
- ChannelInfo *ci = queue[q];
-
- if (ci->GetFounder() == na->nc)
+ if (ci->GetFounder() == na->GetAccount())
{
++chan_count;
replacements["NUMBERS"] = stringify(chan_count);
- replacements["CHANNELS"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
+ replacements["CHANNELS"] = (ci->HasFieldS("CS_NO_EXPIRE") ? "!" : "") + ci->GetName();
replacements["ACCESSES"] = "Founder";
continue;
}
- AccessGroup access = ci->AccessFor(na->nc);
+ ::ChanServ::AccessGroup access = ci->AccessFor(na->GetAccount());
if (access.empty())
continue;
-
+
++chan_count;
replacements["NUMBERS"] = stringify(chan_count);
- replacements["CHANNELS"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
-
- const ChanAccess *highest = access.Highest();
- replacements["ACCESSES"] = highest ? highest->AccessSerialize() : "";
+ replacements["CHANNELS"] = (ci->HasFieldS("CS_NO_EXPIRE") ? "!" : "") + ci->GetName();
+ Anope::string access_str;
+ for (unsigned i = 0; i < access.size(); ++i)
+ access_str += ", " + access[i]->AccessSerialize();
+ replacements["ACCESSES"] = access_str.substr(2);
}
TemplateFileServer page("nickserv/alist.html");
diff --git a/modules/webcpanel/pages/nickserv/alist.h b/modules/webcpanel/pages/nickserv/alist.h
index fa0d7ea0b..096c27be1 100644
--- a/modules/webcpanel/pages/nickserv/alist.h
+++ b/modules/webcpanel/pages/nickserv/alist.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Alist : public WebPanelProtectedPage
public:
Alist(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/nickserv/cert.cpp b/modules/webcpanel/pages/nickserv/cert.cpp
index 94b93c69a..16659e660 100644
--- a/modules/webcpanel/pages/nickserv/cert.cpp
+++ b/modules/webcpanel/pages/nickserv/cert.cpp
@@ -1,18 +1,30 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
-#include "modules/ns_cert.h"
+#include "modules/nickserv/cert.h"
WebCPanel::NickServ::Cert::Cert(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
{
}
-bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
if (message.post_data.count("certfp") > 0)
{
@@ -20,7 +32,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
params.push_back("ADD");
params.push_back(message.post_data["certfp"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "NickServ", "nickserv/cert", params, replacements);
}
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
{
@@ -28,13 +40,12 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "NickServ", "nickserv/cert", params, replacements);
}
- NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
- if (cl)
- for (unsigned i = 0; i < cl->GetCertCount(); ++i)
- replacements["CERTS"] = cl->GetCert(i);
+ std::vector<NSCertEntry *> cl = na->GetAccount()->GetRefs<NSCertEntry *>();
+ for (NSCertEntry *e : cl)
+ replacements["CERTS"] = e->GetCert();
TemplateFileServer page("nickserv/cert.html");
page.Serve(server, page_name, client, message, reply, replacements);
diff --git a/modules/webcpanel/pages/nickserv/cert.h b/modules/webcpanel/pages/nickserv/cert.h
index 7fbd54e20..8dc5adad1 100644
--- a/modules/webcpanel/pages/nickserv/cert.h
+++ b/modules/webcpanel/pages/nickserv/cert.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Cert : public WebPanelProtectedPage
public:
Cert(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/nickserv/info.cpp b/modules/webcpanel/pages/nickserv/info.cpp
index b1c1e2afa..f3c353044 100644
--- a/modules/webcpanel/pages/nickserv/info.cpp
+++ b/modules/webcpanel/pages/nickserv/info.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
@@ -11,83 +23,83 @@ WebCPanel::NickServ::Info::Info(const Anope::string &cat, const Anope::string &u
{
}
-bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
if (message.post_data.empty() == false)
{
if (message.post_data.count("email") > 0)
{
- if (message.post_data["email"] != na->nc->email)
+ if (message.post_data["email"] != na->GetAccount()->GetEmail())
{
if (!message.post_data["email"].empty() && !Mail::Validate(message.post_data["email"]))
replacements["ERRORS"] = "Invalid email";
else
{
- na->nc->email = message.post_data["email"];
+ na->GetAccount()->SetEmail(message.post_data["email"]);
replacements["MESSAGES"] = "Email updated";
}
}
}
if (message.post_data.count("greet") > 0)
{
- Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
+ Anope::string *greet = na->GetAccount()->GetExt<Anope::string>("greet");
const Anope::string &post_greet = HTTPUtils::URLDecode(message.post_data["greet"].replace_all_cs("+", " "));
if (post_greet.empty())
- na->nc->Shrink<Anope::string>("greet");
+ na->GetAccount()->Shrink<Anope::string>("greet");
else if (!greet || post_greet != *greet)
- na->nc->Extend<Anope::string>("greet", post_greet);
+ na->GetAccount()->Extend<Anope::string>("greet", post_greet);
replacements["MESSAGES"] = "Greet updated";
}
- if (na->nc->HasExt("AUTOOP") != message.post_data.count("autoop"))
+ if (na->GetAccount()->HasFieldS("AUTOOP") != message.post_data.count("autoop"))
{
- if (!na->nc->HasExt("AUTOOP"))
- na->nc->Extend<bool>("AUTOOP");
+ if (!na->GetAccount()->HasFieldS("AUTOOP"))
+ na->GetAccount()->SetS<bool>("AUTOOP", true);
else
- na->nc->Shrink<bool>("AUTOOP");
+ na->GetAccount()->UnsetS<bool>("AUTOOP");
replacements["MESSAGES"] = "Autoop updated";
}
- if (na->nc->HasExt("NS_PRIVATE") != message.post_data.count("private"))
+ if (na->GetAccount()->HasFieldS("NS_PRIVATE") != message.post_data.count("private"))
{
- if (!na->nc->HasExt("NS_PRIVATE"))
- na->nc->Extend<bool>("NS_PRIVATE");
+ if (!na->GetAccount()->HasFieldS("NS_PRIVATE"))
+ na->GetAccount()->SetS<bool>("NS_PRIVATE", true);
else
- na->nc->Shrink<bool>("NS_PRIVATE");
+ na->GetAccount()->UnsetS<bool>("NS_PRIVATE");
replacements["MESSAGES"] = "Private updated";
}
- if (na->nc->HasExt("NS_SECURE") != message.post_data.count("secure"))
+ if (na->GetAccount()->HasFieldS("NS_SECURE") != message.post_data.count("secure"))
{
- if (!na->nc->HasExt("NS_SECURE"))
- na->nc->Extend<bool>("NS_SECURE");
+ if (!na->GetAccount()->HasFieldS("NS_SECURE"))
+ na->GetAccount()->SetS<bool>("NS_SECURE", true);
else
- na->nc->Shrink<bool>("NS_SECURE");
+ na->GetAccount()->UnsetS<bool>("NS_SECURE");
replacements["MESSAGES"] = "Secure updated";
}
- if (message.post_data["kill"] == "on" && !na->nc->HasExt("KILLPROTECT"))
+ if (message.post_data["kill"] == "on" && !na->GetAccount()->HasFieldS("KILLPROTECT"))
{
- na->nc->Extend<bool>("KILLPROTECT");
- na->nc->Shrink<bool>("KILL_QUICK");
+ na->GetAccount()->SetS<bool>("KILLPROTECT", true);
+ na->GetAccount()->UnsetS<bool>("KILL_QUICK");
replacements["MESSAGES"] = "Kill updated";
}
- else if (message.post_data["kill"] == "quick" && !na->nc->HasExt("KILL_QUICK"))
+ else if (message.post_data["kill"] == "quick" && !na->GetAccount()->HasFieldS("KILL_QUICK"))
{
- na->nc->Shrink<bool>("KILLPROTECT");
- na->nc->Extend<bool>("KILL_QUICK");
+ na->GetAccount()->UnsetS<bool>("KILLPROTECT");
+ na->GetAccount()->SetS<bool>("KILL_QUICK", true);
replacements["MESSAGES"] = "Kill updated";
}
- else if (message.post_data["kill"] == "off" && (na->nc->HasExt("KILLPROTECT") || na->nc->HasExt("KILL_QUICK")))
+ else if (message.post_data["kill"] == "off" && (na->GetAccount()->HasFieldS("KILLPROTECT") || na->GetAccount()->HasFieldS("KILL_QUICK")))
{
- na->nc->Shrink<bool>("KILLPROTECT");
- na->nc->Shrink<bool>("KILL_QUICK");
+ na->GetAccount()->UnsetS<bool>("KILLPROTECT");
+ na->GetAccount()->UnsetS<bool>("KILL_QUICK");
replacements["MESSAGES"] = "Kill updated";
}
}
- replacements["DISPLAY"] = HTTPUtils::Escape(na->nc->display);
- if (na->nc->email.empty() == false)
- replacements["EMAIL"] = HTTPUtils::Escape(na->nc->email);
- replacements["TIME_REGISTERED"] = Anope::strftime(na->time_registered, na->nc);
+ replacements["DISPLAY"] = HTTPUtils::Escape(na->GetAccount()->GetDisplay());
+ if (na->GetAccount()->GetEmail().empty() == false)
+ replacements["EMAIL"] = HTTPUtils::Escape(na->GetAccount()->GetEmail());
+ replacements["TIME_REGISTERED"] = Anope::strftime(na->GetTimeRegistered(), na->GetAccount());
if (na->HasVhost())
{
if (na->GetVhostIdent().empty() == false)
@@ -95,22 +107,22 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
else
replacements["VHOST"] = na->GetVhostHost();
}
- Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
+ Anope::string *greet = na->GetAccount()->GetExt<Anope::string>("greet");
if (greet)
replacements["GREET"] = HTTPUtils::Escape(*greet);
- if (na->nc->HasExt("AUTOOP"))
+ if (na->GetAccount()->HasFieldS("AUTOOP"))
replacements["AUTOOP"];
- if (na->nc->HasExt("NS_PRIVATE"))
+ if (na->GetAccount()->HasFieldS("NS_PRIVATE"))
replacements["PRIVATE"];
- if (na->nc->HasExt("NS_SECURE"))
+ if (na->GetAccount()->HasFieldS("NS_SECURE"))
replacements["SECURE"];
- if (na->nc->HasExt("KILLPROTECT"))
+ if (na->GetAccount()->HasFieldS("KILLPROTECT"))
replacements["KILL_ON"];
- if (na->nc->HasExt("KILL_QUICK"))
+ if (na->GetAccount()->HasFieldS("KILL_QUICK"))
replacements["KILL_QUICK"];
- if (!na->nc->HasExt("KILLPROTECT") && !na->nc->HasExt("KILL_QUICK"))
+ if (!na->GetAccount()->HasFieldS("KILLPROTECT") && !na->GetAccount()->HasFieldS("KILL_QUICK"))
replacements["KILL_OFF"];
-
+
TemplateFileServer page("nickserv/info.html");
page.Serve(server, page_name, client, message, reply, replacements);
return true;
diff --git a/modules/webcpanel/pages/nickserv/info.h b/modules/webcpanel/pages/nickserv/info.h
index fd4cb2a3c..09ae4d3ee 100644
--- a/modules/webcpanel/pages/nickserv/info.h
+++ b/modules/webcpanel/pages/nickserv/info.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -16,7 +28,7 @@ class Info : public WebPanelProtectedPage
public:
Info(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/operserv/akill.cpp b/modules/webcpanel/pages/operserv/akill.cpp
index bc09c4216..a4cdb26be 100644
--- a/modules/webcpanel/pages/operserv/akill.cpp
+++ b/modules/webcpanel/pages/operserv/akill.cpp
@@ -1,28 +1,38 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../../webcpanel.h"
-WebCPanel::OperServ::Akill::Akill(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
+WebCPanel::OperServ::Akill::Akill(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u), akills("xlinemanager/sgline")
{
}
-bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, ::NickServ::Nick *na, TemplateFileServer::Replacements &replacements)
{
-
- static ServiceReference<XLineManager> akills("XLineManager","xlinemanager/sgline");
-
- if (!na->nc->o || !na->nc->o->ot->HasCommand("operserv/akill"))
+ if (!na->GetAccount()->o || !na->GetAccount()->o->GetType()->HasCommand("operserv/akill"))
{
replacements["NOACCESS"];
}
else
{
- if (akills->GetCount() == 0)
+ std::vector<XLine *> xlines = akills->GetXLines();
+ if (xlines.empty())
replacements["AKILLS"] = "No Akills to display.";
if (message.post_data.count("mask") > 0 && message.post_data.count("expiry") > 0 && message.post_data.count("reason") > 0)
@@ -34,7 +44,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]);
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]);
params.push_back(cmdstr.str());
- WebPanel::RunCommand(na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "OperServ", "operserv/akill", params, replacements);
}
if (message.get_data["del"] == "1" && message.get_data.count("number") > 0)
@@ -42,18 +52,18 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
std::vector<Anope::string> params;
params.push_back("DEL");
params.push_back(HTTPUtils::URLDecode(message.get_data["number"]));
- WebPanel::RunCommand(na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
+ WebPanel::RunCommand(na->GetAccount()->GetDisplay(), na->GetAccount(), "OperServ", "operserv/akill", params, replacements);
}
- for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
+ unsigned int i = 0;
+ for (XLine *x : xlines)
{
- const XLine *x = akills->GetEntry(i);
- replacements["NUMBER"] = stringify(i + 1);
- replacements["HOST"] = x->mask;
- replacements["SETTER"] = x->by;
- replacements["TIME"] = Anope::strftime(x->created, NULL, true);
- replacements["EXPIRE"] = Anope::Expires(x->expires, na->nc);
- replacements["REASON"] = x->reason;
+ replacements["NUMBER"] = stringify(++i);
+ replacements["HOST"] = x->GetMask();
+ replacements["SETTER"] = x->GetBy();
+ replacements["TIME"] = Anope::strftime(x->GetCreated(), NULL, true);
+ replacements["EXPIRE"] = Anope::Expires(x->GetExpires(), na->GetAccount());
+ replacements["REASON"] = x->GetReason();
}
}
diff --git a/modules/webcpanel/pages/operserv/akill.h b/modules/webcpanel/pages/operserv/akill.h
index 1801a4fbd..76435c450 100644
--- a/modules/webcpanel/pages/operserv/akill.h
+++ b/modules/webcpanel/pages/operserv/akill.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
namespace WebCPanel
@@ -13,10 +25,12 @@ namespace OperServ
class Akill : public WebPanelProtectedPage
{
+ ServiceReference<XLineManager> akills;
+
public:
Akill(const Anope::string &cat, const Anope::string &u);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, ::NickServ::Nick *, TemplateFileServer::Replacements &) override;
};
}
diff --git a/modules/webcpanel/pages/register.cpp b/modules/webcpanel/pages/register.cpp
index 7da8b37c3..c662397ab 100644
--- a/modules/webcpanel/pages/register.cpp
+++ b/modules/webcpanel/pages/register.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "../webcpanel.h"
diff --git a/modules/webcpanel/pages/register.h b/modules/webcpanel/pages/register.h
index 2daff1b74..fec14058f 100644
--- a/modules/webcpanel/pages/register.h
+++ b/modules/webcpanel/pages/register.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "modules/httpd.h"
@@ -15,7 +27,7 @@ class Register : public WebPanelPage
public:
Register(const Anope::string &u) : WebPanelPage(u) { }
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) override;
};
}
diff --git a/modules/webcpanel/static_fileserver.cpp b/modules/webcpanel/static_fileserver.cpp
index 47f191b46..858336c6c 100644
--- a/modules/webcpanel/static_fileserver.cpp
+++ b/modules/webcpanel/static_fileserver.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "webcpanel.h"
@@ -35,7 +47,7 @@ bool StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page
char buffer[BUFSIZE];
while ((i = read(fd, buffer, sizeof(buffer))) > 0)
reply.Write(buffer, i);
-
+
close(fd);
return true;
}
diff --git a/modules/webcpanel/static_fileserver.h b/modules/webcpanel/static_fileserver.h
index 2e2ec3f5c..63d041301 100644
--- a/modules/webcpanel/static_fileserver.h
+++ b/modules/webcpanel/static_fileserver.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "modules/httpd.h"
@@ -14,6 +26,6 @@ class StaticFileServer : public HTTPPage
public:
StaticFileServer(const Anope::string &f_n, const Anope::string &u, const Anope::string &c_t);
- bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) override;
};
diff --git a/modules/webcpanel/template_fileserver.cpp b/modules/webcpanel/template_fileserver.cpp
index 7436265d1..81c4c4a5f 100644
--- a/modules/webcpanel/template_fileserver.cpp
+++ b/modules/webcpanel/template_fileserver.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "webcpanel.h"
@@ -79,7 +91,7 @@ static Anope::string FindReplacement(const TemplateFileServer::Replacements &r,
}
}
}
-
+
TemplateFileServer::Replacements::const_iterator it = r.find(key);
if (it != r.end())
return it->second;
@@ -110,7 +122,7 @@ void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_n
buffer[i] = 0;
buf += buffer;
}
-
+
close(fd);
Anope::string finished;
@@ -235,7 +247,7 @@ void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_n
// If the if stack is empty or we are in a true statement
bool ifok = IfStack.empty() || IfStack.top();
bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r);
-
+
if (ifok && forok)
{
const Anope::string &replacement = FindReplacement(r, content.substr(0, f - 1));
@@ -252,7 +264,7 @@ void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_n
// If the if stack is empty or we are in a true statement
bool ifok = IfStack.empty() || IfStack.top();
bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r);
-
+
if (ifok && forok)
finished += buf[j];
}
diff --git a/modules/webcpanel/template_fileserver.h b/modules/webcpanel/template_fileserver.h
index 84be3c71f..5f381d70a 100644
--- a/modules/webcpanel/template_fileserver.h
+++ b/modules/webcpanel/template_fileserver.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "modules/httpd.h"
diff --git a/modules/webcpanel/templates/default/confirm.html b/modules/webcpanel/templates/default/confirm.html
index 652dbd116..871f42118 100644
--- a/modules/webcpanel/templates/default/confirm.html
+++ b/modules/webcpanel/templates/default/confirm.html
@@ -39,7 +39,7 @@
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<div class="footer text-center">
- Anope IRC Services - &copy; 2013-2016 Anope Team - <a href="http://anope.org">http://anope.org</a>
+ Anope IRC Services - &copy; 2013-2014 Anope Team - <a href="http://anope.org">http://anope.org</a>
</div>
</div>
</div>
diff --git a/modules/webcpanel/templates/default/footer.html b/modules/webcpanel/templates/default/footer.html
index fcaaaeb6e..0c6878921 100644
--- a/modules/webcpanel/templates/default/footer.html
+++ b/modules/webcpanel/templates/default/footer.html
@@ -5,7 +5,7 @@
<div class="row">
<div class="col-lg-12">
<div class="footer text-center">
- Anope IRC Services - &copy; 2013-2016 Anope Team - <a href="http://anope.org">http://anope.org</a>
+ Anope IRC Services - &copy; 2013-2014 Anope Team - <a href="http://anope.org">http://anope.org</a>
</div>
</div>
</div>
diff --git a/modules/webcpanel/templates/default/login.html b/modules/webcpanel/templates/default/login.html
index 0916721a2..16e0684fa 100644
--- a/modules/webcpanel/templates/default/login.html
+++ b/modules/webcpanel/templates/default/login.html
@@ -43,7 +43,7 @@
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<div class="footer text-center">
- Anope IRC Services - &copy; 2013-2016 Anope Team - <a href="http://anope.org">http://anope.org</a>
+ Anope IRC Services - &copy; 2013-2014 Anope Team - <a href="http://anope.org">http://anope.org</a>
</div>
</div>
</div>
diff --git a/modules/webcpanel/templates/default/register.html b/modules/webcpanel/templates/default/register.html
index 6cee78a70..0cf8e2543 100644
--- a/modules/webcpanel/templates/default/register.html
+++ b/modules/webcpanel/templates/default/register.html
@@ -53,7 +53,7 @@
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<div class="footer text-center">
- Anope IRC Services - &copy; 2013-2016 Anope Team - <a href="http://anope.org">http://anope.org</a>
+ Anope IRC Services - &copy; 2013-2014 Anope Team - <a href="http://anope.org">http://anope.org</a>
</div>
</div>
</div>
diff --git a/modules/webcpanel/webcpanel.cpp b/modules/webcpanel/webcpanel.cpp
index 4f0bc009a..9da3cc70e 100644
--- a/modules/webcpanel/webcpanel.cpp
+++ b/modules/webcpanel/webcpanel.cpp
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "webcpanel.h"
@@ -14,7 +26,7 @@ class ModuleWebCPanel : public Module
{
ServiceReference<HTTPProvider> provider;
Panel panel;
- PrimitiveExtensibleItem<Anope::string> id, ip;
+ ExtensibleItem<Anope::string> id, ip;
StaticFileServer style_css, logo_png, cubes_png, favicon_ico;
@@ -43,25 +55,42 @@ class ModuleWebCPanel : public Module
public:
- ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- panel(this, "webcpanel"), id(this, "webcpanel_id"), ip(this, "webcpanel_ip"),
- style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), cubes_png("cubes.png", "/static/cubes.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
- index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
- nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
- chanserv_info("ChanServ", "/chanserv/info"), chanserv_set("ChanServ", "/chanserv/set"), chanserv_access("ChanServ", "/chanserv/access"), chanserv_akick("ChanServ", "/chanserv/akick"),
- chanserv_modes("ChanServ", "/chanserv/modes"), chanserv_drop("ChanServ", "/chanserv/drop"), memoserv_memos("MemoServ", "/memoserv/memos"), hostserv_request("HostServ", "/hostserv/request"),
- operserv_akill("OperServ", "/operserv/akill")
+ ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , panel(this, "webcpanel")
+ , id(this, "webcpanel_id")
+ , ip(this, "webcpanel_ip")
+ , style_css("style.css", "/static/style.css", "text/css")
+ , logo_png("logo.png", "/static/logo.png", "image/png")
+ , cubes_png("cubes.png", "/static/cubes.png", "image/png")
+ , favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon")
+ , index("/")
+ , logout("/logout")
+ , _register("/register")
+ , confirm("/confirm")
+ , nickserv_info("NickServ", "/nickserv/info")
+ , nickserv_cert("NickServ", "/nickserv/cert")
+ , nickserv_access("NickServ", "/nickserv/access")
+ , nickserv_alist("NickServ", "/nickserv/alist")
+ , chanserv_info("ChanServ", "/chanserv/info")
+ , chanserv_set("ChanServ", "/chanserv/set")
+ , chanserv_access("ChanServ", "/chanserv/access")
+ , chanserv_akick("ChanServ", "/chanserv/akick")
+ , chanserv_modes("ChanServ", "/chanserv/modes")
+ , chanserv_drop("ChanServ", "/chanserv/drop")
+ , memoserv_memos("MemoServ", "/memoserv/memos")
+ , hostserv_request("HostServ", "/hostserv/request")
+ , operserv_akill("OperServ", "/operserv/akill")
{
me = this;
Configuration::Block *block = Config->GetModule(this);
- provider_name = block->Get<const Anope::string>("server", "httpd/main");
- template_name = block->Get<const Anope::string>("template", "default");
+ provider_name = block->Get<Anope::string>("server", "httpd/main");
+ template_name = block->Get<Anope::string>("template", "default");
template_base = Anope::DataDir + "/modules/webcpanel/templates/" + template_name;
- page_title = block->Get<const Anope::string>("title", "Anope IRC Services");
+ page_title = block->Get<Anope::string>("title", "Anope IRC Services");
- provider = ServiceReference<HTTPProvider>("HTTPProvider", provider_name);
+ provider = ServiceReference<HTTPProvider>(provider_name);
if (!provider)
throw ModuleException("Unable to find HTTPD provider. Is m_httpd loaded?");
@@ -75,7 +104,7 @@ class ModuleWebCPanel : public Module
provider->RegisterPage(&this->_register);
provider->RegisterPage(&this->confirm);
- BotInfo *NickServ = Config->GetClient("NickServ");
+ ServiceBot *NickServ = Config->GetClient("NickServ");
if (NickServ)
{
Section s;
@@ -108,7 +137,7 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- BotInfo *ChanServ = Config->GetClient("ChanServ");
+ ServiceBot *ChanServ = Config->GetClient("ChanServ");
if (ChanServ)
{
Section s;
@@ -148,7 +177,7 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- BotInfo *MemoServ = Config->GetClient("MemoServ");
+ ServiceBot *MemoServ = Config->GetClient("MemoServ");
if (MemoServ)
{
Section s;
@@ -163,7 +192,7 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- BotInfo *HostServ = Config->GetClient("HostServ");
+ ServiceBot *HostServ = Config->GetClient("HostServ");
if (HostServ)
{
Section s;
@@ -178,7 +207,7 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- BotInfo *OperServ = Config->GetClient("OperServ");
+ ServiceBot *OperServ = Config->GetClient("OperServ");
if (OperServ)
{
Section s;
@@ -221,7 +250,7 @@ class ModuleWebCPanel : public Module
provider->UnregisterPage(&this->chanserv_drop);
provider->UnregisterPage(&this->memoserv_memos);
-
+
provider->UnregisterPage(&this->hostserv_request);
provider->UnregisterPage(&this->operserv_akill);
@@ -231,9 +260,9 @@ class ModuleWebCPanel : public Module
namespace WebPanel
{
- void RunCommand(const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key)
+ void RunCommand(const Anope::string &user, NickServ::Account *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key)
{
- ServiceReference<Command> cmd("Command", c);
+ ServiceReference<Command> cmd(c);
if (!cmd)
{
r[key] = "Unable to find command " + c;
@@ -243,13 +272,9 @@ namespace WebPanel
if (params.size() < cmd->min_params)
return;
- BotInfo *bi = Config->GetClient(service);
+ ServiceBot *bi = Config->GetClient(service);
if (!bi)
- {
- if (BotListByNick->empty())
- return;
- bi = BotListByNick->begin()->second; // Pick one...
- }
+ return;
struct MyComandReply : CommandReply
{
@@ -258,7 +283,7 @@ namespace WebPanel
MyComandReply(TemplateFileServer::Replacements &_r, const Anope::string &_k) : re(_r), k(_k) { }
- void SendMessage(BotInfo *source, const Anope::string &msg) anope_override
+ void SendMessage(const MessageSource &, const Anope::string &msg) override
{
re[k] = msg;
}
@@ -271,16 +296,16 @@ namespace WebPanel
cmd->Run(source, "", info, params);
}
- void RunCommandWithName(NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key)
+ void RunCommandWithName(NickServ::Account *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key)
{
- ServiceReference<Command> cmd("Command", c);
+ ServiceReference<Command> cmd(c);
if (!cmd)
{
r[key] = "Unable to find command " + c;
return;
}
- BotInfo *bi = Config->GetClient(service);
+ ServiceBot *bi = Config->GetClient(service);
if (!bi)
return;
@@ -295,14 +320,14 @@ namespace WebPanel
MyComandReply(TemplateFileServer::Replacements &_r, const Anope::string &_k) : re(_r), k(_k) { }
- void SendMessage(BotInfo *source, const Anope::string &msg) anope_override
+ void SendMessage(const MessageSource &, const Anope::string &msg) override
{
re[k] = msg;
}
}
my_reply(r, key);
- CommandSource source(nc->display, NULL, nc, &my_reply, bi);
+ CommandSource source(nc->GetDisplay(), NULL, nc, &my_reply, bi);
cmd->Run(source, cmdname, *info, params);
}
diff --git a/modules/webcpanel/webcpanel.h b/modules/webcpanel/webcpanel.h
index 5112a632e..33e88821d 100644
--- a/modules/webcpanel/webcpanel.h
+++ b/modules/webcpanel/webcpanel.h
@@ -1,8 +1,20 @@
/*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Anope IRC Services
*
- * Please read COPYING and README for further details.
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -31,11 +43,13 @@ struct Section
class Panel : public Section, public Service
{
public:
- Panel(Module *c, const Anope::string &n) : Service(c, "Panel", n) { }
+ static constexpr const char *NAME = "panel";
+
+ Panel(Module *c, const Anope::string &n) : Service(c, NAME, "") { }
std::vector<Section> sections;
- NickAlias *GetNickFromSession(HTTPClient *client, HTTPMessage &msg)
+ NickServ::Nick *GetNickFromSession(HTTPClient *client, HTTPMessage &msg)
{
if (!client)
return NULL;
@@ -45,7 +59,7 @@ class Panel : public Section, public Service
if (acc.empty() || id.empty())
return NULL;
- NickAlias *na = NickAlias::Find(acc);
+ NickServ::Nick *na = NickServ::FindNick(acc);
if (na == NULL)
return NULL;
@@ -68,22 +82,22 @@ class WebPanelPage : public HTTPPage
{
}
- virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0;
+ virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_abstract;
};
class WebPanelProtectedPage : public WebPanelPage
{
Anope::string category;
+ ServiceReference<Panel> panel;
public:
WebPanelProtectedPage(const Anope::string &cat, const Anope::string &u, const Anope::string &ct = "text/html") : WebPanelPage(u, ct), category(cat)
{
}
- bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) anope_override anope_final
+ bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) override final
{
- ServiceReference<Panel> panel("Panel", "webcpanel");
- NickAlias *na;
+ NickServ::Nick *na;
if (!panel || !(na = panel->GetNickFromSession(client, message)))
{
@@ -95,10 +109,10 @@ class WebPanelProtectedPage : public WebPanelPage
TemplateFileServer::Replacements replacements;
replacements["TITLE"] = page_title;
- replacements["ACCOUNT"] = na->nc->display;
+ replacements["ACCOUNT"] = na->GetAccount()->GetDisplay();
replacements["PAGE_NAME"] = page_name;
replacements["CATEGORY"] = category;
- if (na->nc->IsServicesOper())
+ if (na->GetAccount()->IsServicesOper())
replacements["IS_OPER"];
Anope::string sections, get;
@@ -134,7 +148,7 @@ class WebPanelProtectedPage : public WebPanelPage
return this->OnRequest(provider, page_name, client, message, reply, na, replacements);
}
- virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) = 0;
+ virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickServ::Nick *, TemplateFileServer::Replacements &) anope_abstract;
/* What get data should be appended to links in the navbar */
virtual std::set<Anope::string> GetData() { return std::set<Anope::string>(); }
@@ -143,7 +157,7 @@ class WebPanelProtectedPage : public WebPanelPage
namespace WebPanel
{
/** Run a command
- * @param User name to run command as, probably nc->display unless nc == NULL
+ * @param User name to run command as, probably nc->GetDisplay() unless nc == NULL
* @param nc Nick core to run command from
* @param service Service for source.owner and source.service
* @param c Command to run (as a service name)
@@ -151,9 +165,9 @@ namespace WebPanel
* @param r Replacements, reply from command goes back here into key
* @param key The key to put the replies into r
*/
- extern void RunCommand(const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
+ extern void RunCommand(const Anope::string &user, NickServ::Account *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
- extern void RunCommandWithName(NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
+ extern void RunCommandWithName(NickServ::Account *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> &params, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
}
#include "pages/index.h"
diff --git a/modules/m_xmlrpc.cpp b/modules/xmlrpc.cpp
index 7539825d1..41bbfce0a 100644
--- a/modules/m_xmlrpc.cpp
+++ b/modules/xmlrpc.cpp
@@ -1,9 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
@@ -39,12 +50,12 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
public:
MyXMLRPCServiceInterface(Module *creator, const Anope::string &sname) : XMLRPCServiceInterface(creator, sname), HTTPPage("/xmlrpc", "text/xml") { }
- void Register(XMLRPCEvent *event)
+ void Register(XMLRPCEvent *event) override
{
this->events.push_back(event);
}
- void Unregister(XMLRPCEvent *event)
+ void Unregister(XMLRPCEvent *event) override
{
std::deque<XMLRPCEvent *>::iterator it = std::find(this->events.begin(), this->events.end(), event);
@@ -52,7 +63,7 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
this->events.erase(it);
}
- Anope::string Sanitize(const Anope::string &string) anope_override
+ Anope::string Sanitize(const Anope::string &string) override
{
Anope::string ret = string;
for (int i = 0; special[i].character.empty() == false; ++i)
@@ -144,7 +155,7 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
}
public:
- bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) anope_override
+ bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) override
{
Anope::string content = message.content, tname, data;
XMLRPCRequest request(reply);
@@ -181,7 +192,7 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
return true;
}
- void Reply(XMLRPCRequest &request)
+ void Reply(XMLRPCRequest &request) override
{
if (!request.id.empty())
request.reply("id", request.id);
@@ -198,11 +209,12 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
class ModuleXMLRPC : public Module
{
ServiceReference<HTTPProvider> httpref;
+
public:
MyXMLRPCServiceInterface xmlrpcinterface;
- ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- xmlrpcinterface(this, "xmlrpc")
+ ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ , xmlrpcinterface(this, "xmlrpc")
{
}
@@ -213,13 +225,16 @@ class ModuleXMLRPC : public Module
httpref->UnregisterPage(&xmlrpcinterface);
}
- void OnReload(Configuration::Conf *conf) anope_override
+ void OnReload(Configuration::Conf *conf) override
{
if (httpref)
httpref->UnregisterPage(&xmlrpcinterface);
- this->httpref = ServiceReference<HTTPProvider>("HTTPProvider", conf->GetModule(this)->Get<const Anope::string>("server", "httpd/main"));
+
+ this->httpref = ServiceReference<HTTPProvider>(conf->GetModule(this)->Get<Anope::string>("server", "httpd/main"));
+
if (!httpref)
throw ConfigException("Unable to find http reference, is m_httpd loaded?");
+
httpref->RegisterPage(&xmlrpcinterface);
}
};
diff --git a/modules/m_xmlrpc_main.cpp b/modules/xmlrpc_main.cpp
index ed89ec07e..cdbcf3266 100644
--- a/modules/m_xmlrpc_main.cpp
+++ b/modules/xmlrpc_main.cpp
@@ -1,17 +1,29 @@
/*
+ * Anope IRC Services
*
- * (C) 2010-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "module.h"
#include "modules/xmlrpc.h"
+#include "modules/operserv/stats.h"
static Module *me;
-class XMLRPCIdentifyRequest : public IdentifyRequest
+class XMLRPCIdentifyRequest : public NickServ::IdentifyRequestListener
{
XMLRPCRequest request;
HTTPReply repl; /* Request holds a reference to the HTTPReply, because we might exist long enough to invalidate it
@@ -20,9 +32,9 @@ class XMLRPCIdentifyRequest : public IdentifyRequest
Reference<XMLRPCServiceInterface> xinterface;
public:
- XMLRPCIdentifyRequest(Module *m, XMLRPCRequest& req, HTTPClient *c, XMLRPCServiceInterface* iface, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), request(req), repl(request.r), client(c), xinterface(iface) { }
+ XMLRPCIdentifyRequest(XMLRPCRequest& req, HTTPClient *c, XMLRPCServiceInterface* iface) : request(req), repl(request.r), client(c), xinterface(iface) { }
- void OnSuccess() anope_override
+ void OnSuccess(NickServ::IdentifyRequest *req) override
{
if (!xinterface || !client)
return;
@@ -30,13 +42,13 @@ class XMLRPCIdentifyRequest : public IdentifyRequest
request.r = this->repl;
request.reply("result", "Success");
- request.reply("account", GetAccount());
+ request.reply("account", req->GetAccount());
xinterface->Reply(request);
client->SendReply(&request.r);
}
- void OnFail() anope_override
+ void OnFail(NickServ::IdentifyRequest *req) override
{
if (!xinterface || !client)
return;
@@ -53,7 +65,7 @@ class XMLRPCIdentifyRequest : public IdentifyRequest
class MyXMLRPCEvent : public XMLRPCEvent
{
public:
- bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) anope_override
+ bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) override
{
if (request.name == "command")
this->DoCommand(iface, client, request);
@@ -84,14 +96,14 @@ class MyXMLRPCEvent : public XMLRPCEvent
request.reply("error", "Invalid parameters");
else
{
- BotInfo *bi = BotInfo::Find(service, true);
+ ServiceBot *bi = ServiceBot::Find(service, true);
if (!bi)
request.reply("error", "Invalid service");
else
{
request.reply("result", "Success");
- NickAlias *na = NickAlias::Find(user);
+ NickServ::Nick *na = NickServ::FindNick(user);
Anope::string out;
@@ -101,14 +113,14 @@ class MyXMLRPCEvent : public XMLRPCEvent
XMLRPCommandReply(Anope::string &s) : str(s) { }
- void SendMessage(BotInfo *, const Anope::string &msg) anope_override
+ void SendMessage(const MessageSource &, const Anope::string &msg) override
{
str += msg + "\n";
};
}
reply(out);
- CommandSource source(user, NULL, na ? *na->nc : NULL, &reply, bi);
+ CommandSource source(user, NULL, na ? na->GetAccount() : NULL, &reply, bi);
Command::Run(source, command);
if (!out.empty())
@@ -122,21 +134,23 @@ class MyXMLRPCEvent : public XMLRPCEvent
Anope::string username = request.data.size() > 0 ? request.data[0] : "";
Anope::string password = request.data.size() > 1 ? request.data[1] : "";
- if (username.empty() || password.empty())
+ if (username.empty() || password.empty() || !NickServ::service)
request.reply("error", "Invalid parameters");
else
{
- XMLRPCIdentifyRequest *req = new XMLRPCIdentifyRequest(me, request, client, iface, username, password);
- FOREACH_MOD(OnCheckAuthentication, (NULL, req));
+ NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new XMLRPCIdentifyRequest(request, client, iface), me, username, password);
+ EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req);
req->Dispatch();
return false;
}
-
+
return true;
}
void DoStats(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
{
+ Stats *stats = Serialize::GetObject<Stats *>();
+
request.reply("uptime", stringify(Anope::CurTime - Anope::StartTime));
request.reply("uplinkname", Me->GetLinks().front()->GetName());
{
@@ -148,7 +162,7 @@ class MyXMLRPCEvent : public XMLRPCEvent
request.reply("uplinkcapab", buf);
}
request.reply("usercount", stringify(UserListByNick.size()));
- request.reply("maxusercount", stringify(MaxUserCount));
+ request.reply("maxusercount", stringify(stats ? stats->GetMaxUserCount() : 0));
request.reply("channelcount", stringify(ChannelList.size()));
}
@@ -227,9 +241,9 @@ class MyXMLRPCEvent : public XMLRPCEvent
request.reply("signon", stringify(u->signon));
if (u->Account())
{
- request.reply("account", iface->Sanitize(u->Account()->display));
+ request.reply("account", iface->Sanitize(u->Account()->GetDisplay()));
if (u->Account()->o)
- request.reply("opertype", iface->Sanitize(u->Account()->o->ot->GetName()));
+ request.reply("opertype", iface->Sanitize(u->Account()->o->GetType()->GetName()));
}
Anope::string channels;
@@ -266,7 +280,7 @@ class MyXMLRPCEvent : public XMLRPCEvent
Anope::string to = request.data.size() > 1 ? request.data[1] : "";
Anope::string message = request.data.size() > 2 ? request.data[2] : "";
- BotInfo *bi = BotInfo::Find(from, true);
+ ServiceBot *bi = ServiceBot::Find(from, true);
User *u = User::Find(to, true);
if (!bi || !u || message.empty())
@@ -285,7 +299,7 @@ class ModuleXMLRPCMain : public Module
MyXMLRPCEvent stats;
public:
- ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), xmlrpc("XMLRPCServiceInterface", "xmlrpc")
+ ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
{
me = this;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b390d164b..007e3605a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,72 +2,37 @@
file(GLOB SRC_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
if(WIN32)
- append_to_list(SRC_SRCS win32/dir/dir.cpp)
- append_to_list(SRC_SRCS win32/socket.cpp)
- append_to_list(SRC_SRCS win32/windows.cpp)
- append_to_list(SRC_SRCS win32/dl/dl.cpp)
- append_to_list(SRC_SRCS win32/pipe/pipe.cpp)
- append_to_list(SRC_SRCS win32/pthread/pthread.cpp)
- append_to_list(SRC_SRCS win32/sigaction/sigaction.cpp)
-endif(WIN32)
+ list(APPEND SRC_SRCS win32/dir/dir.cpp)
+ list(APPEND SRC_SRCS win32/socket.cpp)
+ list(APPEND SRC_SRCS win32/windows.cpp)
+ list(APPEND SRC_SRCS win32/dl/dl.cpp)
+ list(APPEND SRC_SRCS win32/pipe/pipe.cpp)
+ list(APPEND SRC_SRCS win32/sigaction/sigaction.cpp)
+endif()
if(HAVE_EPOLL)
- append_to_list(SRC_SRCS socketengines/socketengine_epoll.cpp)
-else(HAVE_EPOLL)
- if(HAVE_KQUEUE)
- append_to_list(SRC_SRCS socketengines/socketengine_kqueue.cpp)
- else(HAVE_KQUEUE)
- if(HAVE_POLL)
- append_to_list(SRC_SRCS socketengines/socketengine_poll.cpp)
- else(HAVE_POLL)
- append_to_list(SRC_SRCS socketengines/socketengine_select.cpp)
- endif(HAVE_POLL)
- endif(HAVE_KQUEUE)
-endif(HAVE_EPOLL)
+ list(APPEND SRC_SRCS socketengines/socketengine_epoll.cpp)
+elseif(HAVE_KQUEUE)
+ list(APPEND SRC_SRCS socketengines/socketengine_kqueue.cpp)
+elseif(HAVE_POLL)
+ list(APPEND SRC_SRCS socketengines/socketengine_poll.cpp)
+else()
+ list(APPEND SRC_SRCS socketengines/socketengine_select.cpp)
+endif()
-sort_list(SRC_SRCS)
+list(SORT SRC_SRCS)
# Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though)
set_source_files_properties(${SRC_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
-# Create an empty list to store extra include directories
-set(EXTRA_INCLUDES)
-# Iterate through all the source files
-foreach(SRC ${SRC_SRCS})
- # Temporary variable for the current source's include directories
- set(TEMP_INCLUDES)
- # Calculate the header file dependencies for the given source file
- calculate_depends(${SRC} TEMP_INCLUDES)
- # If there were some extra include directories, add them to the list
- if(TEMP_INCLUDES)
- append_to_list(EXTRA_INCLUDES ${TEMP_INCLUDES})
- endif(TEMP_INCLUDES)
-endforeach(SRC)
-# If there were extra include directories, remove the duplicates and add the directories to the include path
-if(EXTRA_INCLUDES)
- remove_list_duplicates(EXTRA_INCLUDES)
- include_directories(${EXTRA_INCLUDES})
-endif(EXTRA_INCLUDES)
-
# Under Windows, we also include a resource file to the build
if(WIN32)
# Make sure that the resource file is seen as an RC file to be compiled with a resource compiler, not a C++ compiler
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc LANGUAGE RC)
# Add the resource file to the list of sources
- append_to_list(SRC_SRCS ${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc)
- # For MinGW, we have to change the compile flags
- if(MINGW)
- set(RC_CFLAGS "-DMINGW -Ocoff -I${Anope_SOURCE_DIR}/include")
- # If any sort of debugging is being enabled, add a _DEBUG define to the flags for the resource compiler
- if(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
- set(RC_CFLAGS "${RC_CFLAGS} -D_DEBUG")
- endif(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
- set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "${RC_CFLAGS}")
- # For anything else, assumingly Visual Studio at this point, use a different set of compile flags
- else(MINGW)
- set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "/i\"${Anope_SOURCE_DIR}/include\"")
- endif(MINGW)
-endif(WIN32)
+ list(APPEND SRC_SRCS ${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc)
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "/i\"${Anope_SOURCE_DIR}/include\"")
+endif()
# If compiling with Visual Studio, create a static library out of win32/win32_memory.cpp to be included with everything else, needed to override its override of new/delete operators
if(MSVC)
@@ -75,26 +40,26 @@ if(MSVC)
add_library(win32_memory STATIC win32/win32_memory.cpp)
set(WIN32_MEMORY win32_memory)
set(EXTRA_LDFLAGS "/OPT:NOREF") # https://sourceware.org/bugzilla/show_bug.cgi?id=12633
-else(MSVC)
+else()
set(WIN32_MEMORY)
-endif(MSVC)
+endif()
# Generate the Anope executable and set it's linker flags, also set it to export it's symbols even though it's not a module
add_executable(${PROGRAM_NAME} ${SRC_SRCS})
set_target_properties(${PROGRAM_NAME} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS} ${EXTRA_LDFLAGS}" ENABLE_EXPORTS ON INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
# On Windows, also link Anope to the wsock32 and Ws2_32 library, as well as set the version
if(WIN32)
- target_link_libraries(${PROGRAM_NAME} wsock32 Ws2_32 ${LINK_LIBS} ${GETTEXT_LIBRARIES} ${WIN32_MEMORY})
+ target_link_libraries(${PROGRAM_NAME} wsock32 Ws2_32 ${LINK_LIBS} ${GETTEXT_LIBRARIES} ${Boost_LIBRARIES} ${WIN32_MEMORY})
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
-else(WIN32)
- target_link_libraries(${PROGRAM_NAME} ${LINK_LIBS} ${GETTEXT_LIBRARIES})
-endif(WIN32)
+else()
+ target_link_libraries(${PROGRAM_NAME} ${LINK_LIBS} ${GETTEXT_LIBRARIES} ${Boost_LIBRARIES})
+endif()
# Building the Anope executable requires the version.h header to be generated
add_dependencies(${PROGRAM_NAME} headers)
# Also require the language files if we have gettext
if(GETTEXT_FOUND)
add_dependencies(${PROGRAM_NAME} language)
-endif(GETTEXT_FOUND)
+endif()
# Get the filename of the Anope executable as it is in on this system
get_target_property(SERVICES_BINARY ${PROGRAM_NAME} LOCATION)
@@ -108,7 +73,7 @@ configure_file(${Anope_SOURCE_DIR}/include/sysconf.h.cmake ${Anope_BINARY_DIR}/i
# Go into the following directories and run their CMakeLists.txt as well
if(NOT DISABLE_TOOLS)
add_subdirectory(tools)
-endif(NOT DISABLE_TOOLS)
+endif()
# Set Anope to be installed to the bin directory
install(TARGETS ${PROGRAM_NAME}
diff --git a/src/access.cpp b/src/access.cpp
deleted file mode 100644
index 007e6d281..000000000
--- a/src/access.cpp
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "service.h"
-#include "access.h"
-#include "regchannel.h"
-#include "users.h"
-#include "account.h"
-#include "protocol.h"
-
-static struct
-{
- Anope::string name;
- Anope::string desc;
-} descriptions[] = {
- {"ACCESS_CHANGE", _("Allowed to modify the access list")},
- {"ACCESS_LIST", _("Allowed to view the access list")},
- {"AKICK", _("Allowed to use the AKICK command")},
- {"ASSIGN", _("Allowed to assign/unassign a bot")},
- {"AUTOHALFOP", _("Automatic halfop upon join")},
- {"AUTOOP", _("Automatic channel operator status upon join")},
- {"AUTOOWNER", _("Automatic owner upon join")},
- {"AUTOPROTECT", _("Automatic protect upon join")},
- {"AUTOVOICE", _("Automatic voice on join")},
- {"BADWORDS", _("Allowed to modify channel badwords list")},
- {"BAN", _("Allowed to ban users")},
- {"FANTASIA", _("Allowed to use fantasy commands")},
- {"FOUNDER", _("Allowed to issue commands restricted to channel founders")},
- {"GETKEY", _("Allowed to use GETKEY command")},
- {"GREET", _("Greet message displayed on join")},
- {"HALFOP", _("Allowed to (de)halfop users")},
- {"HALFOPME", _("Allowed to (de)halfop him/herself")},
- {"INFO", _("Allowed to get full INFO output")},
- {"INVITE", _("Allowed to use the INVITE command")},
- {"KICK", _("Allowed to use the KICK command")},
- {"MEMO", _("Allowed to read channel memos")},
- {"MODE", _("Allowed to use the MODE command")},
- {"NOKICK", _("Prevents users being kicked by Services")},
- {"OP", _("Allowed to (de)op users")},
- {"OPME", _("Allowed to (de)op him/herself")},
- {"OWNER", _("Allowed to (de)owner users")},
- {"OWNERME", _("Allowed to (de)owner him/herself")},
- {"PROTECT", _("Allowed to (de)protect users")},
- {"PROTECTME", _("Allowed to (de)protect him/herself")},
- {"SAY", _("Allowed to use SAY and ACT commands")},
- {"SET", _("Allowed to set channel settings")},
- {"SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used")},
- {"TOPIC", _("Allowed to change channel topics")},
- {"UNBAN", _("Allowed to unban users")},
- {"VOICE", _("Allowed to (de)voice users")},
- {"VOICEME", _("Allowed to (de)voice him/herself")}
-};
-
-Privilege::Privilege(const Anope::string &n, const Anope::string &d, int r) : name(n), desc(d), rank(r)
-{
- if (this->desc.empty())
- for (unsigned j = 0; j < sizeof(descriptions) / sizeof(*descriptions); ++j)
- if (descriptions[j].name.equals_ci(name))
- this->desc = descriptions[j].desc;
-}
-
-bool Privilege::operator==(const Privilege &other) const
-{
- return this->name.equals_ci(other.name);
-}
-
-std::vector<Privilege> PrivilegeManager::Privileges;
-
-void PrivilegeManager::AddPrivilege(Privilege p)
-{
- unsigned i;
- for (i = 0; i < Privileges.size(); ++i)
- {
- Privilege &priv = Privileges[i];
-
- if (priv.rank > p.rank)
- break;
- }
-
- Privileges.insert(Privileges.begin() + i, p);
-}
-
-void PrivilegeManager::RemovePrivilege(Privilege &p)
-{
- std::vector<Privilege>::iterator it = std::find(Privileges.begin(), Privileges.end(), p);
- if (it != Privileges.end())
- Privileges.erase(it);
-
- for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit)
- {
- cit->second->QueueUpdate();
- cit->second->RemoveLevel(p.name);
- }
-}
-
-Privilege *PrivilegeManager::FindPrivilege(const Anope::string &name)
-{
- for (unsigned i = Privileges.size(); i > 0; --i)
- if (Privileges[i - 1].name.equals_ci(name))
- return &Privileges[i - 1];
- return NULL;
-}
-
-std::vector<Privilege> &PrivilegeManager::GetPrivileges()
-{
- return Privileges;
-}
-
-void PrivilegeManager::ClearPrivileges()
-{
- Privileges.clear();
-}
-
-AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service(o, "AccessProvider", n)
-{
- Providers.push_back(this);
-}
-
-AccessProvider::~AccessProvider()
-{
- std::list<AccessProvider *>::iterator it = std::find(Providers.begin(), Providers.end(), this);
- if (it != Providers.end())
- Providers.erase(it);
-}
-
-std::list<AccessProvider *> AccessProvider::Providers;
-
-const std::list<AccessProvider *>& AccessProvider::GetProviders()
-{
- return Providers;
-}
-
-ChanAccess::ChanAccess(AccessProvider *p) : Serializable("ChanAccess"), provider(p)
-{
-}
-
-ChanAccess::~ChanAccess()
-{
- if (this->ci)
- {
- std::vector<ChanAccess *>::iterator it = std::find(this->ci->access->begin(), this->ci->access->end(), this);
- if (it != this->ci->access->end())
- this->ci->access->erase(it);
-
- if (*nc != NULL)
- nc->RemoveChannelReference(this->ci);
- else
- {
- ChannelInfo *c = ChannelInfo::Find(this->mask);
- if (c)
- c->RemoveChannelReference(this->ci->name);
- }
- }
-}
-
-void ChanAccess::SetMask(const Anope::string &m, ChannelInfo *c)
-{
- if (*nc != NULL)
- nc->RemoveChannelReference(this->ci);
- else if (!this->mask.empty())
- {
- ChannelInfo *targc = ChannelInfo::Find(this->mask);
- if (targc)
- targc->RemoveChannelReference(this->ci->name);
- }
-
- ci = c;
- mask.clear();
- nc = NULL;
-
- const NickAlias *na = NickAlias::Find(m);
- if (na != NULL)
- {
- nc = na->nc;
- nc->AddChannelReference(ci);
- }
- else
- {
- mask = m;
-
- ChannelInfo *targci = ChannelInfo::Find(mask);
- if (targci != NULL)
- targci->AddChannelReference(ci->name);
- }
-}
-
-const Anope::string &ChanAccess::Mask() const
-{
- if (nc)
- return nc->display;
- else
- return mask;
-}
-
-NickCore *ChanAccess::GetAccount() const
-{
- return nc;
-}
-
-void ChanAccess::Serialize(Serialize::Data &data) const
-{
- data["provider"] << this->provider->name;
- data["ci"] << this->ci->name;
- data["mask"] << this->Mask();
- data["creator"] << this->creator;
- data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
- data["data"] << this->AccessSerialize();
-}
-
-Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string provider, chan;
-
- data["provider"] >> provider;
- data["ci"] >> chan;
-
- ServiceReference<AccessProvider> aprovider("AccessProvider", provider);
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (!aprovider || !ci)
- return NULL;
-
- ChanAccess *access;
- if (obj)
- access = anope_dynamic_static_cast<ChanAccess *>(obj);
- else
- access = aprovider->Create();
- access->ci = ci;
- Anope::string m;
- data["mask"] >> m;
- access->SetMask(m, ci);
- data["creator"] >> access->creator;
- data["last_seen"] >> access->last_seen;
- data["created"] >> access->created;
-
- Anope::string adata;
- data["data"] >> adata;
- access->AccessUnserialize(adata);
-
- if (!obj)
- ci->AddAccess(access);
- return access;
-}
-
-bool ChanAccess::Matches(const User *u, const NickCore *acc, ChannelInfo* &next) const
-{
- next = NULL;
-
- if (this->nc)
- return this->nc == acc;
-
- if (u)
- {
- bool is_mask = this->mask.find_first_of("!@?*") != Anope::string::npos;
- if (is_mask && Anope::Match(u->nick, this->mask))
- return true;
- else if (Anope::Match(u->GetDisplayedMask(), this->mask))
- return true;
- }
-
- if (acc)
- {
- for (unsigned i = 0; i < acc->aliases->size(); ++i)
- {
- const NickAlias *na = acc->aliases->at(i);
- if (Anope::Match(na->nick, this->mask))
- return true;
- }
- }
-
- if (IRCD->IsChannelValid(this->mask))
- {
- next = ChannelInfo::Find(this->mask);
- }
-
- return false;
-}
-
-bool ChanAccess::operator>(const ChanAccess &other) const
-{
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = privs.size(); i > 0; --i)
- {
- bool this_p = this->HasPriv(privs[i - 1].name),
- other_p = other.HasPriv(privs[i - 1].name);
-
- if (!this_p && !other_p)
- continue;
-
- return this_p && !other_p;
- }
-
- return false;
-}
-
-bool ChanAccess::operator<(const ChanAccess &other) const
-{
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = privs.size(); i > 0; --i)
- {
- bool this_p = this->HasPriv(privs[i - 1].name),
- other_p = other.HasPriv(privs[i - 1].name);
-
- if (!this_p && !other_p)
- continue;
-
- return !this_p && other_p;
- }
-
- return false;
-}
-
-bool ChanAccess::operator>=(const ChanAccess &other) const
-{
- return !(*this < other);
-}
-
-bool ChanAccess::operator<=(const ChanAccess &other) const
-{
- return !(*this > other);
-}
-
-AccessGroup::AccessGroup()
-{
- this->ci = NULL;
- this->nc = NULL;
- this->super_admin = this->founder = false;
-}
-
-static bool HasPriv(const ChanAccess::Path &path, const Anope::string &name)
-{
- if (path.empty())
- return false;
-
- for (unsigned int i = 0; i < path.size(); ++i)
- {
- ChanAccess *access = path[i];
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnCheckPriv, MOD_RESULT, (access, name));
-
- if (MOD_RESULT != EVENT_ALLOW && !access->HasPriv(name))
- return false;
- }
-
- return true;
-}
-
-bool AccessGroup::HasPriv(const Anope::string &name) const
-{
- if (this->super_admin)
- return true;
- else if (!ci || ci->GetLevel(name) == ACCESS_INVALID)
- return false;
-
- /* Privileges prefixed with auto are understood to be given
- * automatically. Sometimes founders want to not automatically
- * obtain privileges, so we will let them */
- bool auto_mode = !name.find("AUTO");
-
- /* Only grant founder privilege if this isn't an auto mode or if they don't match any entries in this group */
- if ((!auto_mode || paths.empty()) && this->founder)
- return true;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnGroupCheckPriv, MOD_RESULT, (this, name));
- if (MOD_RESULT != EVENT_CONTINUE)
- return MOD_RESULT == EVENT_ALLOW;
-
- for (unsigned int i = paths.size(); i > 0; --i)
- {
- const ChanAccess::Path &path = paths[i - 1];
-
- if (::HasPriv(path, name))
- return true;
- }
-
- return false;
-}
-
-static ChanAccess *HighestInPath(const ChanAccess::Path &path)
-{
- ChanAccess *highest = NULL;
-
- for (unsigned int i = 0; i < path.size(); ++i)
- if (highest == NULL || *path[i] > *highest)
- highest = path[i];
-
- return highest;
-}
-
-const ChanAccess *AccessGroup::Highest() const
-{
- ChanAccess *highest = NULL;
-
- for (unsigned int i = 0; i < paths.size(); ++i)
- {
- ChanAccess *hip = HighestInPath(paths[i]);
-
- if (highest == NULL || *hip > *highest)
- highest = hip;
- }
-
- return highest;
-}
-
-bool AccessGroup::operator>(const AccessGroup &other) const
-{
- if (other.super_admin)
- return false;
- else if (this->super_admin)
- return true;
- else if (other.founder)
- return false;
- else if (this->founder)
- return true;
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = privs.size(); i > 0; --i)
- {
- bool this_p = this->HasPriv(privs[i - 1].name),
- other_p = other.HasPriv(privs[i - 1].name);
-
- if (!this_p && !other_p)
- continue;
-
- return this_p && !other_p;
- }
-
- return false;
-}
-
-bool AccessGroup::operator<(const AccessGroup &other) const
-{
- if (this->super_admin)
- return false;
- else if (other.super_admin)
- return true;
- else if (this->founder)
- return false;
- else if (other.founder)
- return true;
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = privs.size(); i > 0; --i)
- {
- bool this_p = this->HasPriv(privs[i - 1].name),
- other_p = other.HasPriv(privs[i - 1].name);
-
- if (!this_p && !other_p)
- continue;
-
- return !this_p && other_p;
- }
-
- return false;
-}
-
-bool AccessGroup::operator>=(const AccessGroup &other) const
-{
- return !(*this < other);
-}
-
-bool AccessGroup::operator<=(const AccessGroup &other) const
-{
- return !(*this > other);
-}
-
diff --git a/src/accessgroup.cpp b/src/accessgroup.cpp
new file mode 100644
index 000000000..a674f4723
--- /dev/null
+++ b/src/accessgroup.cpp
@@ -0,0 +1,125 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "modules/chanserv.h"
+#include "accessgroup.h"
+
+using namespace ChanServ;
+
+bool AccessGroup::HasPriv(const Anope::string &priv)
+{
+ if (this->super_admin)
+ return true;
+ else if (!ci || ci->GetLevel(priv) == ACCESS_INVALID)
+ return false;
+
+ /* Privileges prefixed with auto are understood to be given
+ * automatically. Sometimes founders want to not automatically
+ * obtain privileges, so we will let them */
+ bool auto_mode = !priv.find("AUTO");
+
+ /* Only grant founder privilege if this isn't an auto mode or if they don't match any entries in this group */
+ if ((!auto_mode || this->empty()) && this->founder)
+ return true;
+
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&::Event::GroupCheckPriv::OnGroupCheckPriv, this, priv);
+ if (MOD_RESULT != EVENT_CONTINUE)
+ return MOD_RESULT == EVENT_ALLOW;
+
+ for (unsigned i = this->size(); i > 0; --i)
+ {
+ ChanAccess *access = this->at(i - 1);
+
+ if (access->HasPriv(priv))
+ return true;
+ }
+
+ return false;
+}
+
+ChanAccess *AccessGroup::Highest()
+{
+ ChanAccess *highest = NULL;
+ for (unsigned i = 0; i < this->size(); ++i)
+ if (highest == NULL || *this->at(i) > *highest)
+ highest = this->at(i);
+ return highest;
+}
+
+bool AccessGroup::operator>(AccessGroup &other)
+{
+ if (other.super_admin)
+ return false;
+ else if (this->super_admin)
+ return true;
+ else if (other.founder)
+ return false;
+ else if (this->founder)
+ return true;
+
+ const std::vector<Privilege> &privs = service->GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ {
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
+
+ if (!this_p && !other_p)
+ continue;
+
+ return this_p && !other_p;
+ }
+
+ return false;
+}
+
+bool AccessGroup::operator<(AccessGroup &other)
+{
+ if (this->super_admin)
+ return false;
+ else if (other.super_admin)
+ return true;
+ else if (this->founder)
+ return false;
+ else if (other.founder)
+ return true;
+
+ const std::vector<Privilege> &privs = service->GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ {
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
+
+ if (!this_p && !other_p)
+ continue;
+
+ return !this_p && other_p;
+ }
+
+ return false;
+}
+
+bool AccessGroup::operator>=(AccessGroup &other)
+{
+ return !(*this < other);
+}
+
+bool AccessGroup::operator<=(AccessGroup &other)
+{
+ return !(*this > other);
+} \ No newline at end of file
diff --git a/src/account.cpp b/src/account.cpp
deleted file mode 100644
index f23f81242..000000000
--- a/src/account.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "services.h"
-#include "account.h"
-#include "modules.h"
-#include "users.h"
-#include "protocol.h"
-#include "regchannel.h"
-
-std::set<IdentifyRequest *> IdentifyRequest::Requests;
-
-IdentifyRequest::IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass) : owner(o), account(acc), password(pass), dispatched(false), success(false)
-{
- Requests.insert(this);
-}
-
-IdentifyRequest::~IdentifyRequest()
-{
- Requests.erase(this);
-}
-
-void IdentifyRequest::Hold(Module *m)
-{
- holds.insert(m);
-}
-
-void IdentifyRequest::Release(Module *m)
-{
- holds.erase(m);
- if (holds.empty() && dispatched)
- {
- if (!success)
- this->OnFail();
- delete this;
- }
-}
-
-void IdentifyRequest::Success(Module *m)
-{
- if (!success)
- {
- this->OnSuccess();
- success = true;
- }
-}
-
-void IdentifyRequest::Dispatch()
-{
- if (holds.empty())
- {
- if (!success)
- this->OnFail();
- delete this;
- }
- else
- dispatched = true;
-}
-
-void IdentifyRequest::ModuleUnload(Module *m)
-{
- for (std::set<IdentifyRequest *>::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end;)
- {
- IdentifyRequest *ir = *it;
- ++it;
-
- ir->holds.erase(m);
- if (ir->holds.empty() && ir->dispatched)
- {
- if (!ir->success)
- ir->OnFail();
- delete ir;
- continue;
- }
-
- if (ir->owner == m)
- {
- if (!ir->success)
- ir->OnFail();
- delete ir;
- }
- }
-}
diff --git a/src/base.cpp b/src/base.cpp
index 5e4ecc9e3..c35a654b4 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -1,17 +1,47 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "anope.h"
#include "service.h"
+#include "base.h"
+
+std::set<ReferenceBase *> *ReferenceBase::references = NULL;
+
+ReferenceBase::ReferenceBase()
+{
+ if (references == NULL)
+ references = new std::set<ReferenceBase *>();
+ references->insert(this);
+}
-std::map<Anope::string, std::map<Anope::string, Service *> > Service::Services;
-std::map<Anope::string, std::map<Anope::string, Anope::string> > Service::Aliases;
+ReferenceBase::~ReferenceBase()
+{
+ references->erase(this);
+}
+
+void ReferenceBase::ResetAll()
+{
+ if (references)
+ for (ReferenceBase *b : *references)
+ b->Reset();
+}
Base::Base() : references(NULL)
{
diff --git a/src/base64.cpp b/src/base64.cpp
index 3096d9c3f..5c2d721ad 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -1,12 +1,20 @@
-/* base64 routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2004-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
diff --git a/src/bots.cpp b/src/bots.cpp
index 7654bb247..07d6ec858 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -1,9 +1,21 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -12,25 +24,29 @@
#include "servers.h"
#include "protocol.h"
#include "xline.h"
-#include "regchannel.h"
#include "channels.h"
#include "config.h"
#include "language.h"
#include "serialize.h"
+#include "event.h"
+#include "modules/chanserv.h"
-Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo");
-
-BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
+ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : LocalUser(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), botmodes(bmodes)
{
- this->lastmsg = this->created = Anope::CurTime;
+ this->type = UserType::BOT;
+ this->lastmsg = Anope::CurTime;
this->introduced = false;
- this->oper_only = this->conf = false;
- (*BotListByNick)[this->nick] = this;
- if (!this->uid.empty())
- (*BotListByUID)[this->uid] = this;
-
- FOREACH_MOD(OnCreateBot, (this));
+ bi = Serialize::New<BotInfo *>();
+ bi->bot = this;
+
+ bi->SetNick(nnick);
+ bi->SetUser(nuser);
+ bi->SetHost(nhost);
+ bi->SetRealName(nreal);
+ bi->SetCreated(Anope::CurTime);
+
+ EventManager::Get()->Dispatch(&Event::CreateBot::OnCreateBot, this);
// If we're synchronised with the uplink already, send the bot.
if (Me && Me->IsSynced())
@@ -39,92 +55,46 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A
if (!tmodes.empty())
this->SetModesInternal(this, tmodes.c_str());
- XLine x(this->nick, "Reserved for services");
- IRCD->SendSQLine(NULL, &x);
+ //XXX
+ //XLine x(this->nick, "Reserved for services");
+ //IRCD->SendSQLine(NULL, &x);
IRCD->SendClientIntroduction(this);
this->introduced = true;
}
}
-BotInfo::~BotInfo()
+ServiceBot::~ServiceBot()
{
- UnsetExtensibles();
+ bi->bot = nullptr;
+ bi->Delete();
- FOREACH_MOD(OnDelBot, (this));
+ EventManager::Get()->Dispatch(&Event::DelBot::OnDelBot, this);
// If we're synchronised with the uplink already, send the bot.
if (Me && Me->IsSynced())
{
IRCD->SendQuit(this, "");
- FOREACH_MOD(OnUserQuit, (this, ""));
+ EventManager::Get()->Dispatch(&Event::UserQuit::OnUserQuit, this, "");
this->introduced = false;
- XLine x(this->nick);
- IRCD->SendSQLineDel(&x);
- }
-
- for (std::set<ChannelInfo *>::iterator it = this->channels->begin(), it_end = this->channels->end(); it != it_end; ++it)
- {
- ChannelInfo *ci = *it;
- this->UnAssign(NULL, ci);
+ // XXX ?
+ //XLine x(this->nick);
+ //IRCD->SendSQLineDel(&x);
}
-
- BotListByNick->erase(this->nick);
- if (!this->uid.empty())
- BotListByUID->erase(this->uid);
}
-void BotInfo::Serialize(Serialize::Data &data) const
-{
- data["nick"] << this->nick;
- data["user"] << this->ident;
- data["host"] << this->host;
- data["realname"] << this->realname;
- data["created"] << this->created;
- data["oper_only"] << this->oper_only;
-
- Extensible::ExtensibleSerialize(this, this, data);
-}
-Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string nick, user, host, realname, flags;
-
- data["nick"] >> nick;
- data["user"] >> user;
- data["host"] >> host;
- data["realname"] >> realname;
-
- BotInfo *bi;
- if (obj)
- bi = anope_dynamic_static_cast<BotInfo *>(obj);
- else if (!(bi = BotInfo::Find(nick, true)))
- bi = new BotInfo(nick, user, host, realname);
-
- data["created"] >> bi->created;
- data["oper_only"] >> bi->oper_only;
-
- Extensible::ExtensibleUnserialize(bi, bi, data);
-
- return bi;
-}
-
-void BotInfo::GenerateUID()
+void ServiceBot::GenerateUID()
{
if (this->introduced)
throw CoreException("Changing bot UID when it is introduced?");
if (!this->uid.empty())
- {
- BotListByUID->erase(this->uid);
UserListByUID.erase(this->uid);
- }
-
this->uid = IRCD->UID_Retrieve();
- (*BotListByUID)[this->uid] = this;
UserListByUID[this->uid] = this;
}
-void BotInfo::OnKill()
+void ServiceBot::OnKill()
{
this->introduced = false;
this->GenerateUID();
@@ -135,63 +105,60 @@ void BotInfo::OnKill()
IRCD->SendJoin(this, cit->second->chan, &cit->second->status);
}
-void BotInfo::SetNewNick(const Anope::string &newnick)
+void ServiceBot::SetNewNick(const Anope::string &newnick)
{
UserListByNick.erase(this->nick);
- BotListByNick->erase(this->nick);
+ bi->SetNick(newnick);
this->nick = newnick;
UserListByNick[this->nick] = this;
- (*BotListByNick)[this->nick] = this;
}
-const std::set<ChannelInfo *> &BotInfo::GetChannels() const
+std::vector<ChanServ::Channel *> ServiceBot::GetChannels() const
{
- return this->channels;
+ return bi->GetRefs<ChanServ::Channel *>();
}
-void BotInfo::Assign(User *u, ChannelInfo *ci)
+void ServiceBot::Assign(User *u, ChanServ::Channel *ci)
{
EventReturn MOD_RESULT;
- FOREACH_RESULT(OnPreBotAssign, MOD_RESULT, (u, ci, this));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreBotAssign::OnPreBotAssign, u, ci, this);
if (MOD_RESULT == EVENT_STOP)
return;
- if (ci->bi)
- ci->bi->UnAssign(u, ci);
-
- ci->bi = this;
- this->channels->insert(ci);
+ if (ci->GetBot())
+ ci->GetBot()->UnAssign(u, ci);
+
+ ci->SetBot(this);
- FOREACH_MOD(OnBotAssign, (u, ci, this));
+ EventManager::Get()->Dispatch(&Event::BotAssign::OnBotAssign, u, ci, this);
}
-void BotInfo::UnAssign(User *u, ChannelInfo *ci)
+void ServiceBot::UnAssign(User *u, ChanServ::Channel *ci)
{
EventReturn MOD_RESULT;
- FOREACH_RESULT(OnBotUnAssign, MOD_RESULT, (u, ci));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotUnAssign::OnBotUnAssign, u, ci);
if (MOD_RESULT == EVENT_STOP)
return;
- if (ci->c && ci->c->FindUser(ci->bi))
+ if (ci->c && ci->c->FindUser(ci->GetBot()))
{
if (u)
- ci->bi->Part(ci->c, "UNASSIGN from " + u->nick);
+ ci->GetBot()->Part(ci->c, "UNASSIGN from " + u->nick);
else
- ci->bi->Part(ci->c);
+ ci->GetBot()->Part(ci->c);
}
- ci->bi = NULL;
- this->channels->erase(ci);
+ ci->SetBot(nullptr);
}
-unsigned BotInfo::GetChannelCount() const
+unsigned ServiceBot::GetChannelCount() const
{
- return this->channels->size();
+ return GetChannels().size();
}
-void BotInfo::Join(Channel *c, ChannelStatus *status)
+void ServiceBot::Join(Channel *c, ChannelStatus *status)
{
if (c->FindUser(this) != NULL)
return;
@@ -200,30 +167,30 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
if (IRCD)
IRCD->SendJoin(this, c, status);
- FOREACH_MOD(OnJoinChannel, (this, c));
+ EventManager::Get()->Dispatch(&Event::JoinChannel::OnJoinChannel, this, c);
}
-void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
+void ServiceBot::Join(const Anope::string &chname, ChannelStatus *status)
{
bool c;
return this->Join(Channel::FindOrCreate(chname, c), status);
}
-void BotInfo::Part(Channel *c, const Anope::string &reason)
+void ServiceBot::Part(Channel *c, const Anope::string &reason)
{
if (c->FindUser(this) == NULL)
return;
- FOREACH_MOD(OnPrePartChannel, (this, c));
+ EventManager::Get()->Dispatch(&Event::PrePartChannel::OnPrePartChannel, this, c);
IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : "");
c->DeleteUser(this);
- FOREACH_MOD(OnPartChannel, (this, c, c->name, reason));
+ EventManager::Get()->Dispatch(&Event::PartChannel::OnPartChannel, this, c, c->name, reason);
}
-void BotInfo::OnMessage(User *u, const Anope::string &message)
+void ServiceBot::OnMessage(User *u, const Anope::string &message)
{
if (this->commands.empty())
return;
@@ -232,16 +199,17 @@ void BotInfo::OnMessage(User *u, const Anope::string &message)
Command::Run(source, message);
}
-CommandInfo& BotInfo::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission)
+CommandInfo& ServiceBot::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission)
{
CommandInfo ci;
ci.name = sname;
+ ci.cname = cname;
ci.permission = permission;
this->commands[cname] = ci;
return this->commands[cname];
}
-CommandInfo *BotInfo::GetCommand(const Anope::string &cname)
+CommandInfo *ServiceBot::GetCommand(const Anope::string &cname)
{
CommandInfo::map::iterator it = this->commands.find(cname);
if (it != this->commands.end())
@@ -249,30 +217,96 @@ CommandInfo *BotInfo::GetCommand(const Anope::string &cname)
return NULL;
}
-BotInfo* BotInfo::Find(const Anope::string &nick, bool nick_only)
+CommandInfo *ServiceBot::FindCommand(const Anope::string &service)
{
- if (!nick_only && IRCD != NULL && IRCD->RequiresID)
+ for (auto& it : commands)
{
- botinfo_map::iterator it = BotListByUID->find(nick);
- if (it != BotListByUID->end())
- {
- BotInfo *bi = it->second;
- bi->QueueUpdate();
- return bi;
- }
-
- if (IRCD->AmbiguousID)
- return NULL;
+ CommandInfo &ci = it.second;
+
+ if (ci.name == service)
+ return &ci;
}
- botinfo_map::iterator it = BotListByNick->find(nick);
- if (it != BotListByNick->end())
+ return nullptr;
+}
+
+ServiceBot* ServiceBot::Find(const Anope::string &nick, bool nick_only)
+{
+ User *u = User::Find(nick, nick_only);
+ if (u && u->type == UserType::BOT)
+ return anope_dynamic_static_cast<ServiceBot *>(u);
+ return nullptr;
+}
+
+void BotInfo::Delete()
+{
+ if (bot)
{
- BotInfo *bi = it->second;
- bi->QueueUpdate();
- return bi;
+ ServiceBot *b = bot;
+ bot = nullptr;
+ delete b;
}
- return NULL;
+ return Serialize::Object::Delete();
+}
+
+void BotInfo::SetCreated(const time_t &t)
+{
+ Set(&BotInfoType::created, t);
+}
+
+time_t BotInfo::GetCreated()
+{
+ return Get(&BotInfoType::created);
+}
+
+void BotInfo::SetOperOnly(const bool &b)
+{
+ Set(&BotInfoType::operonly, b);
+}
+
+bool BotInfo::GetOperOnly()
+{
+ return Get(&BotInfoType::operonly);
+}
+
+void BotInfo::SetNick(const Anope::string &n)
+{
+ Set(&BotInfoType::nick, n);
+}
+
+Anope::string BotInfo::GetNick()
+{
+ return Get(&BotInfoType::nick);
+}
+
+void BotInfo::SetUser(const Anope::string &u)
+{
+ Set(&BotInfoType::user, u);
+}
+
+Anope::string BotInfo::GetUser()
+{
+ return Get(&BotInfoType::user);
+}
+
+void BotInfo::SetHost(const Anope::string &h)
+{
+ Set(&BotInfoType::host, h);
+}
+
+Anope::string BotInfo::GetHost()
+{
+ return Get(&BotInfoType::host);
+}
+
+void BotInfo::SetRealName(const Anope::string &r)
+{
+ Set(&BotInfoType::realname, r);
+}
+
+Anope::string BotInfo::GetRealName()
+{
+ return Get(&BotInfoType::realname);
}
diff --git a/src/channels.cpp b/src/channels.cpp
index 3d824f0d8..98ecfe127 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -1,29 +1,36 @@
-/* Channel-handling routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "channels.h"
-#include "regchannel.h"
#include "logger.h"
#include "modules.h"
#include "users.h"
-#include "bots.h"
#include "servers.h"
#include "protocol.h"
#include "users.h"
#include "config.h"
-#include "access.h"
#include "sockets.h"
#include "language.h"
#include "uplink.h"
+#include "event.h"
+#include "modules/chanserv.h"
channel_map ChannelList;
std::vector<Channel *> Channel::deleting;
@@ -40,21 +47,15 @@ Channel::Channel(const Anope::string &nname, time_t ts)
this->server_modetime = this->chanserv_modetime = 0;
this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0;
- this->ci = ChannelInfo::Find(this->name);
- if (this->ci)
- this->ci->c = this;
-
if (Me && Me->IsSynced())
Log(NULL, this, "create");
- FOREACH_MOD(OnChannelCreate, (this));
+ EventManager::Get()->Dispatch(&Event::ChannelCreate::OnChannelCreate, this);
}
Channel::~Channel()
{
- UnsetExtensibles();
-
- FOREACH_MOD(OnChannelDelete, (this));
+ EventManager::Get()->Dispatch(&Event::ChannelDelete::OnChannelDelete, this);
ModeManager::StackerDel(this);
@@ -90,7 +91,7 @@ void Channel::Reset()
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
this->SetCorrectModes(it->second->user, true);
-
+
// If the channel is syncing now, do not force a sync due to Reset(), as we are probably iterating over users in Message::SJoin
// A sync will come soon
if (!syncing)
@@ -100,7 +101,7 @@ void Channel::Reset()
void Channel::Sync()
{
syncing = false;
- FOREACH_MOD(OnChannelSync, (this));
+ EventManager::Get()->Dispatch(&Event::ChannelSync::OnChannelSync, this);
CheckModes();
}
@@ -118,7 +119,7 @@ void Channel::CheckModes()
}
Reference<Channel> ref = this;
- FOREACH_MOD(OnCheckModes, (ref));
+ EventManager::Get()->Dispatch(&Event::CheckModes::OnCheckModes, ref);
}
bool Channel::CheckDelete()
@@ -128,13 +129,13 @@ bool Channel::CheckDelete()
*/
if (this->syncing)
return false;
-
+
/* Permanent channels never get deleted */
if (this->HasMode("PERM"))
return false;
EventReturn MOD_RESULT;
- FOREACH_RESULT(OnCheckDelete, MOD_RESULT, (this));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::CheckDelete::OnCheckDelete, this);
return MOD_RESULT != EVENT_STOP && this->users.empty();
}
@@ -158,7 +159,7 @@ void Channel::DeleteUser(User *user)
if (user->server && user->server->IsSynced() && !user->Quitting())
Log(user, this, "leave");
- FOREACH_MOD(OnLeaveChannel, (user, this));
+ EventManager::Get()->Dispatch(&Event::LeaveChannel::OnLeaveChannel, user, this);
ChanUserContainer *cu = user->FindChannel(this);
if (!this->users.erase(user))
@@ -257,7 +258,7 @@ std::vector<Anope::string> Channel::GetModeList(const Anope::string &mname)
return r;
}
-void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock)
+void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock)
{
if (!ocm)
return;
@@ -291,7 +292,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano
if (cc)
cc->status.AddMode(cm->mchar);
- FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeSet::OnChannelModeSet, this, setter, cm, param);
/* Enforce secureops, etc */
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
@@ -312,13 +313,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano
return;
}
- if (cm->type == MODE_LIST)
- {
- ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm);
- cml->OnAdd(this, param);
- }
-
- FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeSet::OnChannelModeSet, this, setter, cm, param);
/* Check if we should enforce mlock */
if (!enforce_mlock || MOD_RESULT == EVENT_STOP)
@@ -327,7 +322,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano
this->CheckModes();
}
-void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock)
+void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock)
{
if (!ocm)
return;
@@ -346,8 +341,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const
return;
}
- BotInfo *bi = BotInfo::Find(param);
- User *u = bi ? bi : User::Find(param);
+ User *u = User::Find(param);
if (!u)
{
@@ -362,7 +356,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const
if (cc)
cc->status.DelMode(cm->mchar);
- FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeUnset::OnChannelModeUnset, this, setter, cm, param);
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
this->SetCorrectModes(u, false);
@@ -381,14 +375,8 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const
}
else
this->modes.erase(cm->name);
-
- if (cm->type == MODE_LIST)
- {
- ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm);
- cml->OnDel(this, param);
- }
- FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeUnset::OnChannelModeUnset, this, setter, cm, param);
if (cm->name == "PERM")
{
@@ -406,7 +394,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const
this->CheckModes();
}
-void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param, bool enforce_mlock)
+void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string &param, bool enforce_mlock)
{
Anope::string wparam = param;
if (!cm)
@@ -455,16 +443,15 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param,
ChannelMode *wcm = cm->Wrap(wparam);
ModeManager::StackerAdd(bi, this, wcm, true, wparam);
- MessageSource ms(bi);
- SetModeInternal(ms, wcm, wparam, enforce_mlock);
+ SetModeInternal(bi, wcm, wparam, enforce_mlock);
}
-void Channel::SetMode(BotInfo *bi, const Anope::string &mname, const Anope::string &param, bool enforce_mlock)
+void Channel::SetMode(User *bi, const Anope::string &mname, const Anope::string &param, bool enforce_mlock)
{
SetMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock);
}
-void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param, bool enforce_mlock)
+void Channel::RemoveMode(User *bi, ChannelMode *cm, const Anope::string &param, bool enforce_mlock)
{
if (!cm)
return;
@@ -509,11 +496,10 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string &para
ChannelMode *wcm = cm->Wrap(wparam);
ModeManager::StackerAdd(bi, this, wcm, false, wparam);
- MessageSource ms(bi);
- RemoveModeInternal(ms, wcm, wparam, enforce_mlock);
+ RemoveModeInternal(bi, wcm, wparam, enforce_mlock);
}
-void Channel::RemoveMode(BotInfo *bi, const Anope::string &mname, const Anope::string &param, bool enforce_mlock)
+void Channel::RemoveMode(User *bi, const Anope::string &mname, const Anope::string &param, bool enforce_mlock)
{
RemoveMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock);
}
@@ -533,7 +519,7 @@ bool Channel::GetParam(const Anope::string &mname, Anope::string &target) const
return false;
}
-void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...)
+void Channel::SetModes(User *bi, bool enforce_mlock, const char *cmodes, ...)
{
char buf[BUFSIZE] = "";
va_list args;
@@ -713,7 +699,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
Log(setter, this, "mode") << modestring << paramstring;
else
Log(LOG_DEBUG) << source.GetName() << " is setting " << this->name << " to " << modestring << paramstring;
-
+
if (enforce_mlock)
this->CheckModes();
}
@@ -734,14 +720,14 @@ bool Channel::MatchesList(User *u, const Anope::string &mode)
return false;
}
-void Channel::KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason)
+bool Channel::KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason)
{
User *sender = source.GetUser();
User *target = User::Find(nick);
if (!target)
{
Log(LOG_DEBUG) << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason;
- return;
+ return false;
}
if (sender)
@@ -755,17 +741,22 @@ void Channel::KickInternal(const MessageSource &source, const Anope::string &nic
if (cu == NULL)
{
Log(LOG_DEBUG) << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name;
- return;
+ return false;
}
ChannelStatus status = cu->status;
- FOREACH_MOD(OnPreUserKicked, (source, cu, reason));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreUserKicked::OnPreUserKicked, source, cu, reason);
+ if ((sender && sender->server == Me) || source.GetServer() == Me)
+ if (MOD_RESULT == EVENT_STOP)
+ return false;
+
this->DeleteUser(target);
- FOREACH_MOD(OnUserKicked, (source, target, this->name, status, reason));
+ EventManager::Get()->Dispatch(&Event::UserKicked::OnUserKicked, source, target, this->name, status, reason);
+ return true;
}
-bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
+bool Channel::Kick(User *source, User *u, const char *reason, ...)
{
va_list args;
char buf[BUFSIZE] = "";
@@ -776,16 +767,13 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
/* Do not kick protected clients or Ulines */
if (u->IsProtected())
return false;
-
- if (bi == NULL)
- bi = this->ci->WhoSends();
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnBotKick, MOD_RESULT, (bi, this, u, buf));
- if (MOD_RESULT == EVENT_STOP)
+ if (source == NULL)
+ source = this->ci->WhoSends();
+
+ if (!this->KickInternal(source, u->nick, buf))
return false;
- IRCD->SendKick(bi, this, u, "%s", buf);
- this->KickInternal(bi, u->nick, buf);
+ IRCD->SendKick(source, this, u, "%s", buf);
return true;
}
@@ -798,7 +786,7 @@ void Channel::ChangeTopicInternal(User *u, const Anope::string &user, const Anop
Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << this->topic_setter << " to " << newtopic;
- FOREACH_MOD(OnTopicUpdated, (u, this, user, this->topic));
+ EventManager::Get()->Dispatch(&Event::TopicUpdated::OnTopicUpdated, u, this, user, this->topic);
}
void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts)
@@ -812,25 +800,25 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop
/* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */
this->topic_time = Anope::CurTime;
- FOREACH_MOD(OnTopicUpdated, (NULL, this, user, this->topic));
+ EventManager::Get()->Dispatch(&Event::TopicUpdated::OnTopicUpdated, nullptr, this, user, this->topic);
}
void Channel::SetCorrectModes(User *user, bool give_modes)
{
if (user == NULL)
return;
-
+
if (!this->ci)
return;
Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << this->name << " (" << (give_modes ? "" : "not ") << "giving modes)";
- AccessGroup u_access = ci->AccessFor(user);
+ ChanServ::AccessGroup u_access = ci->AccessFor(user);
/* Initially only take modes if the channel is being created by a non netmerge */
bool take_modes = this->syncing && user->server->IsSynced();
- FOREACH_MOD(OnSetCorrectModes, (user, this, u_access, give_modes, take_modes));
+ EventManager::Get()->Dispatch(&Event::SetCorrectModes::OnSetCorrectModes, user, this, u_access, give_modes, take_modes);
/* Never take modes from ulines */
if (user->server->IsULined())
@@ -857,7 +845,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
}
}
/* modes that have no privileges assigned shouldn't be removed (like operprefix, ojoin) */
- else if (take_modes && !has_priv && ci->GetLevel(cm->name + "ME") != ACCESS_INVALID && !u_access.HasPriv(cm->name + "ME"))
+ else if (take_modes && !has_priv && ci->GetLevel(cm->name + "ME") != ChanServ::ACCESS_INVALID && !u_access.HasPriv(cm->name + "ME"))
{
/* Only remove modes if they are > voice */
if (cm->name == "VOICE")
@@ -901,15 +889,14 @@ bool Channel::CheckKick(User *user)
Anope::string mask, reason;
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnCheckKick, MOD_RESULT, (user, this, mask, reason));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::CheckKick::OnCheckKick, user, this, mask, reason);
if (MOD_RESULT != EVENT_STOP)
return false;
-
+
if (mask.empty())
mask = this->ci->GetIdealBan(user);
if (reason.empty())
- reason = Language::Translate(user->Account(), CHAN_NOT_ALLOWED_TO_JOIN);
+ reason = Language::Translate(user->Account(), _("You are not permitted to be on this channel."));
Log(LOG_DEBUG) << "Autokicking " << user->nick << " (" << mask << ") from " << this->name;
diff --git a/src/command.cpp b/src/command.cpp
index 35a99eb80..ade17fd45 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -1,9 +1,21 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -11,13 +23,15 @@
#include "users.h"
#include "language.h"
#include "config.h"
-#include "bots.h"
#include "opertype.h"
-#include "access.h"
-#include "regchannel.h"
#include "channels.h"
+#include "event.h"
+#include "bots.h"
+#include "protocol.h"
+#include "modules/botserv.h"
+#include "modules/chanserv.h"
-CommandSource::CommandSource(const Anope::string &n, User *user, NickCore *core, CommandReply *r, BotInfo *bi) : nick(n), u(user), nc(core), reply(r),
+CommandSource::CommandSource(const Anope::string &n, User *user, NickServ::Account *core, CommandReply *r, ServiceBot *bi) : nick(n), u(user), nc(core), reply(r),
c(NULL), service(bi)
{
}
@@ -32,25 +46,25 @@ User *CommandSource::GetUser()
return this->u;
}
-NickCore *CommandSource::GetAccount()
+NickServ::Account *CommandSource::GetAccount()
{
return this->nc;
}
-AccessGroup CommandSource::AccessFor(ChannelInfo *ci)
+ChanServ::AccessGroup CommandSource::AccessFor(ChanServ::Channel *ci)
{
if (this->u)
return ci->AccessFor(this->u);
else if (this->nc)
return ci->AccessFor(this->nc);
else
- return AccessGroup();
+ return ChanServ::AccessGroup();
}
-bool CommandSource::IsFounder(ChannelInfo *ci)
+bool CommandSource::IsFounder(ChanServ::Channel *ci)
{
if (this->u)
- return ::IsFounder(this->u, ci);
+ return ci->IsFounder(this->u);
else if (this->nc)
return *this->nc == ci->GetFounder();
return false;
@@ -61,7 +75,7 @@ bool CommandSource::HasCommand(const Anope::string &cmd)
if (this->u)
return this->u->HasCommand(cmd);
else if (this->nc && this->nc->o)
- return this->nc->o->ot->HasCommand(cmd);
+ return this->nc->o->GetType()->HasCommand(cmd);
return false;
}
@@ -70,7 +84,7 @@ bool CommandSource::HasPriv(const Anope::string &cmd)
if (this->u)
return this->u->HasPriv(cmd);
else if (this->nc && this->nc->o)
- return this->nc->o->ot->HasPriv(cmd);
+ return this->nc->o->GetType()->HasPriv(cmd);
return false;
}
@@ -92,21 +106,6 @@ bool CommandSource::IsOper()
return false;
}
-void CommandSource::Reply(const char *message, ...)
-{
- va_list args;
- char buf[4096]; // Messages can be really big.
-
- const char *translated_message = Language::Translate(this->nc, message);
-
- va_start(args, message);
- vsnprintf(buf, sizeof(buf), translated_message, args);
-
- this->Reply(Anope::string(buf));
-
- va_end(args);
-}
-
void CommandSource::Reply(const Anope::string &message)
{
const char *translated_message = Language::Translate(this->nc, message.c_str());
@@ -114,7 +113,7 @@ void CommandSource::Reply(const Anope::string &message)
sepstream sep(translated_message, '\n', true);
Anope::string tok;
while (sep.GetToken(tok))
- this->reply->SendMessage(this->service, tok);
+ this->reply->SendMessage(*this->service, tok);
}
Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, "Command", sname), max_params(maxparams), min_params(minparams), module(o)
@@ -146,13 +145,13 @@ void Command::SendSyntax(CommandSource &source)
Anope::string s = Language::Translate(source.GetAccount(), _("Syntax"));
if (!this->syntax.empty())
{
- source.Reply("%s: \002%s %s\002", s.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[0].c_str()));
+ source.Reply("{0}: \002{1} {2}\002", s, source.command, Language::Translate(source.GetAccount(), this->syntax[0].c_str()));
Anope::string spaces(s.length(), ' ');
for (unsigned i = 1, j = this->syntax.size(); i < j; ++i)
- source.Reply("%s \002%s %s\002", spaces.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[i].c_str()));
+ source.Reply("{0} \002{1} {2}\002", spaces, source.command, Language::Translate(source.GetAccount(), this->syntax[i].c_str()));
}
else
- source.Reply("%s: \002%s\002", s.c_str(), source.command.c_str());
+ source.Reply("{0}: \002{1}\002", s, source.command);
}
bool Command::AllowUnregistered() const
@@ -182,7 +181,7 @@ const Anope::string Command::GetDesc(CommandSource &) const
void Command::OnServHelp(CommandSource &source)
{
- source.Reply(" %-14s %s", source.command.c_str(), Language::Translate(source.nc, this->GetDesc(source).c_str()));
+ source.Reply(Anope::printf(" %-14s %s", source.command.c_str(), Language::Translate(source.nc, this->GetDesc(source).c_str())));
}
bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; }
@@ -192,7 +191,7 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma
this->SendSyntax(source);
bool has_help = source.service->commands.find("HELP") != source.service->commands.end();
if (has_help)
- source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
+ source.Reply(_("\002{0}{1} HELP {2}\002 for more information."), Config->StrictPrivmsg, source.service->nick, source.command);
}
void Command::Run(CommandSource &source, const Anope::string &message)
@@ -217,20 +216,20 @@ void Command::Run(CommandSource &source, const Anope::string &message)
if (it == source.service->commands.end())
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002{0}\002. \"{1}{2} HELP\" for help."), message, Config->StrictPrivmsg, source.service->nick);
else
- source.Reply(_("Unknown command \002%s\002."), message.c_str());
+ source.Reply(_("Unknown command \002{0}\002."), message);
return;
}
const CommandInfo &info = it->second;
- ServiceReference<Command> c("Command", info.name);
+ ServiceReference<Command> c(info.name);
if (!c)
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002{0}\002. \"{1}{2} HELP\" for help."), message, Config->StrictPrivmsg, source.service->nick);
else
- source.Reply(_("Unknown command \002%s\002."), message.c_str());
+ source.Reply(_("Unknown command \002{0}\002."), message);
Log(source.service) << "Command " << it->first << " exists on me, but its service " << info.name << " was not found!";
return;
}
@@ -255,7 +254,7 @@ void Command::Run(CommandSource &source, const Anope::string &cmdname, const Com
// Command requires registered users only
if (!this->AllowUnregistered() && !source.nc)
{
- source.Reply(NICK_IDENTIFY_REQUIRED);
+ source.Reply(_("Password authentication required for that command."));
if (source.GetUser())
Log(LOG_NORMAL, "access_denied_unreg", source.service) << "Access denied for unregistered user " << source.GetUser()->GetMask() << " with command " << cmdname;
return;
@@ -264,8 +263,7 @@ void Command::Run(CommandSource &source, const Anope::string &cmdname, const Com
source.command = cmdname;
source.permission = info.permission;
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, this, params));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreCommand::OnPreCommand, source, this, params);
if (MOD_RESULT == EVENT_STOP)
return;
@@ -278,23 +276,30 @@ void Command::Run(CommandSource &source, const Anope::string &cmdname, const Com
// If the command requires a permission, and they aren't registered or don't have the required perm, DENIED
if (!info.permission.empty() && !source.HasCommand(info.permission))
{
- source.Reply(ACCESS_DENIED);
+ if (!source.IsOper())
+ source.Reply(_("Access denied. You are not a Services Operator."));
+ else
+ source.Reply(_("Access denied. You do not have access to command \002{0}\002."), info.permission);
if (source.GetUser())
Log(LOG_NORMAL, "access_denied", source.service) << "Access denied for user " << source.GetUser()->GetMask() << " with command " << cmdname;
return;
}
this->Execute(source, params);
- FOREACH_MOD(OnPostCommand, (source, this, params));
+ EventManager::Get()->Dispatch(&Event::PostCommand::OnPostCommand, source, this, params);
}
-bool Command::FindCommandFromService(const Anope::string &command_service, BotInfo* &bot, Anope::string &name)
+bool Command::FindCommandFromService(const Anope::string &command_service, ServiceBot* &bot, Anope::string &name)
{
bot = NULL;
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ for (std::pair<Anope::string, User *> p : UserListByNick)
{
- BotInfo *bi = it->second;
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
for (CommandInfo::map::const_iterator cit = bi->commands.begin(), cit_end = bi->commands.end(); cit != cit_end; ++cit)
{
@@ -309,7 +314,7 @@ bool Command::FindCommandFromService(const Anope::string &command_service, BotIn
return true;
}
}
-
+
return false;
}
diff --git a/src/config.cpp b/src/config.cpp
index c9a4a53c8..6d9cef04d 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1,25 +1,37 @@
-/* Configuration file handling.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "config.h"
-#include "bots.h"
-#include "access.h"
#include "opertype.h"
#include "channels.h"
#include "hashcomp.h"
+#include "event.h"
+#include "bots.h"
+#include "modules.h"
+#include "servers.h"
+#include "protocol.h"
+#include "modules/nickserv.h"
using namespace Configuration;
-File ServicesConf("services.conf", false); // Services configuration file name
+File ServicesConf("anope.conf", false); // Services configuration file name
Conf *Config = NULL;
Block::Block(const Anope::string &n) : name(n), linenum(-1)
@@ -33,47 +45,37 @@ const Anope::string &Block::GetName() const
int Block::CountBlock(const Anope::string &bname)
{
- if (!this)
- return 0;
-
return blocks.count(bname);
}
+Block* Block::GetBlock(const Anope::string &bname)
+{
+ auto it = blocks.find(bname);
+
+ if (it != blocks.end())
+ return &it->second;
+
+ blocks.emplace(bname, bname);
+ return GetBlock(bname);
+}
+
Block* Block::GetBlock(const Anope::string &bname, int num)
{
- if (!this)
- return NULL;
-
std::pair<block_map::iterator, block_map::iterator> it = blocks.equal_range(bname);
for (int i = 0; it.first != it.second; ++it.first, ++i)
if (i == num)
return &it.first->second;
- return NULL;
-}
-
-bool Block::Set(const Anope::string &tag, const Anope::string &value)
-{
- if (!this)
- return false;
-
- items[tag] = value;
- return true;
+ return nullptr;
}
const Block::item_map* Block::GetItems() const
{
- if (this)
- return &items;
- else
- return NULL;
+ return &items;
}
-template<> const Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const
+template<> Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const
{
- if (!this)
- return def;
-
Anope::map<Anope::string>::const_iterator it = items.find(tag);
if (it != items.end())
return it->second;
@@ -83,15 +85,41 @@ template<> const Anope::string Block::Get(const Anope::string &tag, const Anope:
template<> time_t Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- return Anope::DoTime(Get<const Anope::string>(tag, def));
+ return Anope::DoTime(Get<Anope::string>(tag, def));
}
template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- const Anope::string &str = Get<const Anope::string>(tag, def);
+ const Anope::string &str = Get<Anope::string>(tag, def);
return !str.empty() && !str.equals_ci("no") && !str.equals_ci("off") && !str.equals_ci("false") && !str.equals_ci("0");
}
+template<> unsigned int Block::Get(const Anope::string &tag, const Anope::string &def) const
+{
+ const Anope::string &str = Get<Anope::string>(tag, def);
+ std::size_t pos = str.length();
+ unsigned long l;
+
+ try
+ {
+ l = std::stoul(str.str(), &pos, 0);
+ }
+ catch (...)
+ {
+ return 0;
+ }
+
+ if (pos != str.length())
+ return 0;
+
+ return l;
+}
+
+template<> void Block::Set(const Anope::string &tag, const Anope::string &value)
+{
+ items[tag] = value;
+}
+
static void ValidateNotEmpty(const Anope::string &block, const Anope::string &name, const Anope::string &value)
{
if (value.empty())
@@ -121,14 +149,17 @@ Conf::Conf() : Block("")
{
Block *include = this->GetBlock("include", i);
- const Anope::string &type = include->Get<const Anope::string>("type"),
- &file = include->Get<const Anope::string>("name");
+ const Anope::string &type = include->Get<Anope::string>("type"),
+ &file = include->Get<Anope::string>("name");
+
+ ValidateNotEmpty("include", "name", file);
File f(file, type == "executable");
this->LoadConf(f);
}
- FOREACH_MOD(OnReload, (this));
+ for (Module *m : ModuleManager::Modules)
+ m->OnReload(this);
/* Check for modified values that aren't allowed to be modified */
if (Config)
@@ -147,20 +178,21 @@ Conf::Conf() : Block("")
{"networkinfo", "userlen"},
{"networkinfo", "hostlen"},
{"networkinfo", "chanlen"},
+ {"options", "casemap"},
};
for (unsigned i = 0; i < sizeof(noreload) / sizeof(noreload[0]); ++i)
- if (this->GetBlock(noreload[i].block)->Get<const Anope::string>(noreload[i].name) != Config->GetBlock(noreload[i].block)->Get<const Anope::string>(noreload[i].name))
+ if (this->GetBlock(noreload[i].block)->Get<Anope::string>(noreload[i].name) != Config->GetBlock(noreload[i].block)->Get<Anope::string>(noreload[i].name))
throw ConfigException("<" + noreload[i].block + ":" + noreload[i].name + "> can not be modified once set");
}
Block *serverinfo = this->GetBlock("serverinfo"), *options = this->GetBlock("options"),
*mail = this->GetBlock("mail"), *networkinfo = this->GetBlock("networkinfo");
- ValidateNotEmpty("serverinfo", "name", serverinfo->Get<const Anope::string>("name"));
- ValidateNotEmpty("serverinfo", "description", serverinfo->Get<const Anope::string>("description"));
- ValidateNotEmpty("serverinfo", "pid", serverinfo->Get<const Anope::string>("pid"));
- ValidateNotEmpty("serverinfo", "motd", serverinfo->Get<const Anope::string>("motd"));
+ ValidateNotEmpty("serverinfo", "name", serverinfo->Get<Anope::string>("name"));
+ ValidateNotEmpty("serverinfo", "description", serverinfo->Get<Anope::string>("description"));
+ ValidateNotEmpty("serverinfo", "pid", serverinfo->Get<Anope::string>("pid"));
+ ValidateNotEmpty("serverinfo", "motd", serverinfo->Get<Anope::string>("motd"));
ValidateNotZero("options", "readtimeout", options->Get<time_t>("readtimeout"));
ValidateNotZero("options", "warningtimeout", options->Get<time_t>("warningtimeout"));
@@ -170,13 +202,13 @@ Conf::Conf() : Block("")
ValidateNotZero("networkinfo", "hostlen", networkinfo->Get<unsigned>("hostlen"));
ValidateNotZero("networkinfo", "chanlen", networkinfo->Get<unsigned>("chanlen"));
- spacesepstream(options->Get<const Anope::string>("ulineservers")).GetTokens(this->Ulines);
+ spacesepstream(options->Get<Anope::string>("ulineservers")).GetTokens(this->Ulines);
if (mail->Get<bool>("usemail"))
{
Anope::string check[] = { "sendmailpath", "sendfrom", "registration_subject", "registration_message", "emailchange_subject", "emailchange_message", "memo_subject", "memo_message" };
for (unsigned i = 0; i < sizeof(check) / sizeof(Anope::string); ++i)
- ValidateNotEmpty("mail", check[i], mail->Get<const Anope::string>(check[i]));
+ ValidateNotEmpty("mail", check[i], mail->Get<Anope::string>(check[i]));
}
this->ReadTimeout = options->Get<time_t>("readtimeout");
@@ -185,21 +217,42 @@ Conf::Conf() : Block("")
this->StrictPrivmsg = !UseStrictPrivmsg ? "/msg " : "/";
{
std::vector<Anope::string> defaults;
- spacesepstream(this->GetModule("nickserv")->Get<const Anope::string>("defaults")).GetTokens(defaults);
+ spacesepstream(this->GetModule("nickserv")->Get<Anope::string>("defaults")).GetTokens(defaults);
this->DefPrivmsg = std::find(defaults.begin(), defaults.end(), "msg") != defaults.end();
}
- this->DefLanguage = options->Get<const Anope::string>("defaultlanguage");
+ this->DefLanguage = options->Get<Anope::string>("defaultlanguage");
this->TimeoutCheck = options->Get<time_t>("timeoutcheck");
this->NickChars = networkinfo->Get<Anope::string>("nick_chars");
+ Anope::string locale = options->Get<Anope::string>("locale");
+ Anope::string casemap = options->Get<Anope::string>("casemap");
+
+ if (locale.empty() == casemap.empty())
+ throw ConfigException("One of options:locale and options:casemap must be set");
+
+ if (locale.empty())
+ {
+ // load locale conf
+ File f(casemap + ".conf", false);
+ this->LoadConf(f);
+ }
+ else
+ {
+#if Boost_FOUND
+ this->locale = new std::locale(Anope::locale::generate(locale.str()));
+#else
+ throw ConfigException("Boost.Locale is not enabled, cannot use locale " + locale);
+#endif
+ }
+
for (int i = 0; i < this->CountBlock("uplink"); ++i)
{
Block *uplink = this->GetBlock("uplink", i);
- const Anope::string &host = uplink->Get<const Anope::string>("host");
+ const Anope::string &host = uplink->Get<Anope::string>("host");
bool ipv6 = uplink->Get<bool>("ipv6");
int port = uplink->Get<int>("port");
- const Anope::string &password = uplink->Get<const Anope::string>("password");
+ const Anope::string &password = uplink->Get<Anope::string>("password");
ValidateNotEmpty("uplink", "host", host);
ValidateNotZero("uplink", "port", port);
@@ -212,7 +265,7 @@ Conf::Conf() : Block("")
{
Block *module = this->GetBlock("module", i);
- const Anope::string &modname = module->Get<const Anope::string>("name");
+ const Anope::string &modname = module->Get<Anope::string>("name");
ValidateNotEmpty("module", "name", modname);
@@ -223,11 +276,11 @@ Conf::Conf() : Block("")
{
Block *opertype = this->GetBlock("opertype", i);
- const Anope::string &oname = opertype->Get<const Anope::string>("name"),
- &modes = opertype->Get<const Anope::string>("modes"),
- &inherits = opertype->Get<const Anope::string>("inherits"),
- &commands = opertype->Get<const Anope::string>("commands"),
- &privs = opertype->Get<const Anope::string>("privs");
+ const Anope::string &oname = opertype->Get<Anope::string>("name"),
+ &modes = opertype->Get<Anope::string>("modes"),
+ &inherits = opertype->Get<Anope::string>("inherits"),
+ &commands = opertype->Get<Anope::string>("commands"),
+ &privs = opertype->Get<Anope::string>("privs");
ValidateNotEmpty("opertype", "name", oname);
@@ -268,17 +321,17 @@ Conf::Conf() : Block("")
{
Block *oper = this->GetBlock("oper", i);
- const Anope::string &nname = oper->Get<const Anope::string>("name"),
- &type = oper->Get<const Anope::string>("type"),
- &password = oper->Get<const Anope::string>("password"),
- &certfp = oper->Get<const Anope::string>("certfp"),
- &host = oper->Get<const Anope::string>("host"),
- &vhost = oper->Get<const Anope::string>("vhost");
+ const Anope::string &nname = oper->Get<Anope::string>("name"),
+ &type = oper->Get<Anope::string>("type"),
+ &password = oper->Get<Anope::string>("password"),
+ &certfp = oper->Get<Anope::string>("certfp"),
+ &host = oper->Get<Anope::string>("host"),
+ &vhost = oper->Get<Anope::string>("vhost");
bool require_oper = oper->Get<bool>("require_oper");
ValidateNotEmpty("oper", "name", nname);
ValidateNotEmpty("oper", "type", type);
-
+
OperType *ot = NULL;
for (unsigned j = 0; j < this->MyOperTypes.size(); ++j)
if (this->MyOperTypes[j]->GetName() == type)
@@ -286,28 +339,29 @@ Conf::Conf() : Block("")
if (ot == NULL)
throw ConfigException("Oper block for " + nname + " has invalid oper type " + type);
- Oper *o = new Oper(nname, ot);
- o->require_oper = require_oper;
- o->password = password;
- o->certfp = certfp;
- spacesepstream(host).GetTokens(o->hosts);
- o->vhost = vhost;
-
- this->Opers.push_back(o);
+ Oper *o = Serialize::New<Oper *>();
+ o->conf = this;
+ o->SetName(nname);
+ o->SetType(ot);
+ o->SetRequireOper(require_oper);
+ o->SetPassword(password);
+ o->SetCertFP(certfp);
+ o->SetHost(host);
+ o->SetVhost(vhost);
}
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->conf = false;
+ for (BotInfo *bi : Serialize::GetObjects<BotInfo *>())
+ bi->conf = nullptr;
for (int i = 0; i < this->CountBlock("service"); ++i)
{
Block *service = this->GetBlock("service", i);
- const Anope::string &nick = service->Get<const Anope::string>("nick"),
- &user = service->Get<const Anope::string>("user"),
- &host = service->Get<const Anope::string>("host"),
- &gecos = service->Get<const Anope::string>("gecos"),
- &modes = service->Get<const Anope::string>("modes"),
- &channels = service->Get<const Anope::string>("channels");
+ const Anope::string &nick = service->Get<Anope::string>("nick"),
+ &user = service->Get<Anope::string>("user"),
+ &host = service->Get<Anope::string>("host"),
+ &gecos = service->Get<Anope::string>("gecos"),
+ &modes = service->Get<Anope::string>("modes"),
+ &channels = service->Get<Anope::string>("channels");
ValidateNotEmpty("service", "nick", nick);
ValidateNotEmpty("service", "user", user);
@@ -315,73 +369,19 @@ Conf::Conf() : Block("")
ValidateNotEmpty("service", "gecos", gecos);
ValidateNoSpaces("service", "channels", channels);
- BotInfo *bi = BotInfo::Find(nick, true);
- if (!bi)
- bi = new BotInfo(nick, user, host, gecos, modes);
- bi->conf = true;
-
- std::vector<Anope::string> oldchannels = bi->botchannels;
- bi->botchannels.clear();
- commasepstream sep(channels);
- for (Anope::string token; sep.GetToken(token);)
+ if (User *u = User::Find(nick, true))
{
- bi->botchannels.push_back(token);
- size_t ch = token.find('#');
- Anope::string chname, want_modes;
- if (ch == Anope::string::npos)
- chname = token;
- else
- {
- want_modes = token.substr(0, ch);
- chname = token.substr(ch);
- }
- bi->Join(chname);
- Channel *c = Channel::Find(chname);
- if (!c)
- continue; // Can't happen
-
- c->botchannel = true;
-
- /* Remove all existing modes */
- ChanUserContainer *cu = c->FindUser(bi);
- if (cu != NULL)
- for (size_t j = 0; j < cu->status.Modes().length(); ++j)
- c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->GetUID());
- /* Set the new modes */
- for (unsigned j = 0; j < want_modes.length(); ++j)
+ if (u->type != UserType::BOT)
{
- ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
- if (cm == NULL)
- cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
- if (cm && cm->type == MODE_STATUS)
- c->SetMode(bi, cm, bi->GetUID());
+ u->Kill(Me, "Nickname required by services");
}
}
- for (unsigned k = 0; k < oldchannels.size(); ++k)
- {
- size_t ch = oldchannels[k].find('#');
- Anope::string chname = oldchannels[k].substr(ch != Anope::string::npos ? ch : 0);
- bool found = false;
- for (unsigned j = 0; j < bi->botchannels.size(); ++j)
- {
- ch = bi->botchannels[j].find('#');
- Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0);
-
- if (chname.equals_ci(ochname))
- found = true;
- }
+ ServiceBot *sb = ServiceBot::Find(nick, true);
+ if (!sb)
+ sb = new ServiceBot(nick, user, host, gecos, modes);
- if (found)
- continue;
-
- Channel *c = Channel::Find(chname);
- if (c)
- {
- c->botchannel = false;
- bi->Part(c);
- }
- }
+ sb->bi->conf = service;
}
for (int i = 0; i < this->CountBlock("log"); ++i)
@@ -394,38 +394,45 @@ Conf::Conf() : Block("")
LogInfo l(logage, rawio, debug);
- l.bot = BotInfo::Find(log->Get<const Anope::string>("bot", "Global"), true);
- spacesepstream(log->Get<const Anope::string>("target")).GetTokens(l.targets);
- spacesepstream(log->Get<const Anope::string>("source")).GetTokens(l.sources);
- spacesepstream(log->Get<const Anope::string>("admin")).GetTokens(l.admin);
- spacesepstream(log->Get<const Anope::string>("override")).GetTokens(l.override);
- spacesepstream(log->Get<const Anope::string>("commands")).GetTokens(l.commands);
- spacesepstream(log->Get<const Anope::string>("servers")).GetTokens(l.servers);
- spacesepstream(log->Get<const Anope::string>("channels")).GetTokens(l.channels);
- spacesepstream(log->Get<const Anope::string>("users")).GetTokens(l.users);
- spacesepstream(log->Get<const Anope::string>("other")).GetTokens(l.normal);
+ l.bot = ServiceBot::Find(log->Get<Anope::string>("bot", "Global"), true);
+ spacesepstream(log->Get<Anope::string>("target")).GetTokens(l.targets);
+ spacesepstream(log->Get<Anope::string>("source")).GetTokens(l.sources);
+ spacesepstream(log->Get<Anope::string>("admin")).GetTokens(l.admin);
+ spacesepstream(log->Get<Anope::string>("override")).GetTokens(l.override);
+ spacesepstream(log->Get<Anope::string>("commands")).GetTokens(l.commands);
+ spacesepstream(log->Get<Anope::string>("servers")).GetTokens(l.servers);
+ spacesepstream(log->Get<Anope::string>("channels")).GetTokens(l.channels);
+ spacesepstream(log->Get<Anope::string>("users")).GetTokens(l.users);
+ spacesepstream(log->Get<Anope::string>("other")).GetTokens(l.normal);
this->LogInfos.push_back(l);
}
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->commands.clear();
+ for (std::pair<Anope::string, User *> p : UserListByNick)
+ {
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->commands.clear();
+ }
for (int i = 0; i < this->CountBlock("command"); ++i)
{
Block *command = this->GetBlock("command", i);
- const Anope::string &service = command->Get<const Anope::string>("service"),
- &nname = command->Get<const Anope::string>("name"),
- &cmd = command->Get<const Anope::string>("command"),
- &permission = command->Get<const Anope::string>("permission"),
- &group = command->Get<const Anope::string>("group");
+ const Anope::string &service = command->Get<Anope::string>("service"),
+ &nname = command->Get<Anope::string>("name"),
+ &cmd = command->Get<Anope::string>("command"),
+ &permission = command->Get<Anope::string>("permission"),
+ &group = command->Get<Anope::string>("group");
bool hide = command->Get<bool>("hide");
ValidateNotEmpty("command", "service", service);
ValidateNotEmpty("command", "name", nname);
ValidateNotEmpty("command", "command", cmd);
- BotInfo *bi = this->GetClient(service);
+ ServiceBot *bi = this->GetClient(service);
if (!bi)
continue;
@@ -434,26 +441,14 @@ Conf::Conf() : Block("")
ci.hide = hide;
}
- PrivilegeManager::ClearPrivileges();
- for (int i = 0; i < this->CountBlock("privilege"); ++i)
- {
- Block *privilege = this->GetBlock("privilege", i);
-
- const Anope::string &nname = privilege->Get<const Anope::string>("name"),
- &desc = privilege->Get<const Anope::string>("desc");
- int rank = privilege->Get<int>("rank");
-
- PrivilegeManager::AddPrivilege(Privilege(nname, desc, rank));
- }
-
for (int i = 0; i < this->CountBlock("fantasy"); ++i)
{
Block *fantasy = this->GetBlock("fantasy", i);
- const Anope::string &nname = fantasy->Get<const Anope::string>("name"),
- &service = fantasy->Get<const Anope::string>("command"),
- &permission = fantasy->Get<const Anope::string>("permission"),
- &group = fantasy->Get<const Anope::string>("group");
+ const Anope::string &nname = fantasy->Get<Anope::string>("name"),
+ &service = fantasy->Get<Anope::string>("command"),
+ &permission = fantasy->Get<Anope::string>("permission"),
+ &group = fantasy->Get<Anope::string>("group");
bool hide = fantasy->Get<bool>("hide"),
prepend_channel = fantasy->Get<bool>("prepend_channel", "yes");
@@ -462,6 +457,7 @@ Conf::Conf() : Block("")
CommandInfo &c = this->Fantasy[nname];
c.name = service;
+ c.cname = nname;
c.permission = permission;
c.group = group;
c.hide = hide;
@@ -472,8 +468,8 @@ Conf::Conf() : Block("")
{
Block *command_group = this->GetBlock("command_group", i);
- const Anope::string &nname = command_group->Get<const Anope::string>("name"),
- &description = command_group->Get<const Anope::string>("description");
+ const Anope::string &nname = command_group->Get<Anope::string>("name"),
+ &description = command_group->Get<Anope::string>("description");
CommandGroup gr;
gr.name = nname;
@@ -482,64 +478,151 @@ Conf::Conf() : Block("")
this->CommandGroups.push_back(gr);
}
- /* Below here can't throw */
-
- if (Config)
- /* Clear existing conf opers */
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- NickCore *nc = it->second;
- if (nc->o && std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end())
- nc->o = NULL;
- }
- /* Apply new opers */
- for (unsigned i = 0; i < this->Opers.size(); ++i)
+ for (int i = 0; i < this->CountBlock("usermode"); ++i)
{
- Oper *o = this->Opers[i];
+ Block *usermode = this->GetBlock("usermode", i);
- NickAlias *na = NickAlias::Find(o->name);
- if (!na)
- continue;
+ Anope::string nname = usermode->Get<Anope::string>("name"),
+ character = usermode->Get<Anope::string>("character");
+ bool oper_only = usermode->Get<bool>("oper_only"),
+ setable = usermode->Get<bool>("setable"),
+ param = usermode->Get<bool>("param");
- if (!na->nc || na->nc->o)
- {
- // If the account is already an oper it might mean two oper blocks for the same nick, or
- // something else has configured them as an oper (like a module)
- continue;
- }
+ ValidateNotEmpty("usermode", "name", nname);
+
+ if (character.length() != 1)
+ throw ConfigException("Usermode character length must be 1");
+
+ Usermode um;
+ um.name = nname;
+ um.character = character[0];
+ um.param = param;
+ um.oper_only = oper_only;
+ um.setable = setable;
- na->nc->o = o;
- Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ this->Usermodes.push_back(um);
}
- if (options->Get<const Anope::string>("casemap", "ascii") == "ascii")
- Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
- else if (options->Get<const Anope::string>("casemap") == "rfc1459")
- Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype<char>());
- else
+ for (int i = 0; i < this->CountBlock("channelmode"); ++i)
{
- try
+ Block *channelmode = this->GetBlock("channelmode", i);
+
+ Anope::string nname = channelmode->Get<Anope::string>("name"),
+ character = channelmode->Get<Anope::string>("character"),
+ status = channelmode->Get<Anope::string>("status"),
+ param_regex = channelmode->Get<Anope::string>("param_regex");
+ bool oper_only = channelmode->Get<bool>("oper_only"),
+ setable = channelmode->Get<bool>("setable"),
+ list = channelmode->Get<bool>("list"),
+ param = channelmode->Get<bool>("param"),
+ param_unset = channelmode->Get<bool>("param_unset", "yes");
+ int level = channelmode->Get<int>("level");
+
+ ValidateNotEmpty("usermode", "name", nname);
+
+ if (character.length() != 1)
+ throw ConfigException("Channelmode character length must be 1");
+
+ if (status.length() > 1)
+ throw ConfigException("Channelmode status must be at most one character");
+
+ if (list || !param_regex.empty() || !status.empty())
+ param = true;
+
+ Channelmode cm;
+ cm.name = nname;
+ cm.character = character[0];
+ cm.status = !status.empty() ? status[0] : 0;
+ cm.param_regex = param_regex;
+ cm.oper_only = oper_only;
+ cm.setable = setable;
+ cm.list = list;
+ cm.param = param;
+ cm.param_unset = param_unset;
+ cm.level = level;
+
+ this->Channelmodes.push_back(cm);
+ }
+
+ for (int i = 0; i < this->CountBlock("casemap"); ++i)
+ {
+ Block *casemap = this->GetBlock("casemap", i);
+
+ unsigned char upper = casemap->Get<unsigned int>("upper"),
+ lower = casemap->Get<unsigned int>("lower");
+
+ if (!upper)
{
- Anope::casemap = std::locale(options->Get<const Anope::string>("casemap").c_str());
+ Anope::string s = casemap->Get<Anope::string>("upper");
+ if (s.length() == 1)
+ upper = s[0];
}
- catch (const std::runtime_error &)
+
+ if (!lower)
+ {
+ Anope::string s = casemap->Get<Anope::string>("lower");
+ if (s.length() == 1)
+ lower = s[0];
+ }
+
+ if (upper && lower)
{
- Log() << "Unknown casemap " << options->Get<const Anope::string>("casemap") << " - casemap not changed";
+ CaseMapUpper[lower] = CaseMapUpper[upper] = upper;
+ CaseMapLower[lower] = CaseMapLower[upper] = lower;
}
}
- Anope::CaseMapRebuild();
+
+ /* Below here can't throw */
+
+ /* Clear existing conf opers */
+ if (Config)
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ if (o->conf == Config)
+ o->Delete();
+ /* Apply new opers */
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ {
+ NickServ::Nick *na = NickServ::FindNick(o->GetName());
+ if (!na)
+ continue;
+
+ na->GetAccount()->o = o;
+ Log() << "Tied oper " << na->GetAccount()->GetDisplay() << " to type " << o->GetType()->GetName();
+ }
/* Check the user keys */
if (!options->Get<unsigned>("seed"))
Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
+
+ /* check regexengine */
+ const Anope::string &regex_engine = options->Get<Anope::string>("regexengine");
+ if (regex_engine == "ecmascript")
+ regex_flags = std::regex::ECMAScript;
+ else if (regex_engine == "basic")
+ regex_flags = std::regex::basic;
+ else if (regex_engine == "extended")
+ regex_flags = std::regex::extended;
+ else if (regex_engine == "awk")
+ regex_flags = std::regex::awk;
+ else if (regex_engine == "grep")
+ regex_flags = std::regex::grep;
+ else if (regex_engine == "egrep")
+ regex_flags = std::regex::egrep;
+ else
+ regex_flags = static_cast<std::basic_regex<char>::flag_type>(0);
+ /* always enable icase and optimize */
+ if (regex_flags)
+ regex_flags |= std::regex::icase | std::regex::optimize;
+
+ this->LineWrap = options->Get<unsigned>("linewrap", "200");
}
Conf::~Conf()
{
for (unsigned i = 0; i < MyOperTypes.size(); ++i)
delete MyOperTypes[i];
- for (unsigned i = 0; i < Opers.size(); ++i)
- delete Opers[i];
+
+ delete locale;
}
void Conf::Post(Conf *old)
@@ -552,33 +635,65 @@ void Conf::Post(Conf *old)
if (std::find(old->ModulesAutoLoad.begin(), old->ModulesAutoLoad.end(), this->ModulesAutoLoad[i]) == old->ModulesAutoLoad.end())
ModuleManager::LoadModule(this->ModulesAutoLoad[i], NULL);
+ ModeManager::Apply(old);
+
/* Apply opertype changes, as non-conf opers still point to the old oper types */
- for (unsigned i = Oper::opers.size(); i > 0; --i)
+ for (Oper *o : Serialize::GetObjects<Oper *>())
{
- Oper *o = Oper::opers[i - 1];
-
/* Oper's type is in the old config, so update it */
- if (std::find(old->MyOperTypes.begin(), old->MyOperTypes.end(), o->ot) != old->MyOperTypes.end())
+ if (std::find(old->MyOperTypes.begin(), old->MyOperTypes.end(), o->GetType()) != old->MyOperTypes.end())
{
- OperType *ot = o->ot;
- o->ot = NULL;
+ OperType *ot = o->GetType();
+ o->SetType(nullptr);
for (unsigned j = 0; j < MyOperTypes.size(); ++j)
if (ot->GetName() == MyOperTypes[j]->GetName())
- o->ot = MyOperTypes[j];
+ o->SetType(MyOperTypes[j]);
- if (o->ot == NULL)
+ if (o->GetType() == NULL)
{
/* Oper block has lost type */
- std::vector<Oper *>::iterator it = std::find(old->Opers.begin(), old->Opers.end(), o);
- if (it != old->Opers.end())
- old->Opers.erase(it);
+ o->Delete();
+ }
+ }
+ }
+
+ for (BotInfo *bi : Serialize::GetObjects<BotInfo *>())
+ {
+ if (!bi->conf)
+ {
+ bi->Delete();
+ continue;
+ }
+
+ for (int i = 0; i < bi->conf->CountBlock("channel"); ++i)
+ {
+ Block *channel = bi->conf->GetBlock("channel", i);
+
+ const Anope::string &chname = channel->Get<Anope::string>("name"),
+ &modes = channel->Get<Anope::string>("modes");
+
+ bi->bot->Join(chname);
- it = std::find(this->Opers.begin(), this->Opers.end(), o);
- if (it != this->Opers.end())
- this->Opers.erase(it);
+ Channel *c = Channel::Find(chname);
+ if (!c)
+ continue; // Can't happen
+
+ c->botchannel = true;
- delete o;
+ /* Remove all existing modes */
+ ChanUserContainer *cu = c->FindUser(bi->bot);
+ if (cu != NULL)
+ for (size_t j = 0; j < cu->status.Modes().length(); ++j)
+ c->RemoveMode(bi->bot, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->bot->GetUID());
+ /* Set the new modes */
+ for (unsigned j = 0; j < modes.length(); ++j)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[j]);
+ if (cm == NULL)
+ cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(modes[j]));
+ if (cm && cm->type == MODE_STATUS)
+ c->SetMode(bi->bot, cm, bi->bot->GetUID());
}
}
}
@@ -588,7 +703,7 @@ Block *Conf::GetModule(Module *m)
{
if (!m)
return NULL;
-
+
return GetModule(m->name);
}
@@ -599,30 +714,37 @@ Block *Conf::GetModule(const Anope::string &mname)
return it->second;
Block* &block = modules[mname];
-
+
/* Search for the block */
for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range("module"); iters.first != iters.second; ++iters.first)
{
Block *b = &iters.first->second;
- if (b->Get<const Anope::string>("name") == mname)
+ if (b->Get<Anope::string>("name") == mname)
{
block = b;
break;
}
}
- return GetModule(mname);
+ if (block == nullptr)
+ {
+ /* not found, create new block */
+ auto it2 = blocks.emplace(mname, mname);
+ block = &it2->second;
+ }
+
+ return block;
}
-BotInfo *Conf::GetClient(const Anope::string &cname)
+ServiceBot *Conf::GetClient(const Anope::string &cname)
{
Anope::map<Anope::string>::iterator it = bots.find(cname);
if (it != bots.end())
- return BotInfo::Find(!it->second.empty() ? it->second : cname, true);
+ return ServiceBot::Find(!it->second.empty() ? it->second : cname, true);
Block *block = GetModule(cname.lower());
- const Anope::string &client = block->Get<const Anope::string>("client");
+ const Anope::string &client = block->Get<Anope::string>("client");
bots[cname] = client;
return GetClient(cname);
}
@@ -720,10 +842,10 @@ void Conf::LoadConf(File &file)
Log(LOG_DEBUG) << "Start to read conf " << file.GetName();
// Start reading characters...
while (!file.End())
- {
+ {
Anope::string line = file.Read();
++linenumber;
-
+
/* If this line is completely empty and we are in a quote, just append a newline */
if (line.empty() && in_quote)
wordbuffer += "\n";
@@ -884,10 +1006,10 @@ void Conf::LoadConf(File &file)
{
Block *define = this->GetBlock("define", i);
- const Anope::string &dname = define->Get<const Anope::string>("name");
+ const Anope::string &dname = define->Get<Anope::string>("name");
if (dname == wordbuffer && define != b)
- wordbuffer = define->Get<const Anope::string>("value");
+ wordbuffer = define->Get<Anope::string>("value");
}
if (b)
diff --git a/src/event.cpp b/src/event.cpp
new file mode 100644
index 000000000..8f59f9960
--- /dev/null
+++ b/src/event.cpp
@@ -0,0 +1,35 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2014-2016 Adam <adam@anope.org>
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "services.h"
+#include "event.h"
+
+EventManager *EventManager::eventManager = nullptr;
+
+void EventManager::Init()
+{
+ eventManager = new EventManager();
+}
+
+EventManager *EventManager::Get()
+{
+ return eventManager;
+}
+
diff --git a/src/extensible.cpp b/src/extensible.cpp
index 4079290ff..dc468fae7 100644
--- a/src/extensible.cpp
+++ b/src/extensible.cpp
@@ -1,37 +1,39 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2013-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "extensible.h"
-static std::set<ExtensibleBase *> extensible_items;
-
-ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &n) : Service(m, "Extensible", n)
+ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &n) : ExtensibleBase(m, "Extensible", n)
{
- extensible_items.insert(this);
}
-ExtensibleBase::~ExtensibleBase()
+ExtensibleBase::ExtensibleBase(Module *m, const Anope::string &t, const Anope::string &n) : Service(m, t, n)
{
- extensible_items.erase(this);
}
Extensible::~Extensible()
{
- UnsetExtensibles();
-}
-
-void Extensible::UnsetExtensibles()
-{
while (!extension_items.empty())
(*extension_items.begin())->Unset(this);
}
-bool Extensible::HasExt(const Anope::string &name) const
+bool Extensible::HasExtOK(const Anope::string &name)
{
ExtensibleRef<void *> ref(name);
if (ref)
@@ -41,32 +43,3 @@ bool Extensible::HasExt(const Anope::string &name) const
return false;
}
-void Extensible::ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data)
-{
- for (std::set<ExtensibleBase *>::iterator it = e->extension_items.begin(); it != e->extension_items.end(); ++it)
- {
- ExtensibleBase *eb = *it;
- eb->ExtensibleSerialize(e, s, data);
- }
-}
-
-void Extensible::ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data)
-{
- for (std::set<ExtensibleBase *>::iterator it = extensible_items.begin(); it != extensible_items.end(); ++it)
- {
- ExtensibleBase *eb = *it;
- eb->ExtensibleUnserialize(e, s, data);
- }
-}
-
-template<>
-bool* Extensible::Extend(const Anope::string &name, const bool &what)
-{
- ExtensibleRef<bool> ref(name);
- if (ref)
- return ref->Set(this);
-
- Log(LOG_DEBUG) << "Extend for non-existent type " << name << " on " << static_cast<void *>(this);
- return NULL;
-}
-
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 6374639d8..265cb362b 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -1,40 +1,46 @@
/*
+ * Anope IRC Services
*
- * (C) 2002-2011 InspIRCd Development Team
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2002-2011 InspIRCd Development Team
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "hashcomp.h"
#include "anope.h"
+#include "config.h"
-/* Case map in use by Anope */
-std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
-/* Cache of the above case map, forced upper */
-static unsigned char case_map_upper[256], case_map_lower[256];
-
-/* called whenever Anope::casemap is modified to rebuild the casemap cache */
-void Anope::CaseMapRebuild()
-{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
-
- for (unsigned i = 0; i < sizeof(case_map_upper); ++i)
- {
- case_map_upper[i] = ct.toupper(i);
- case_map_lower[i] = ct.tolower(i);
- }
-}
+#ifdef Boost_FOUND
+#include <boost/locale.hpp>
+#endif
unsigned char Anope::tolower(unsigned char c)
{
- return case_map_lower[c];
+ if (!Config || !Config->CaseMapLower[c])
+ return std::tolower(c);
+
+ return Config->CaseMapLower[c];
}
unsigned char Anope::toupper(unsigned char c)
{
- return case_map_upper[c];
+ if (!Config || !Config->CaseMapUpper[c])
+ return std::toupper(c);
+
+ return Config->CaseMapUpper[c];
}
/*
@@ -43,10 +49,10 @@ unsigned char Anope::toupper(unsigned char c)
* which is a case-insensitive equivalent to std::string.
*
*/
-
+
bool ci::ci_char_traits::eq(char c1st, char c2nd)
{
- return case_map_upper[static_cast<unsigned char>(c1st)] == case_map_upper[static_cast<unsigned char>(c2nd)];
+ return Anope::toupper(c1st) == Anope::toupper(c2nd);
}
bool ci::ci_char_traits::ne(char c1st, char c2nd)
@@ -56,15 +62,15 @@ bool ci::ci_char_traits::ne(char c1st, char c2nd)
bool ci::ci_char_traits::lt(char c1st, char c2nd)
{
- return case_map_upper[static_cast<unsigned char>(c1st)] < case_map_upper[static_cast<unsigned char>(c2nd)];
+ return Anope::toupper(c1st) < Anope::toupper(c2nd);
}
int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
{
for (unsigned i = 0; i < n; ++i)
{
- register unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)],
- c2 = case_map_upper[static_cast<unsigned char>(*str2)];
+ unsigned char c1 = Anope::toupper(*str1),
+ c2 = Anope::toupper(*str2);
if (c1 > c2)
return 1;
@@ -81,7 +87,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
const char *ci::ci_char_traits::find(const char *s1, int n, char c)
{
- while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != case_map_upper[static_cast<unsigned char>(c)])
+ while (n-- > 0 && Anope::toupper(*s1) != Anope::toupper(c))
++s1;
return n >= 0 ? s1 : NULL;
}
@@ -162,3 +168,77 @@ bool sepstream::StreamEnd()
return this->pos > this->tokens.length();
}
+size_t Anope::hash::operator()(const Anope::string &s) const
+{
+ return std::hash<std::string>()(s.str());
+}
+
+bool Anope::compare::operator()(const Anope::string &s1, const Anope::string &s2) const
+{
+ return s1.equals_cs(s2);
+}
+
+size_t Anope::hash_ci::operator()(const Anope::string &s) const
+{
+ return std::hash<std::string>()(s.lower().str());
+}
+
+bool Anope::compare_ci::operator()(const Anope::string &s1, const Anope::string &s2) const
+{
+ return s1.equals_ci(s2);
+}
+
+size_t Anope::hash_locale::operator()(const Anope::string &s) const
+{
+#ifdef Boost_FOUND
+ if (Config != nullptr && Config->locale != nullptr)
+ {
+ return Anope::locale::hash(s.str());
+ }
+#endif
+
+ return Anope::hash_ci()(s);
+}
+
+bool Anope::compare_locale::operator()(const Anope::string &s1, const Anope::string &s2) const
+{
+#ifdef Boost_FOUND
+ if (Config != nullptr && Config->locale != nullptr)
+ {
+ return Anope::locale::compare(s1.str(), s2.str()) == 0;
+ }
+#endif
+
+ return Anope::compare_ci()(s1, s2);
+}
+
+#ifdef Boost_FOUND
+
+std::locale Anope::locale::generate(const std::string &name)
+{
+ boost::locale::generator gen;
+ return gen.generate(name);
+}
+
+int Anope::locale::compare(const std::string &s1, const std::string &s2)
+{
+ std::string c1 = boost::locale::conv::between(s1.data(), s1.data() + s1.length(),
+ Config->locale->name(),
+ "");
+
+ std::string c2 = boost::locale::conv::between(s2.data(), s2.data() + s2.length(),
+ Config->locale->name(),
+ "");
+
+ const boost::locale::collator<char> &ct = std::use_facet<boost::locale::collator<char>>(*Config->locale);
+ return ct.compare(boost::locale::collator_base::secondary, c1, c2);
+}
+
+long Anope::locale::hash(const std::string &s)
+{
+ const boost::locale::collator<char> &ct = std::use_facet<boost::locale::collator<char>>(*Config->locale);
+ return ct.hash(boost::locale::collator_base::secondary, s.data(), s.data() + s.length());
+}
+
+#endif
+
diff --git a/src/init.cpp b/src/init.cpp
index 7e5722603..ec23a7b4b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,12 +1,20 @@
-/* Initialization and related routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -18,6 +26,8 @@
#include "socketengine.h"
#include "servers.h"
#include "language.h"
+#include "event.h"
+#include "modules.h"
#ifndef _WIN32
#include <sys/wait.h>
@@ -105,7 +115,7 @@ void Anope::Fork()
{
#ifndef _WIN32
kill(getppid(), SIGUSR2);
-
+
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
@@ -207,14 +217,14 @@ static void InitSignals()
static void remove_pidfile()
{
- remove(Config->GetBlock("serverinfo")->Get<const Anope::string>("pid").c_str());
+ remove(Config->GetBlock("serverinfo")->Get<Anope::string>("pid").c_str());
}
/* Create our PID file and write the PID to it. */
static void write_pidfile()
{
- FILE *pidfile = fopen(Config->GetBlock("serverinfo")->Get<const Anope::string>("pid").c_str(), "w");
+ FILE *pidfile = fopen(Config->GetBlock("serverinfo")->Get<Anope::string>("pid").c_str(), "w");
if (pidfile)
{
#ifdef _WIN32
@@ -226,7 +236,7 @@ static void write_pidfile()
atexit(remove_pidfile);
}
else
- throw CoreException("Can not write to PID file " + Config->GetBlock("serverinfo")->Get<const Anope::string>("pid"));
+ throw CoreException("Can not write to PID file " + Config->GetBlock("serverinfo")->Get<Anope::string>("pid"));
}
static void setuidgid()
@@ -236,21 +246,21 @@ static void setuidgid()
uid_t uid = -1;
gid_t gid = -1;
- if (!options->Get<const Anope::string>("user").empty())
+ if (!options->Get<Anope::string>("user").empty())
{
errno = 0;
- struct passwd *u = getpwnam(options->Get<const Anope::string>("user").c_str());
+ struct passwd *u = getpwnam(options->Get<Anope::string>("user").c_str());
if (u == NULL)
- Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
+ Log() << "Unable to setuid to " << options->Get<Anope::string>("user") << ": " << Anope::LastError();
else
uid = u->pw_uid;
}
- if (!options->Get<const Anope::string>("group").empty())
+ if (!options->Get<Anope::string>("group").empty())
{
errno = 0;
- struct group *g = getgrnam(options->Get<const Anope::string>("group").c_str());
+ struct group *g = getgrnam(options->Get<Anope::string>("group").c_str());
if (g == NULL)
- Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
+ Log() << "Unable to setgid to " << options->Get<Anope::string>("group") << ": " << Anope::LastError();
else
gid = g->gr_gid;
}
@@ -270,16 +280,16 @@ static void setuidgid()
if (static_cast<int>(gid) != -1)
{
if (setgid(gid) == -1)
- Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
+ Log() << "Unable to setgid to " << options->Get<Anope::string>("group") << ": " << Anope::LastError();
else
- Log() << "Successfully set group to " << options->Get<const Anope::string>("group");
+ Log() << "Successfully set group to " << options->Get<Anope::string>("group");
}
if (static_cast<int>(uid) != -1)
{
if (setuid(uid) == -1)
- Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
+ Log() << "Unable to setuid to " << options->Get<Anope::string>("user") << ": " << Anope::LastError();
else
- Log() << "Successfully set user to " << options->Get<const Anope::string>("user");
+ Log() << "Successfully set user to " << options->Get<Anope::string>("user");
}
#endif
}
@@ -291,8 +301,6 @@ void Anope::Init(int ac, char **av)
umask(DEFUMASK);
#endif
- Serialize::RegisterTypes();
-
/* Parse command line arguments */
ParseCommandLineArguments(ac, av);
@@ -423,7 +431,7 @@ void Anope::Init(int ac, char **av)
{
/* If we are configured to setuid later, don't issue a warning */
Configuration::Block *options = Config->GetBlock("options");
- if (options->Get<const Anope::string>("user").empty())
+ if (options->Get<Anope::string>("user").empty())
{
std::cerr << "WARNING: You are currently running Anope as the root superuser. Anope does not" << std::endl;
std::cerr << " require root privileges to run, and it is discouraged that you run Anope" << std::endl;
@@ -480,6 +488,13 @@ void Anope::Init(int ac, char **av)
/* Initialize the socket engine. Note that some engines can not survive a fork(), so this must be here. */
SocketEngine::Init();
+ ServiceManager::Init();
+ EventManager::Init();
+
+ new BotInfoType();
+ new XLineType(nullptr);
+ new OperBlockType();
+
/* Read configuration file; exit if there are problems. */
try
{
@@ -488,7 +503,7 @@ void Anope::Init(int ac, char **av)
catch (const ConfigException &ex)
{
Log(LOG_TERMINAL) << ex.GetReason();
- Log(LOG_TERMINAL) << "*** Support resources: Read through the services.conf self-contained";
+ Log(LOG_TERMINAL) << "*** Support resources: Read through the anope.conf self-contained";
Log(LOG_TERMINAL) << "*** documentation. Read the documentation files found in the 'docs'";
Log(LOG_TERMINAL) << "*** folder. Visit our portal located at http://www.anope.org/. Join";
Log(LOG_TERMINAL) << "*** our support channel on /server irc.anope.org channel #anope.";
@@ -497,10 +512,15 @@ void Anope::Init(int ac, char **av)
/* Create me */
Configuration::Block *block = Config->GetBlock("serverinfo");
- Me = new Server(NULL, block->Get<const Anope::string>("name"), 0, block->Get<const Anope::string>("description"), block->Get<const Anope::string>("id"));
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ Me = new Server(NULL, block->Get<Anope::string>("name"), 0, block->Get<Anope::string>("description"), block->Get<Anope::string>("id"));
+ for (std::pair<Anope::string, User *> p : UserListByNick)
{
- it->second->server = Me;
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->server = Me;
++Me->users;
}
@@ -516,10 +536,12 @@ void Anope::Init(int ac, char **av)
block = Config->GetBlock("options");
srand(block->Get<unsigned>("seed") ^ time(NULL));
+ ModeManager::Apply(nullptr);
+
/* load modules */
Log() << "Loading modules...";
for (int i = 0; i < Config->CountBlock("module"); ++i)
- ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<const Anope::string>("name"), NULL);
+ ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<Anope::string>("name"), NULL);
#ifndef _WIN32
/* We won't background later, so we should setuid now */
@@ -542,20 +564,24 @@ void Anope::Init(int ac, char **av)
Anope::string sid = IRCD->SID_Retrieve();
if (Me->GetSID() == Me->GetName())
Me->SetSID(sid);
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- it->second->GenerateUID();
+ for (std::pair<Anope::string, User *> p : UserListByNick)
+ {
+ User *u = p.second;
+ if (u->type != UserType::BOT)
+ continue;
+
+ ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ bi->GenerateUID();
+ }
}
/* Load up databases */
Log() << "Loading databases...";
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnLoadDatabase, MOD_RESULT, ());
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::LoadDatabase::OnLoadDatabase);;
static_cast<void>(MOD_RESULT);
Log() << "Databases loaded";
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
it->second->Sync();
-
- Serialize::CheckTypes();
}
diff --git a/src/language.cpp b/src/language.cpp
index 0a19729b1..8c3e6221a 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -14,6 +22,7 @@
#include "commands.h"
#include "config.h"
#include "language.h"
+#include "modules/nickserv.h"
#if GETTEXT_FOUND
# include <libintl.h>
@@ -36,7 +45,7 @@ void Language::InitLanguages()
setlocale(LC_ALL, "");
- spacesepstream sep(Config->GetBlock("options")->Get<const Anope::string>("languages"));
+ spacesepstream sep(Config->GetBlock("options")->Get<Anope::string>("languages"));
Anope::string language;
while (sep.GetToken(language))
{
@@ -60,6 +69,11 @@ const char *Language::Translate(const char *string)
return Translate("", string);
}
+const char *Language::Translate(const Anope::string &string)
+{
+ return Translate("", string.c_str());
+}
+
const char *Language::Translate(User *u, const char *string)
{
if (u && u->Account())
@@ -68,9 +82,19 @@ const char *Language::Translate(User *u, const char *string)
return Translate("", string);
}
-const char *Language::Translate(const NickCore *nc, const char *string)
+const char *Language::Translate(User *u, const Anope::string &string)
+{
+ return Translate(u, string.c_str());
+}
+
+const char *Language::Translate(NickServ::Account *nc, const char *string)
+{
+ return Translate(nc ? nc->GetLanguage().c_str() : "", string);
+}
+
+const char *Language::Translate(NickServ::Account *nc, const Anope::string &string)
{
- return Translate(nc ? nc->language.c_str() : "", string);
+ return Translate(nc, string.c_str());
}
#if GETTEXT_FOUND
diff --git a/src/logger.cpp b/src/logger.cpp
index c681e42fa..0d379e568 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -1,12 +1,20 @@
-/* Logging routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -20,6 +28,9 @@
#include "servers.h"
#include "uplink.h"
#include "protocol.h"
+#include "event.h"
+#include "modules/nickserv.h"
+#include "modules/chanserv.h"
#ifndef _WIN32
#include <sys/time.h>
@@ -74,23 +85,23 @@ const Anope::string &LogFile::GetName() const
return this->filename;
}
-Log::Log(LogType t, const Anope::string &cat, BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(t), category(cat)
+Log::Log(LogType t, const Anope::string &cat, ServiceBot *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(t), category(cat)
{
}
-Log::Log(LogType t, CommandSource &src, Command *_c, ChannelInfo *_ci) : u(src.GetUser()), nc(src.nc), c(_c), source(&src), chan(NULL), ci(_ci), s(NULL), m(NULL), type(t)
+Log::Log(LogType t, CommandSource &src, Command *_c, ChanServ::Channel *_ci) : u(src.GetUser()), nc(src.nc), c(_c), source(&src), chan(NULL), ci(_ci), s(NULL), m(NULL), type(t)
{
if (!c)
throw CoreException("Invalid pointers passed to Log::Log");
-
+
if (type != LOG_COMMAND && type != LOG_OVERRIDE && type != LOG_ADMIN)
throw CoreException("This constructor does not support this log type");
- size_t sl = c->name.find('/');
+ size_t sl = c->GetName().find('/');
this->bi = NULL;
if (sl != Anope::string::npos)
- this->bi = BotInfo::Find(c->name.substr(0, sl), true);
- this->category = c->name;
+ this->bi = ServiceBot::Find(c->GetName().substr(0, sl), true);
+ this->category = c->GetName();
}
Log::Log(User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(NULL), c(NULL), source(NULL), chan(ch), ci(chan ? *chan->ci : NULL), s(NULL), m(NULL), type(LOG_CHANNEL), category(cat)
@@ -99,23 +110,23 @@ Log::Log(User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(
throw CoreException("Invalid pointers passed to Log::Log");
}
-Log::Log(User *_u, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
+Log::Log(User *_u, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
{
if (!u)
throw CoreException("Invalid pointers passed to Log::Log");
}
-Log::Log(Server *serv, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
+Log::Log(Server *serv, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
{
if (!s)
throw CoreException("Invalid pointer passed to Log::Log");
}
-Log::Log(BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
+Log::Log(ServiceBot *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
{
}
-Log::Log(Module *mod, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
+Log::Log(Module *mod, const Anope::string &cat, ServiceBot *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
{
}
@@ -128,8 +139,16 @@ Log::~Log()
else if (this->type == LOG_TERMINAL)
std::cout << this->BuildPrefix() << this->buf.str() << std::endl;
- FOREACH_MOD(OnLog, (this));
-
+ /* Some of the higher debug messages are in the event/service system which manages event dispatch,
+ * so firing off the log event here can cause them to be in weird states
+ */
+ if (this->type <= LOG_NORMAL)
+ {
+ EventManager *em = EventManager::Get();
+ if (em != nullptr)
+ em->Dispatch(&Event::Log::OnLog, this);
+ }
+
if (Config)
for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
if (Config->LogInfos[i].HasType(this->type, this->category))
@@ -140,19 +159,19 @@ Anope::string Log::FormatSource() const
{
if (u)
if (nc)
- return this->u->GetMask() + " (" + this->nc->display + ")";
+ return this->u->GetMask() + " (" + this->nc->GetDisplay() + ")";
else
return this->u->GetMask();
else if (nc)
- return nc->display;
+ return nc->GetDisplay();
return "";
}
Anope::string Log::FormatCommand() const
{
- Anope::string buffer = FormatSource() + " used " + (source != NULL && !source->command.empty() ? source->command : this->c->name) + " ";
+ Anope::string buffer = FormatSource() + " used " + (source != NULL && !source->command.empty() ? source->command : this->c->GetName()) + " ";
if (this->ci)
- buffer += "on " + this->ci->name + " ";
+ buffer += "on " + this->ci->GetName() + " ";
return buffer;
}
@@ -329,9 +348,9 @@ void LogInfo::ProcessMessage(const Log *l)
log = true;
else if (l->u && src == l->u->nick)
log = true;
- else if (l->nc && src == l->nc->display)
+ else if (l->nc && src == l->nc->GetDisplay())
log = true;
- else if (l->ci && src == l->ci->name)
+ else if (l->ci && src == l->ci->GetName())
log = true;
else if (l->m && src == l->m->name)
log = true;
@@ -344,7 +363,7 @@ void LogInfo::ProcessMessage(const Log *l)
const Anope::string &buffer = l->BuildPrefix() + l->buf.str();
- FOREACH_MOD(OnLogMessage, (this, l, buffer));
+ EventManager::Get()->Dispatch(&Event::LogMessage::OnLogMessage, this, l, buffer);
for (unsigned i = 0; i < this->targets.size(); ++i)
{
@@ -358,7 +377,7 @@ void LogInfo::ProcessMessage(const Log *l)
if (!c)
continue;
- BotInfo *bi = l->bi;
+ User *bi = l->bi;
if (!bi)
bi = this->bot;
if (!bi)
@@ -375,7 +394,7 @@ void LogInfo::ProcessMessage(const Log *l)
}
}
}
-
+
tm *tm = localtime(&Anope::CurTime);
if (tm->tm_mday != this->last_day)
{
diff --git a/src/mail.cpp b/src/mail.cpp
index f909fa5a3..02a39bd13 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -1,19 +1,30 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "mail.h"
#include "config.h"
+#include "bots.h"
+#include "protocol.h"
+#include "modules/nickserv.h"
-Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->GetBlock("mail")->Get<const Anope::string>("sendmailpath")), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->GetBlock("mail")->Get<bool>("dontquoteaddresses")), success(false)
+Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->GetBlock("mail")->Get<Anope::string>("sendmailpath")), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->GetBlock("mail")->Get<bool>("dontquoteaddresses")), success(false)
{
}
@@ -50,37 +61,37 @@ void Mail::Message::Run()
SetExitState();
}
-bool Mail::Send(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message)
+bool Mail::Send(User *u, NickServ::Account *nc, ServiceBot *service, const Anope::string &subject, const Anope::string &message)
{
if (!nc || !service || subject.empty() || message.empty())
return false;
Configuration::Block *b = Config->GetBlock("mail");
-
+
if (!u)
{
- if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty())
+ if (!b->Get<bool>("usemail") || b->Get<Anope::string>("sendfrom").empty())
return false;
- else if (nc->email.empty())
+ else if (nc->GetEmail().empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
}
else
{
- if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty())
+ if (!b->Get<bool>("usemail") || b->Get<Anope::string>("sendfrom").empty())
u->SendMessage(service, _("Services have been configured to not send mail."));
else if (Anope::CurTime - u->lastmail < b->Get<time_t>("delay"))
u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), b->Get<time_t>("delay") - (Anope::CurTime - u->lastmail));
- else if (nc->email.empty())
- u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
+ else if (nc->GetEmail().empty())
+ u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->GetDisplay().c_str());
else
{
u->lastmail = nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
}
@@ -89,14 +100,14 @@ bool Mail::Send(User *u, NickCore *nc, BotInfo *service, const Anope::string &su
}
}
-bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message)
+bool Mail::Send(NickServ::Account *nc, const Anope::string &subject, const Anope::string &message)
{
Configuration::Block *b = Config->GetBlock("mail");
- if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty() || !nc || nc->email.empty() || subject.empty() || message.empty())
+ if (!b->Get<bool>("usemail") || b->Get<Anope::string>("sendfrom").empty() || !nc || nc->GetEmail().empty() || subject.empty() || message.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<Anope::string>("sendfrom"), nc->GetDisplay(), nc->GetEmail(), subject, message);
t->Start();
return true;
diff --git a/src/main.cpp b/src/main.cpp
index bbcccee27..33cd9b23f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,12 +1,20 @@
-/* Services -- main source file.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -15,6 +23,8 @@
#include "bots.h"
#include "socketengine.h"
#include "uplink.h"
+#include "event.h"
+#include "modules.h"
#ifndef _WIN32
#include <limits.h>
@@ -46,7 +56,7 @@ class UpdateTimer : public Timer
public:
UpdateTimer(time_t timeout) : Timer(timeout, Anope::CurTime, true) { }
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
Anope::SaveDatabases();
}
@@ -57,9 +67,9 @@ class ExpireTimer : public Timer
public:
ExpireTimer(time_t timeout) : Timer(timeout, Anope::CurTime, true) { }
- void Tick(time_t) anope_override
+ void Tick(time_t) override
{
- FOREACH_MOD(OnExpireTick, ());
+ EventManager::Get()->Dispatch(&Event::ExpireTick::OnExpireTick);
}
};
@@ -69,7 +79,7 @@ void Anope::SaveDatabases()
return;
Log(LOG_DEBUG) << "Saving databases";
- FOREACH_MOD(OnSaveDatabase, ());
+ EventManager::Get()->Dispatch(&Event::SaveDatabase::OnSaveDatabase);
}
/** The following comes from InspIRCd to get the full path of the Anope executable
@@ -113,9 +123,6 @@ static Anope::string GetFullProgDir(const Anope::string &argv0)
int main(int ac, char **av, char **envp)
{
- /* String comparisons won't work until we build the case map cache, so do it first */
- Anope::CaseMapRebuild();
-
BinaryDir = GetFullProgDir(av[0]);
if (BinaryDir[BinaryDir.length() - 1] == '.')
BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2);
@@ -180,11 +187,11 @@ int main(int ac, char **av, char **envp)
if (Anope::Restarting)
{
- FOREACH_MOD(OnRestart, ());
+ EventManager::Get()->Dispatch(&Event::Restart::OnRestart);
}
else
{
- FOREACH_MOD(OnShutdown, ());
+ EventManager::Get()->Dispatch(&Event::Shutdown::OnShutdown);
}
if (Anope::QuitReason.empty())
diff --git a/src/memos.cpp b/src/memos.cpp
deleted file mode 100644
index bf8f0eb73..000000000
--- a/src/memos.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* MemoServ functions.
- *
- * (C) 2003-2016 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 "services.h"
-#include "modules.h"
-#include "service.h"
-#include "memo.h"
-#include "users.h"
-#include "account.h"
-#include "regchannel.h"
-
-Memo::Memo() : Serializable("Memo")
-{
- mi = NULL;
- unread = receipt = false;
-}
-
-Memo::~Memo()
-{
- if (mi)
- {
- std::vector<Memo *>::iterator it = std::find(mi->memos->begin(), mi->memos->end(), this);
-
- if (it != mi->memos->end())
- mi->memos->erase(it);
- }
-}
-
-void Memo::Serialize(Serialize::Data &data) const
-{
- data["owner"] << this->owner;
- data.SetType("time", Serialize::Data::DT_INT); data["time"] << this->time;
- data["sender"] << this->sender;
- data["text"] << this->text;
- data["unread"] << this->unread;
- data["receipt"] << this->receipt;
-}
-
-Serializable* Memo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string owner;
-
- data["owner"] >> owner;
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(owner, ischan);
- if (!mi)
- return NULL;
-
- Memo *m;
- if (obj)
- m = anope_dynamic_static_cast<Memo *>(obj);
- else
- {
- m = new Memo();
- m->mi = mi;
- }
-
- m->owner = owner;
- data["time"] >> m->time;
- data["sender"] >> m->sender;
- data["text"] >> m->text;
- data["unread"] >> m->unread;
- data["receipt"] >> m->receipt;
-
- if (obj == NULL)
- mi->memos->push_back(m);
- return m;
-}
-
-MemoInfo::MemoInfo() : memomax(0), memos("Memo")
-{
-}
-
-Memo *MemoInfo::GetMemo(unsigned index) const
-{
- if (index >= this->memos->size())
- return NULL;
- Memo *m = (*memos)[index];
- m->QueueUpdate();
- return m;
-}
-
-unsigned MemoInfo::GetIndex(Memo *m) const
-{
- for (unsigned i = 0; i < this->memos->size(); ++i)
- if (this->GetMemo(i) == m)
- return i;
- return -1;
-}
-
-void MemoInfo::Del(unsigned index)
-{
- if (index >= this->memos->size())
- return;
-
- Memo *m = this->GetMemo(index);
-
- std::vector<Memo *>::iterator it = std::find(memos->begin(), memos->end(), m);
- if (it != memos->end())
- memos->erase(it);
-
- delete m;
-}
-
-bool MemoInfo::HasIgnore(User *u)
-{
- for (unsigned i = 0; i < this->ignores.size(); ++i)
- if (u->nick.equals_ci(this->ignores[i]) || (u->Account() && u->Account()->display.equals_ci(this->ignores[i])) || Anope::Match(u->GetMask(), Anope::string(this->ignores[i])))
- return true;
- return false;
-}
-
-MemoInfo *MemoInfo::GetMemoInfo(const Anope::string &target, bool &ischan)
-{
- if (!target.empty() && target[0] == '#')
- {
- ischan = true;
- ChannelInfo *ci = ChannelInfo::Find(target);
- if (ci != NULL)
- return &ci->memos;
- }
- else
- {
- ischan = false;
- NickAlias *na = NickAlias::Find(target);
- if (na != NULL)
- return &na->nc->memos;
- }
-
- return NULL;
-}
-
diff --git a/src/messages.cpp b/src/messages.cpp
index ee02cc473..c778de383 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -1,12 +1,20 @@
-/* Common message handlers
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -19,6 +27,9 @@
#include "messages.h"
#include "servers.h"
#include "channels.h"
+#include "event.h"
+#include "bots.h"
+#include "modules/operserv/stats.h"
using namespace Message;
@@ -26,7 +37,8 @@ void Away::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &msg = !params.empty() ? params[0] : "";
- FOREACH_MOD(OnUserAway, (source.GetUser(), msg));
+ EventManager::Get()->Dispatch(&Event::UserAway::OnUserAway, source.GetUser(), msg);
+
if (!msg.empty())
Log(source.GetUser(), "away") << "is now away: " << msg;
else
@@ -61,8 +73,8 @@ void Invite::Run(MessageSource &source, const std::vector<Anope::string> &params
if (!targ || targ->server != Me || !c || c->FindUser(targ))
return;
-
- FOREACH_MOD(OnInvite, (source.GetUser(), c, targ));
+
+ EventManager::Get()->Dispatch(&Event::Invite::OnInvite, source.GetUser(), c, targ);
}
void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -84,9 +96,9 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
Channel *c = cc->chan;
++it;
- FOREACH_MOD(OnPrePartChannel, (user, c));
+ EventManager::Get()->Dispatch(&Event::PrePartChannel::OnPrePartChannel, user, c);
cc->chan->DeleteUser(user);
- FOREACH_MOD(OnPartChannel, (user, c, c->name, ""));
+ EventManager::Get()->Dispatch(&Event::PartChannel::OnPartChannel, user, c, c->name, "");
}
continue;
}
@@ -119,14 +131,14 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
/* Their TS is newer, don't accept any modes from them */
else if (ts > c->creation_time)
keep_their_modes = false;
-
+
/* Update the modes for the channel */
if (keep_their_modes && !modes.empty())
/* If we are syncing, mlock is checked later in Channel::Sync. It is important to not check it here
* so that Channel::SetCorrectModes can correctly detect the presence of channel mode +r.
*/
c->SetModesInternal(source, modes, ts, !c->syncing);
-
+
for (std::list<SJoinUser>::const_iterator it = users.begin(), it_end = users.end(); it != it_end; ++it)
{
const ChannelStatus &status = it->first;
@@ -147,8 +159,8 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
* they aren't allowed to have (secureops etc).
*/
c->SetCorrectModes(u, true);
-
- FOREACH_MOD(OnJoinChannel, (u, c));
+
+ EventManager::Get()->Dispatch(&Event::JoinChannel::OnJoinChannel, u, c);
}
/* Channel is done syncing */
@@ -187,13 +199,13 @@ void Kick::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Kill::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
User *u = User::Find(params[0]);
- BotInfo *bi;
+ ServiceBot *bi;
if (!u)
return;
/* Recover if someone kills us. */
- if (u->server == Me && (bi = dynamic_cast<BotInfo *>(u)))
+ if (u->server == Me && (bi = dynamic_cast<ServiceBot *>(u)))
{
static time_t last_time = 0;
@@ -240,7 +252,7 @@ void MOTD::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (s != Me)
return;
- FILE *f = fopen(Config->GetBlock("serverinfo")->Get<const Anope::string>("motd").c_str(), "r");
+ FILE *f = fopen(Config->GetBlock("serverinfo")->Get<Anope::string>("motd").c_str(), "r");
if (f)
{
IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", s->GetName().c_str());
@@ -266,10 +278,10 @@ void Notice::Run(MessageSource &source, const std::vector<Anope::string> &params
/* ignore channel notices */
if (!IRCD->IsChannelValid(params[0]))
{
- BotInfo *bi = BotInfo::Find(params[0]);
+ ServiceBot *bi = ServiceBot::Find(params[0]);
if (!bi)
return;
- FOREACH_MOD(OnBotNotice, (u, bi, message));
+ EventManager::Get()->Dispatch(&Event::BotNotice::OnBotNotice, u, bi, message);
}
}
@@ -289,9 +301,10 @@ void Part::Run(MessageSource &source, const std::vector<Anope::string> &params)
continue;
Log(u, c, "part") << "Reason: " << (!reason.empty() ? reason : "No reason");
- FOREACH_MOD(OnPrePartChannel, (u, c));
+
+ EventManager::Get()->Dispatch(&Event::PrePartChannel::OnPrePartChannel, u, c);
c->DeleteUser(u);
- FOREACH_MOD(OnPartChannel, (u, c, c->name, !reason.empty() ? reason : ""));
+ EventManager::Get()->Dispatch(&Event::PartChannel::OnPartChannel, u, c, c->name, reason);
}
}
@@ -312,7 +325,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
Channel *c = Channel::Find(receiver);
if (c)
{
- FOREACH_MOD(OnPrivmsg, (u, c, message));
+ EventManager::Get()->Dispatch(&Event::Privmsg::OnPrivmsg, u, c, message);
}
}
else
@@ -332,7 +345,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
}
else if (!IRCD->RequiresID && Config->UseStrictPrivmsg)
{
- BotInfo *bi = BotInfo::Find(receiver);
+ ServiceBot *bi = ServiceBot::Find(receiver);
if (!bi)
return;
Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
@@ -340,7 +353,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
return;
}
- BotInfo *bi = BotInfo::Find(botname, nick_only);
+ ServiceBot *bi = ServiceBot::Find(botname, nick_only);
if (bi)
{
@@ -361,11 +374,10 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
return;
}
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnBotPrivmsg, MOD_RESULT, (u, bi, message));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotPrivmsg::OnBotPrivmsg, u, bi, message);
if (MOD_RESULT == EVENT_STOP)
return;
-
+
bi->OnMessage(u, message);
}
}
@@ -404,7 +416,7 @@ void SQuit::Run(MessageSource &source, const std::vector<Anope::string> &params)
s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
}
-void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
+void Message::Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
User *u = source.GetUser();
@@ -426,14 +438,8 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
else
{
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- const NickAlias *na = NickAlias::Find(o->name);
- if (na)
- IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->name.c_str(), o->ot->GetName().replace_all_cs(" ", "_").c_str());
- }
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->GetName().c_str(), o->GetType()->GetName().replace_all_cs(" ", "_").c_str());
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
}
@@ -441,9 +447,11 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
break;
case 'u':
{
+ ::Stats *s = Serialize::GetObject<::Stats *>();
long uptime = static_cast<long>(Anope::CurTime - Anope::StartTime);
+
IRCD->SendNumeric(242, source.GetSource(), ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60);
- IRCD->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", UserListByNick.size(), OperCount, MaxUserCount);
+ IRCD->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", UserListByNick.size(), OperCount, s ? s->GetMaxUserCount() : 0);
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
break;
} /* case 'u' */
@@ -487,11 +495,11 @@ void Whois::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (u && u->server == Me)
{
- const BotInfo *bi = BotInfo::Find(u->GetUID());
+ const ServiceBot *bi = ServiceBot::Find(u->GetUID());
IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
if (bi)
IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str());
- IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Me->GetName().c_str(), Config->GetBlock("serverinfo")->Get<const Anope::string>("description").c_str());
+ IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Me->GetName().c_str(), Config->GetBlock("serverinfo")->Get<Anope::string>("description").c_str());
if (bi)
IRCD->SendNumeric(317, source.GetSource(), "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(bi->signon));
IRCD->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", u->nick.c_str());
diff --git a/src/misc.cpp b/src/misc.cpp
index 0938a033c..3b044d9fa 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -1,12 +1,20 @@
-/* Miscellaneous routines.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -16,8 +24,8 @@
#include "config.h"
#include "bots.h"
#include "language.h"
-#include "regexpr.h"
#include "sockets.h"
+#include "event.h"
#include <errno.h>
#include <sys/types.h>
@@ -27,11 +35,13 @@
#include <netdb.h>
#endif
-NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(true), desc(descending)
+NumberList::NumberList(const Anope::string &list, bool descending, std::function<void(unsigned int)> nf, std::function<void(void)> ef) : endf(ef)
{
Anope::string error;
commasepstream sep(list);
Anope::string token;
+ bool is_valid = true;
+ std::set<unsigned> numbers;
sep.GetToken(token);
if (token.empty())
@@ -55,11 +65,8 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
if (!error.empty())
{
- if (!this->InvalidRange(list))
- {
- is_valid = false;
- return;
- }
+ is_valid = false;
+ return;
}
}
else
@@ -80,47 +87,27 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
if (!error.empty() || !error2.empty())
{
- if (!this->InvalidRange(list))
- {
- is_valid = false;
- return;
- }
+ is_valid = false;
+ return;
}
}
} while (sep.GetToken(token));
-}
-
-NumberList::~NumberList()
-{
-}
-void NumberList::Process()
-{
if (!is_valid)
return;
- if (this->desc)
- {
- for (std::set<unsigned>::reverse_iterator it = numbers.rbegin(), it_end = numbers.rend(); it != it_end; ++it)
- this->HandleNumber(*it);
- }
+ if (descending)
+ std::for_each(numbers.rbegin(), numbers.rend(), nf);
else
- {
- for (std::set<unsigned>::iterator it = numbers.begin(), it_end = numbers.end(); it != it_end; ++it)
- this->HandleNumber(*it);
- }
+ std::for_each(numbers.begin(), numbers.end(), nf);
}
-void NumberList::HandleNumber(unsigned)
-{
-}
-
-bool NumberList::InvalidRange(const Anope::string &)
+NumberList::~NumberList()
{
- return true;
+ endf();
}
-ListFormatter::ListFormatter(NickCore *acc) : nc(acc)
+ListFormatter::ListFormatter(NickServ::Account *acc) : nc(acc)
{
}
@@ -160,14 +147,15 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
unsigned length = 0;
for (std::map<Anope::string, size_t>::iterator it = lenghts.begin(), it_end = lenghts.end(); it != it_end; ++it)
{
- /* Break lines at 80 chars */
- if (length > 80)
+ if (length > Config->LineWrap)
{
breaks.insert(it->first);
length = 0;
}
else
+ {
length += it->second;
+ }
}
/* Only put a list header if more than 1 column */
@@ -214,7 +202,7 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
}
}
-InfoFormatter::InfoFormatter(NickCore *acc) : nc(acc), longest(0)
+InfoFormatter::InfoFormatter(NickServ::Account *acc) : nc(acc), longest(0)
{
}
@@ -311,7 +299,7 @@ time_t Anope::DoTime(const Anope::string &s)
return amount;
}
-Anope::string Anope::Duration(time_t t, const NickCore *nc)
+Anope::string Anope::Duration(time_t t, NickServ::Account *nc)
{
/* We first calculate everything */
time_t years = t / 31536000;
@@ -352,7 +340,7 @@ Anope::string Anope::Duration(time_t t, const NickCore *nc)
}
}
-Anope::string Anope::strftime(time_t t, const NickCore *nc, bool short_output)
+Anope::string Anope::strftime(time_t t, NickServ::Account *nc, bool short_output)
{
tm tm = *localtime(&t);
char buf[BUFSIZE];
@@ -367,10 +355,10 @@ Anope::string Anope::strftime(time_t t, const NickCore *nc, bool short_output)
return Anope::string(buf) + " " + Language::Translate(nc, _("(now)"));
}
-Anope::string Anope::Expires(time_t expires, const NickCore *nc)
+Anope::string Anope::Expires(time_t expires, NickServ::Account *nc)
{
if (!expires)
- return Language::Translate(nc, NO_EXPIRE);
+ return Language::Translate(nc, _("does not expire"));
else if (expires <= Anope::CurTime)
return Language::Translate(nc, _("expires momentarily"));
else
@@ -407,38 +395,29 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
{
size_t s = 0, m = 0, str_len = str.length(), mask_len = mask.length();
- if (use_regex && mask_len >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/')
+ if (use_regex && Config->regex_flags && mask_len >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/')
{
Anope::string stripped_mask = mask.substr(1, mask_len - 2);
// This is often called with the same mask multiple times in a row, so cache it
- static Regex *r = NULL;
+ static Anope::string pattern;
+ static std::regex r;
- if (r == NULL || r->GetExpression() != stripped_mask)
+ if (pattern != stripped_mask)
{
- ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string>("regexengine"));
- if (provider)
+ try
{
- try
- {
- delete r;
- r = NULL;
- // This may throw
- r = provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- Log(LOG_DEBUG) << ex.GetReason();
- }
+ r.assign(stripped_mask.str(), Config->regex_flags);
+ pattern = stripped_mask;
}
- else
+ catch (const std::regex_error &error)
{
- delete r;
- r = NULL;
+ Log(LOG_DEBUG) << error.what();
}
}
- if (r != NULL && r->Matches(str))
- return true;
+ if (pattern == stripped_mask)
+ if (std::regex_search(str.str(), r))
+ return true;
// Fall through to non regex match
}
@@ -509,29 +488,10 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
void Anope::Encrypt(const Anope::string &src, Anope::string &dest)
{
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnEncrypt, MOD_RESULT, (src, dest));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::Encrypt::OnEncrypt, src, dest);
static_cast<void>(MOD_RESULT);
}
-bool Anope::Decrypt(const Anope::string &src, Anope::string &dest)
-{
- size_t pos = src.find(':');
- if (pos == Anope::string::npos)
- {
- Log() << "Error: Anope::Decrypt() called with invalid password string (" << src << ")";
- return false;
- }
- Anope::string hashm(src.begin(), src.begin() + pos);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnDecrypt, MOD_RESULT, (hashm, src, dest));
- if (MOD_RESULT == EVENT_ALLOW)
- return true;
-
- return false;
-}
-
Anope::string Anope::printf(const char *fmt, ...)
{
va_list args;
@@ -651,7 +611,7 @@ Anope::string Anope::VersionBuildString()
if (!flags.empty())
s += ", flags " + flags;
-
+
return s;
}
diff --git a/src/modes.cpp b/src/modes.cpp
index 229945b7d..b41bece1d 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -1,9 +1,21 @@
-/* Mode support
+/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Adam <Adam@anope.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Adam <Adam@anope.org>
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -13,6 +25,8 @@
#include "protocol.h"
#include "channels.h"
#include "uplink.h"
+#include "event.h"
+#include "modules/chanserv.h"
struct StackerInfo;
@@ -36,9 +50,6 @@ static std::map<Anope::string, UserMode *> UserModesByName;
/* Sorted by status */
static std::vector<ChannelModeStatus *> ChannelModesByStatus;
-/* Number of generic modes we support */
-unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
-
struct StackerInfo
{
/* Modes to be added */
@@ -46,7 +57,7 @@ struct StackerInfo
/* Modes to be deleted */
std::list<std::pair<Mode *, Anope::string> > DelModes;
/* Bot this is sent from */
- BotInfo *bi;
+ User *bi;
StackerInfo() : bi(NULL) { }
@@ -124,6 +135,12 @@ Mode::~Mode()
bool Mode::CanSet(User *u) const
{
+ if (!setable)
+ return false;
+
+ if (oper_only)
+ return u && u->HasMode("OPER");
+
return true;
}
@@ -142,8 +159,7 @@ ChannelMode::ChannelMode(const Anope::string &cm, char mch) : Mode(cm, MC_CHANNE
bool ChannelMode::CanSet(User *u) const
{
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnCanSet, MOD_RESULT, (u, this));
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::CanSet::OnCanSet, u, this);
return MOD_RESULT != EVENT_STOP;
}
@@ -186,6 +202,11 @@ ChannelModeParam::ChannelModeParam(const Anope::string &cm, char mch, bool ma) :
this->type = MODE_PARAM;
}
+bool ChannelModeParam::IsValid(Anope::string &value) const
+{
+ return std::regex_search(value.str(), param_validation);
+}
+
ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char msymbol, short mlevel) : ChannelMode(mname, modeChar), symbol(msymbol), level(mlevel)
{
this->type = MODE_STATUS;
@@ -231,34 +252,6 @@ ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string &param)
template class ChannelModeVirtual<ChannelMode>;
template class ChannelModeVirtual<ChannelModeList>;
-bool UserModeOperOnly::CanSet(User *u) const
-{
- return u && u->HasMode("OPER");
-}
-
-bool UserModeNoone::CanSet(User *u) const
-{
- return false;
-}
-
-bool ChannelModeKey::IsValid(Anope::string &value) const
-{
- if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos)
- return true;
-
- return false;
-}
-
-bool ChannelModeOperOnly::CanSet(User *u) const
-{
- return u && u->HasMode("OPER");
-}
-
-bool ChannelModeNoone::CanSet(User *u) const
-{
- return false;
-}
-
void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string &param)
{
bool is_param = mode->type == MODE_PARAM;
@@ -313,7 +306,7 @@ void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string &param)
static class ModePipe : public Pipe
{
public:
- void OnNotify()
+ void OnNotify() override
{
ModeManager::ProcessModes();
}
@@ -395,15 +388,10 @@ bool ModeManager::AddUserMode(UserMode *um)
{
if (ModeManager::FindUserModeByChar(um->mchar) != NULL)
return false;
+
if (ModeManager::FindUserModeByName(um->name) != NULL)
return false;
- if (um->name.empty())
- {
- um->name = stringify(++GenericUserModes);
- Log() << "ModeManager: Added generic support for user mode " << um->mchar;
- }
-
unsigned want = um->mchar;
if (want >= UserModesIdx.size())
UserModesIdx.resize(want + 1);
@@ -413,7 +401,7 @@ bool ModeManager::AddUserMode(UserMode *um)
UserModes.push_back(um);
- FOREACH_MOD(OnUserModeAdd, (um));
+ EventManager::Get()->Dispatch(&Event::UserModeAdd::OnUserModeAdd, um);
return true;
}
@@ -425,12 +413,6 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
if (ModeManager::FindChannelModeByName(cm->name) != NULL)
return false;
- if (cm->name.empty())
- {
- cm->name = stringify(++GenericChannelModes);
- Log() << "ModeManager: Added generic support for channel mode " << cm->mchar;
- }
-
if (cm->mchar)
{
unsigned want = cm->mchar;
@@ -454,7 +436,7 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
ChannelModes.push_back(cm);
- FOREACH_MOD(OnChannelModeAdd, (cm));
+ EventManager::Get()->Dispatch(&Event::ChannelModeAdd::OnChannelModeAdd, cm);
for (unsigned int i = 0; i < ChannelModes.size(); ++i)
ChannelModes[i]->Check();
@@ -570,7 +552,7 @@ char ModeManager::GetStatusChar(char value)
ChannelMode *cm = ChannelModesIdx[want];
if (cm == NULL || cm->type != MODE_STATUS || cm->mchar == value)
return 0;
-
+
return cm->mchar;
}
@@ -610,7 +592,7 @@ void ModeManager::RebuildStatusModes()
std::sort(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), statuscmp);
}
-void ModeManager::StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
+void ModeManager::StackerAdd(User *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
{
StackerInfo *s = GetInfo(ChannelStackerObjects, c);
s->AddMode(cm, Set, Param);
@@ -624,7 +606,7 @@ void ModeManager::StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set,
modePipe->Notify();
}
-void ModeManager::StackerAdd(BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param)
+void ModeManager::StackerAdd(User *bi, User *u, UserMode *um, bool Set, const Anope::string &Param)
{
StackerInfo *s = GetInfo(UserStackerObjects, u);
s->AddMode(um, Set, Param);
@@ -742,7 +724,59 @@ void ModeManager::StackerDel(Mode *m)
}
}
-Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0), family(0)
+void ModeManager::Apply(Configuration::Conf *old)
+{
+#warning "remove old modes"
+
+ for (Configuration::Channelmode &cm : Config->Channelmodes)
+ {
+ ChannelMode *mode;
+
+ if (cm.list)
+ Log(LOG_DEBUG) << "Creating channelmode list " << cm.name << " (" << cm.character << ")";
+ else if (cm.status)
+ Log(LOG_DEBUG) << "Creating channelmode status " << cm.name << " (" << cm.character << ")";
+ else if (cm.param)
+ Log(LOG_DEBUG) << "Creating channelmode param " << cm.name << " (" << cm.character << ")";
+ else
+ Log(LOG_DEBUG) << "Creating channelmode " << cm.name << " (" << cm.character << ")";
+
+ if (cm.list)
+ mode = new ChannelModeList(cm.name, cm.character);
+ else if (cm.status)
+ mode = new ChannelModeStatus(cm.name, cm.character, cm.status, cm.level);
+ else if (cm.param)
+ mode = new ChannelModeParam(cm.name, cm.character, !cm.param_unset);
+ else
+ mode = new ChannelMode(cm.name, cm.character);
+
+ mode->SetSetable(cm.setable);
+ mode->SetOperOnly(cm.oper_only);
+
+ if (!AddChannelMode(mode))
+ delete mode;
+ }
+
+ for (Configuration::Usermode &um : Config->Usermodes)
+ {
+ UserMode *mode;
+
+ Log(LOG_DEBUG) << "Creating usermode " << um.name << " (" << um.character << ")";
+
+ if (um.param)
+ mode = new UserModeParam(um.name, um.character);
+ else
+ mode = new UserMode(um.name, um.character);
+
+ mode->SetSetable(um.setable);
+ mode->SetOperOnly(um.oper_only);
+
+ if (!AddUserMode(mode))
+ delete mode;
+ }
+}
+
+Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
{
Anope::string n, u, h;
@@ -769,21 +803,21 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
else
this->nick = fh;
}
-
+
at = this->host.find('#');
if (at != Anope::string::npos)
{
this->real = this->host.substr(at + 1);
this->host = this->host.substr(0, at);
}
-
+
/* If the mask is all *'s it will match anything, so just clear it */
if (this->nick.find_first_not_of("*") == Anope::string::npos)
this->nick.clear();
-
+
if (this->user.find_first_not_of("*") == Anope::string::npos)
this->user.clear();
-
+
if (this->host.find_first_not_of("*") == Anope::string::npos)
this->host.clear();
else
@@ -803,8 +837,6 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
{
this->cidr_len = convertTo<unsigned short>(cidr_range);
- /* If we got here, cidr_len is a valid number. */
-
this->host = cidr_ip;
this->family = addr.family();
@@ -831,6 +863,7 @@ const Anope::string Entry::GetNUHMask() const
h = host.empty() ? "*" : host,
r = real.empty() ? "" : "#" + real,
c;
+
switch (family)
{
case AF_INET:
@@ -842,8 +875,7 @@ const Anope::string Entry::GetNUHMask() const
c = "/" + stringify(cidr_len);
break;
}
-
- return n + "!" + u + "@" + h + c + r;
+ return n + "!" + u + "@" + h + r + c;
}
bool Entry::Matches(User *u, bool full) const
@@ -888,10 +920,10 @@ bool Entry::Matches(User *u, bool full) const
else if (!this->host.empty() && !Anope::Match(u->GetDisplayedHost(), this->host) && !Anope::Match(u->GetCloakedHost(), this->host) &&
(!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip.addr(), this->host))))
ret = false;
-
+
if (!this->real.empty() && !Anope::Match(u->realname, this->real))
ret = false;
-
+
return ret;
}
diff --git a/src/module.cpp b/src/module.cpp
index 3e377efec..73ab9ad99 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -1,15 +1,25 @@
-/* Modular support
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "modules.h"
#include "language.h"
-#include "account.h"
#ifdef GETTEXT_FOUND
# include <libintl.h>
@@ -33,7 +43,7 @@ Module::Module(const Anope::string &modname, const Anope::string &, ModType modt
if (ModuleManager::FindModule(this->name))
throw CoreException("Module already exists!");
-
+
if (Anope::NoThird && type & THIRD)
throw ModuleException("Third party modules may not be loaded");
@@ -63,11 +73,6 @@ Module::Module(const Anope::string &modname, const Anope::string &, ModType modt
Module::~Module()
{
- UnsetExtensibles();
-
- /* Detach all event hooks for this module */
- ModuleManager::DetachAll(this);
- IdentifyRequest::ModuleUnload(this);
/* Clear any active timers this module has */
TimerManager::DeleteTimersFor(this);
@@ -102,10 +107,6 @@ void Module::SetAuthor(const Anope::string &nauthor)
this->author = nauthor;
}
-void Module::Prioritize()
-{
-}
-
ModuleVersion::ModuleVersion(const ModuleVersionC &ver)
{
version_major = ver.version_major;
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index 2cda9e256..204421f34 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -1,16 +1,27 @@
-/* Modular support
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "modules.h"
#include "users.h"
-#include "regchannel.h"
#include "config.h"
+#include "event.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -21,7 +32,16 @@
#endif
std::list<Module *> ModuleManager::Modules;
-std::vector<Module *> ModuleManager::EventHandlers[I_SIZE];
+
+void ModuleDef::Depends(const Anope::string &modname)
+{
+ dependencies.push_back(modname);
+}
+
+const std::vector<Anope::string> &ModuleDef::GetDependencies()
+{
+ return dependencies;
+}
#ifdef _WIN32
void ModuleManager::CleanupRuntimeDirectory()
@@ -36,7 +56,7 @@ void ModuleManager::CleanupRuntimeDirectory()
Log(LOG_DEBUG) << "Cannot open directory (" << dirbuf << ")";
return;
}
-
+
for (dirent *dp; (dp = readdir(dirp));)
{
if (!dp->d_ino)
@@ -62,17 +82,17 @@ void ModuleManager::CleanupRuntimeDirectory()
static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &output)
{
Anope::string input = Anope::ModuleDir + "/modules/" + name + ".so";
-
+
struct stat s;
if (stat(input.c_str(), &s) == -1)
return MOD_ERR_NOEXIST;
else if (!S_ISREG(s.st_mode))
return MOD_ERR_NOEXIST;
-
+
std::ifstream source(input.c_str(), std::ios_base::in | std::ios_base::binary);
if (!source.is_open())
return MOD_ERR_NOEXIST;
-
+
char *tmp_output = strdup(output.c_str());
int target_fd = mkstemp(tmp_output);
if (target_fd == -1 || close(target_fd) == -1)
@@ -85,7 +105,7 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out
free(tmp_output);
Log(LOG_DEBUG_2) << "Runtime module location: " << output;
-
+
std::ofstream target(output.c_str(), std::ios_base::in | std::ios_base::binary);
if (!target.is_open())
{
@@ -103,7 +123,7 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out
target.write(buffer, read_len);
want -= read_len;
}
-
+
source.close();
target.close();
@@ -111,22 +131,6 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out
}
#endif
-/* This code was found online at http://www.linuxjournal.com/article/3687#comment-26593
- *
- * This function will take a pointer from either dlsym or GetProcAddress and cast it in
- * a way that won't cause C++ warnings/errors to come up.
- */
-template <class TYPE> static TYPE function_cast(void *symbol)
-{
- union
- {
- void *symbol;
- TYPE function;
- } cast;
- cast.symbol = symbol;
- return cast.function;
-}
-
ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
{
if (modname.empty())
@@ -139,7 +143,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
#ifdef _WIN32
/* Generate the filename for the temporary copy of the module */
- Anope::string pbuf = Anope::DataDir + "/runtime/" + modname + ".so.XXXXXX";
+ Anope::string pbuf = Anope::DataDir + "/runtime/" + modname.replace_all_cs("/", "_") + ".so.XXXXXX";
/* Don't skip return value checking! -GD */
ModuleReturn ret = moduleCopyFile(modname, pbuf);
@@ -152,7 +156,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
return ret;
}
#else
- Anope::string pbuf = Anope::ModuleDir + "/modules/" + modname + ".so";
+ Anope::string pbuf = Anope::ModuleDir + "/modules/" + modname.replace_all_cs("/", "_") + ".so";
#endif
dlerror();
@@ -165,9 +169,21 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
return MOD_ERR_NOLOAD;
}
+ dlerror();
+ AnopeModule *module = static_cast<AnopeModule *>(dlsym(handle, "AnopeMod"));
+ err = dlerror();
+ if (!module || module->api_version != ANOPE_MODAPI_VER)
+ {
+ Log() << "No module symbols function found, not an Anope module";
+ if (err && *err)
+ Log(LOG_DEBUG) << err;
+ dlclose(handle);
+ return MOD_ERR_NOLOAD;
+ }
+
try
{
- ModuleVersion v = GetVersion(handle);
+ ModuleVersion v = module->version();
if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor()))
{
@@ -205,17 +221,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
return MOD_ERR_NOLOAD;
}
- dlerror();
- Module *(*func)(const Anope::string &, const Anope::string &) = function_cast<Module *(*)(const Anope::string &, const Anope::string &)>(dlsym(handle, "AnopeInit"));
- err = dlerror();
- if (!func)
- {
- Log() << "No init function found, not an Anope module";
- if (err && *err)
- Log(LOG_DEBUG) << err;
- dlclose(handle);
- return MOD_ERR_NOLOAD;
- }
+ ModuleDef *def = module->init();
/* Create module. */
Anope::string nick;
@@ -227,7 +233,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
ModuleReturn moderr = MOD_ERR_OK;
try
{
- m = func(modname, nick);
+ m = def->Create(modname, nick);
}
catch (const ModuleException &ex)
{
@@ -244,6 +250,8 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
m->filename = pbuf;
m->handle = handle;
+ m->def = def;
+ m->module = module;
/* Initialize config */
try
@@ -260,9 +268,6 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
Log() << "Module " << modname << " couldn't load due to configuration problems: " << ex.GetReason();
moderr = MOD_ERR_EXCEPTION;
}
- catch (const NotImplementedException &ex)
- {
- }
if (moderr != MOD_ERR_OK)
{
@@ -272,41 +277,17 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
Log(LOG_DEBUG) << "Module " << modname << " loaded.";
- /* Attach module to all events */
- for (unsigned i = 0; i < I_SIZE; ++i)
- EventHandlers[i].push_back(m);
-
- m->Prioritize();
-
- FOREACH_MOD(OnModuleLoad, (u, m));
+ EventManager::Get()->Dispatch(&Event::ModuleLoad::OnModuleLoad, u, m);
return MOD_ERR_OK;
}
-ModuleVersion ModuleManager::GetVersion(void *handle)
-{
- dlerror();
- ModuleVersionC (*func)() = function_cast<ModuleVersionC (*)()>(dlsym(handle, "AnopeVersion"));;
- if (!func)
- {
- Log() << "No version function found, not an Anope module";
-
- const char *err = dlerror();
- if (err && *err)
- Log(LOG_DEBUG) << err;
-
- throw ModuleException("No version");
- }
-
- return func();
-}
-
ModuleReturn ModuleManager::UnloadModule(Module *m, User *u)
{
if (!m)
return MOD_ERR_PARAMS;
- FOREACH_MOD(OnModuleUnload, (u, m));
+ EventManager::Get()->Dispatch(&Event::ModuleUnload::OnModuleUnload, u, m);
return DeleteModule(m);
}
@@ -366,22 +347,20 @@ ModuleReturn ModuleManager::DeleteModule(Module *m)
if (!m || !m->handle)
return MOD_ERR_PARAMS;
+ Serialize::Unregister(m);
+
void *handle = m->handle;
Anope::string filename = m->filename;
Log(LOG_DEBUG) << "Unloading module " << m->name;
- dlerror();
- void (*destroy_func)(Module *m) = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini"));
- const char *err = dlerror();
- if (!destroy_func || (err && *err))
- {
- Log() << "No destroy function found for " << m->name << ", chancing delete...";
- delete m; /* we just have to chance they haven't overwrote the delete operator then... */
- }
- else
- destroy_func(m); /* Let the module delete it self, just in case */
+ ModuleDef *def = m->def;
+ AnopeModule *module = m->module;
+ def->Destroy(m);
+ module->fini(def);
+
+ dlerror();
if (dlclose(handle))
Log() << dlerror();
@@ -389,121 +368,8 @@ ModuleReturn ModuleManager::DeleteModule(Module *m)
if (!filename.empty())
unlink(filename.c_str());
#endif
-
- return MOD_ERR_OK;
-}
-
-void ModuleManager::DetachAll(Module *mod)
-{
- for (unsigned i = 0; i < I_SIZE; ++i)
- {
- std::vector<Module *> &mods = EventHandlers[i];
- std::vector<Module *>::iterator it2 = std::find(mods.begin(), mods.end(), mod);
- if (it2 != mods.end())
- mods.erase(it2);
- }
-}
-
-bool ModuleManager::SetPriority(Module *mod, Priority s)
-{
- for (unsigned i = 0; i < I_SIZE; ++i)
- SetPriority(mod, static_cast<Implementation>(i), s);
-
- return true;
-}
-
-bool ModuleManager::SetPriority(Module *mod, Implementation i, Priority s, Module **modules, size_t sz)
-{
- /** To change the priority of a module, we first find its position in the vector,
- * then we find the position of the other modules in the vector that this module
- * wants to be before/after. We pick off either the first or last of these depending
- * on which they want, and we make sure our module is *at least* before or after
- * the first or last of this subset, depending again on the type of priority.
- */
-
- /* Locate our module. This is O(n) but it only occurs on module load so we're
- * not too bothered about it
- */
- size_t source = 0;
- bool found = false;
- for (size_t x = 0, end = EventHandlers[i].size(); x != end; ++x)
- if (EventHandlers[i][x] == mod)
- {
- source = x;
- found = true;
- break;
- }
-
- /* Eh? this module doesn't exist, probably trying to set priority on an event
- * they're not attached to.
- */
- if (!found)
- return false;
-
- size_t swap_pos = 0;
- bool swap = true;
- switch (s)
- {
- /* Dummy value */
- case PRIORITY_DONTCARE:
- swap = false;
- break;
- /* Module wants to be first, sod everything else */
- case PRIORITY_FIRST:
- swap_pos = 0;
- break;
- /* Module is submissive and wants to be last... awww. */
- case PRIORITY_LAST:
- if (EventHandlers[i].empty())
- swap_pos = 0;
- else
- swap_pos = EventHandlers[i].size() - 1;
- break;
- /* Place this module after a set of other modules */
- case PRIORITY_AFTER:
- /* Find the latest possible position */
- swap_pos = 0;
- swap = false;
- for (size_t x = 0, end = EventHandlers[i].size(); x != end; ++x)
- for (size_t n = 0; n < sz; ++n)
- if (modules[n] && EventHandlers[i][x] == modules[n] && x >= swap_pos && source <= swap_pos)
- {
- swap_pos = x;
- swap = true;
- }
- break;
- /* Place this module before a set of other modules */
- case PRIORITY_BEFORE:
- swap_pos = EventHandlers[i].size() - 1;
- swap = false;
- for (size_t x = 0, end = EventHandlers[i].size(); x != end; ++x)
- for (size_t n = 0; n < sz; ++n)
- if (modules[n] && EventHandlers[i][x] == modules[n] && x <= swap_pos && source >= swap_pos)
- {
- swap = true;
- swap_pos = x;
- }
- }
-
- /* Do we need to swap? */
- if (swap && swap_pos != source)
- {
- /* Suggestion from Phoenix, "shuffle" the modules to better retain call order */
- int incrmnt = 1;
-
- if (source > swap_pos)
- incrmnt = -1;
-
- for (unsigned j = source; j != swap_pos; j += incrmnt)
- {
- if (j + incrmnt > EventHandlers[i].size() - 1 || (!j && incrmnt == -1))
- continue;
- std::swap(EventHandlers[i][j], EventHandlers[i][j + incrmnt]);
- }
- }
-
- return true;
+ return MOD_ERR_OK;
}
void ModuleManager::UnloadAll()
@@ -516,7 +382,7 @@ void ModuleManager::UnloadAll()
if ((m->type & j) == m->type)
modules.push_back(m->name);
}
-
+
for (unsigned i = 0; i < modules.size(); ++i)
{
Module *m = FindModule(modules[i]);
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
deleted file mode 100644
index 795298cba..000000000
--- a/src/nickalias.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "services.h"
-#include "account.h"
-#include "modules.h"
-#include "opertype.h"
-#include "protocol.h"
-#include "users.h"
-#include "servers.h"
-#include "config.h"
-
-Serialize::Checker<nickalias_map> NickAliasList("NickAlias");
-
-NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serializable("NickAlias")
-{
- if (nickname.empty())
- throw CoreException("Empty nick passed to NickAlias constructor");
- else if (!nickcore)
- throw CoreException("Empty nickcore passed to NickAlias constructor");
-
- this->time_registered = this->last_seen = Anope::CurTime;
- this->nick = nickname;
- this->nc = nickcore;
- nickcore->aliases->push_back(this);
-
- size_t old = NickAliasList->size();
- (*NickAliasList)[this->nick] = this;
- if (old == NickAliasList->size())
- Log(LOG_DEBUG) << "Duplicate nick " << nickname << " in nickalias table";
-
- if (this->nc->o == NULL)
- {
- Oper *o = Oper::Find(this->nick);
- if (o == NULL)
- o = Oper::Find(this->nc->display);
- nickcore->o = o;
- if (this->nc->o != NULL)
- Log() << "Tied oper " << this->nc->display << " to type " << this->nc->o->ot->GetName();
- }
-}
-
-NickAlias::~NickAlias()
-{
- UnsetExtensibles();
-
- FOREACH_MOD(OnDelNick, (this));
-
- /* Accept nicks that have no core, because of database load functions */
- if (this->nc)
- {
- /* Next: see if our core is still useful. */
- std::vector<NickAlias *>::iterator it = std::find(this->nc->aliases->begin(), this->nc->aliases->end(), this);
- if (it != this->nc->aliases->end())
- this->nc->aliases->erase(it);
- if (this->nc->aliases->empty())
- {
- delete this->nc;
- this->nc = NULL;
- }
- else
- {
- /* Display updating stuff */
- if (this->nick.equals_ci(this->nc->display))
- this->nc->SetDisplay(this->nc->aliases->front());
- }
- }
-
- /* Remove us from the aliases list */
- NickAliasList->erase(this->nick);
-}
-
-void NickAlias::SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created)
-{
- this->vhost_ident = ident;
- this->vhost_host = host;
- this->vhost_creator = creator;
- this->vhost_created = created;
-}
-
-void NickAlias::RemoveVhost()
-{
- this->vhost_ident.clear();
- this->vhost_host.clear();
- this->vhost_creator.clear();
- this->vhost_created = 0;
-}
-
-bool NickAlias::HasVhost() const
-{
- return !this->vhost_host.empty();
-}
-
-const Anope::string &NickAlias::GetVhostIdent() const
-{
- return this->vhost_ident;
-}
-
-const Anope::string &NickAlias::GetVhostHost() const
-{
- return this->vhost_host;
-}
-
-const Anope::string &NickAlias::GetVhostCreator() const
-{
- return this->vhost_creator;
-}
-
-time_t NickAlias::GetVhostCreated() const
-{
- return this->vhost_created;
-}
-
-NickAlias *NickAlias::Find(const Anope::string &nick)
-{
- nickalias_map::const_iterator it = NickAliasList->find(nick);
- if (it != NickAliasList->end())
- {
- it->second->QueueUpdate();
- return it->second;
- }
-
- return NULL;
-}
-
-void NickAlias::Serialize(Serialize::Data &data) const
-{
- data["nick"] << this->nick;
- data["last_quit"] << this->last_quit;
- data["last_realname"] << this->last_realname;
- data["last_usermask"] << this->last_usermask;
- data["last_realhost"] << this->last_realhost;
- data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
- data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
- data["nc"] << this->nc->display;
-
- if (this->HasVhost())
- {
- data["vhost_ident"] << this->GetVhostIdent();
- data["vhost_host"] << this->GetVhostHost();
- data["vhost_creator"] << this->GetVhostCreator();
- data["vhost_time"] << this->GetVhostCreated();
- }
-
- Extensible::ExtensibleSerialize(this, this, data);
-}
-
-Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string snc, snick;
-
- data["nc"] >> snc;
- data["nick"] >> snick;
-
- NickCore *core = NickCore::Find(snc);
- if (core == NULL)
- return NULL;
-
- NickAlias *na;
- if (obj)
- na = anope_dynamic_static_cast<NickAlias *>(obj);
- else
- na = new NickAlias(snick, core);
-
- if (na->nc != core)
- {
- std::vector<NickAlias *>::iterator it = std::find(na->nc->aliases->begin(), na->nc->aliases->end(), na);
- if (it != na->nc->aliases->end())
- na->nc->aliases->erase(it);
-
- if (na->nc->aliases->empty())
- delete na->nc;
- else if (na->nick.equals_ci(na->nc->display))
- na->nc->SetDisplay(na->nc->aliases->front());
-
- na->nc = core;
- core->aliases->push_back(na);
- }
-
- data["last_quit"] >> na->last_quit;
- data["last_realname"] >> na->last_realname;
- data["last_usermask"] >> na->last_usermask;
- data["last_realhost"] >> na->last_realhost;
- data["time_registered"] >> na->time_registered;
- data["last_seen"] >> na->last_seen;
-
- Anope::string vhost_ident, vhost_host, vhost_creator;
- time_t vhost_time;
-
- data["vhost_ident"] >> vhost_ident;
- data["vhost_host"] >> vhost_host;
- data["vhost_creator"] >> vhost_creator;
- data["vhost_time"] >> vhost_time;
-
- na->SetVhost(vhost_ident, vhost_host, vhost_creator, vhost_time);
-
- Extensible::ExtensibleUnserialize(na, na, data);
-
- /* compat */
- bool b;
- b = false;
- data["extensible:NO_EXPIRE"] >> b;
- if (b)
- na->Extend<bool>("NS_NO_EXPIRE");
- /* end compat */
-
- return na;
-}
-
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
deleted file mode 100644
index 633f5a7cb..000000000
--- a/src/nickcore.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "services.h"
-#include "modules.h"
-#include "account.h"
-#include "config.h"
-
-Serialize::Checker<nickcore_map> NickCoreList("NickCore");
-
-NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), chanaccess("ChannelInfo"), aliases("NickAlias")
-{
- if (coredisplay.empty())
- throw CoreException("Empty display passed to NickCore constructor");
-
- this->o = NULL;
- this->channelcount = 0;
- this->lastmail = 0;
-
- this->display = coredisplay;
-
- size_t old = NickCoreList->size();
- (*NickCoreList)[this->display] = this;
- if (old == NickCoreList->size())
- Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?";
-
- FOREACH_MOD(OnNickCoreCreate, (this));
-}
-
-NickCore::~NickCore()
-{
- UnsetExtensibles();
-
- FOREACH_MOD(OnDelCore, (this));
-
- if (!this->chanaccess->empty())
- Log(LOG_DEBUG) << "Non-empty chanaccess list in destructor!";
-
- for (std::list<User *>::iterator it = this->users.begin(); it != this->users.end();)
- {
- User *user = *it++;
- user->Logout();
- }
- this->users.clear();
-
- NickCoreList->erase(this->display);
-
- this->ClearAccess();
-
- if (!this->memos.memos->empty())
- {
- for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i)
- delete this->memos.GetMemo(i);
- this->memos.memos->clear();
- }
-}
-
-void NickCore::Serialize(Serialize::Data &data) const
-{
- data["display"] << this->display;
- data["pass"] << this->pass;
- data["email"] << this->email;
- data["language"] << this->language;
- for (unsigned i = 0; i < this->access.size(); ++i)
- data["access"] << this->access[i] << " ";
- data["memomax"] << this->memos.memomax;
- for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
- data["memoignores"] << this->memos.ignores[i] << " ";
- Extensible::ExtensibleSerialize(this, this, data);
-}
-
-Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- NickCore *nc;
-
- Anope::string sdisplay;
-
- data["display"] >> sdisplay;
-
- if (obj)
- nc = anope_dynamic_static_cast<NickCore *>(obj);
- else
- nc = new NickCore(sdisplay);
-
- data["pass"] >> nc->pass;
- data["email"] >> nc->email;
- data["language"] >> nc->language;
- {
- Anope::string buf;
- data["access"] >> buf;
- spacesepstream sep(buf);
- nc->access.clear();
- while (sep.GetToken(buf))
- nc->access.push_back(buf);
- }
- data["memomax"] >> nc->memos.memomax;
- {
- Anope::string buf;
- data["memoignores"] >> buf;
- spacesepstream sep(buf);
- nc->memos.ignores.clear();
- while (sep.GetToken(buf))
- nc->memos.ignores.push_back(buf);
- }
-
- Extensible::ExtensibleUnserialize(nc, nc, data);
-
- /* compat */
- bool b;
- b = false;
- data["extensible:SECURE"] >> b;
- if (b)
- nc->Extend<bool>("NS_SECURE");
- b = false;
- data["extensible:PRIVATE"] >> b;
- if (b)
- nc->Extend<bool>("NS_PRIVATE");
- b = false;
- data["extensible:AUTOOP"] >> b;
- if (b)
- nc->Extend<bool>("AUTOOP");
- b = false;
- data["extensible:HIDE_EMAIL"] >> b;
- if (b)
- nc->Extend<bool>("HIDE_EMAIL");
- b = false;
- data["extensible:HIDE_QUIT"] >> b;
- if (b)
- nc->Extend<bool>("HIDE_QUIT");
- b = false;
- data["extensible:MEMO_RECEIVE"] >> b;
- if (b)
- nc->Extend<bool>("MEMO_RECEIVE");
- b = false;
- data["extensible:MEMO_SIGNON"] >> b;
- if (b)
- nc->Extend<bool>("MEMO_SIGNON");
- b = false;
- data["extensible:KILLPROTECT"] >> b;
- if (b)
- nc->Extend<bool>("KILLPROTECT");
- /* end compat */
-
- return nc;
-}
-
-void NickCore::SetDisplay(const NickAlias *na)
-{
- if (na->nc != this || na->nick == this->display)
- return;
-
- FOREACH_MOD(OnChangeCoreDisplay, (this, na->nick));
-
- /* this affects the serialized aliases */
- for (unsigned i = 0; i < aliases->size(); ++i)
- aliases->at(i)->QueueUpdate();
-
- /* Remove the core from the list */
- NickCoreList->erase(this->display);
-
- this->display = na->nick;
-
- (*NickCoreList)[this->display] = this;
-}
-
-bool NickCore::IsServicesOper() const
-{
- return this->o != NULL;
-}
-
-void NickCore::AddAccess(const Anope::string &entry)
-{
- this->access.push_back(entry);
- FOREACH_MOD(OnNickAddAccess, (this, entry));
-}
-
-Anope::string NickCore::GetAccess(unsigned entry) const
-{
- if (this->access.empty() || entry >= this->access.size())
- return "";
- return this->access[entry];
-}
-
-unsigned NickCore::GetAccessCount() const
-{
- return this->access.size();
-}
-
-bool NickCore::FindAccess(const Anope::string &entry)
-{
- for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- if (this->access[i] == entry)
- return true;
-
- return false;
-}
-
-void NickCore::EraseAccess(const Anope::string &entry)
-{
- for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- if (this->access[i] == entry)
- {
- FOREACH_MOD(OnNickEraseAccess, (this, entry));
- this->access.erase(this->access.begin() + i);
- break;
- }
-}
-
-void NickCore::ClearAccess()
-{
- FOREACH_MOD(OnNickClearAccess, (this));
- this->access.clear();
-}
-
-bool NickCore::IsOnAccess(const User *u) const
-{
- Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3;
- if (!u->vhost.empty())
- buf2 = u->GetIdent() + "@" + u->vhost;
- if (!u->GetCloakedHost().empty())
- buf3 = u->GetIdent() + "@" + u->GetCloakedHost();
-
- for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- {
- Anope::string a = this->GetAccess(i);
- if (Anope::Match(buf, a) || (!buf2.empty() && Anope::Match(buf2, a)) || (!buf3.empty() && Anope::Match(buf3, a)))
- return true;
- }
- return false;
-}
-
-void NickCore::AddChannelReference(ChannelInfo *ci)
-{
- ++(*this->chanaccess)[ci];
-}
-
-void NickCore::RemoveChannelReference(ChannelInfo *ci)
-{
- int& i = (*this->chanaccess)[ci];
- if (--i <= 0)
- this->chanaccess->erase(ci);
-}
-
-void NickCore::GetChannelReferences(std::deque<ChannelInfo *> &queue)
-{
- queue.clear();
- for (std::map<ChannelInfo *, int>::iterator it = this->chanaccess->begin(), it_end = this->chanaccess->end(); it != it_end; ++it)
- queue.push_back(it->first);
-}
-
-NickCore* NickCore::Find(const Anope::string &nick)
-{
- nickcore_map::const_iterator it = NickCoreList->find(nick);
- if (it != NickCoreList->end())
- {
- it->second->QueueUpdate();
- return it->second;
- }
-
- return NULL;
-}
-
diff --git a/src/opertype.cpp b/src/opertype.cpp
index 9438c2ff5..91676bd84 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -1,9 +1,21 @@
/*
+ * Anope IRC Services
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -11,31 +23,83 @@
#include "opertype.h"
#include "config.h"
-std::vector<Oper *> Oper::opers;
+Anope::string Oper::GetName()
+{
+ return Get(&OperBlockType::name);
+}
-Oper::Oper(const Anope::string &n, OperType *o) : name(n), ot(o), require_oper(false)
+void Oper::SetName(const Anope::string &n)
{
- opers.push_back(this);
+ Set(&OperBlockType::name, n);
}
-Oper::~Oper()
+Anope::string Oper::GetPassword()
{
- std::vector<Oper *>::iterator it = std::find(opers.begin(), opers.end(), this);
- if (it != opers.end())
- opers.erase(it);
+ return Get(&OperBlockType::password);
}
-Oper *Oper::Find(const Anope::string &name)
+void Oper::SetPassword(const Anope::string &s)
{
- for (unsigned i = 0; i < opers.size(); ++i)
- {
- Oper *o = opers[i];
+ Set(&OperBlockType::password, s);
+}
- if (o->name.equals_ci(name))
+Anope::string Oper::GetCertFP()
+{
+ return Get(&OperBlockType::certfp);
+}
+
+void Oper::SetCertFP(const Anope::string &s)
+{
+ Set(&OperBlockType::certfp, s);
+}
+
+Anope::string Oper::GetHost()
+{
+ return Get(&OperBlockType::host);
+}
+
+void Oper::SetHost(const Anope::string &h)
+{
+ Set(&OperBlockType::host, h);
+}
+
+Anope::string Oper::GetVhost()
+{
+ return Get(&OperBlockType::vhost);
+}
+
+void Oper::SetVhost(const Anope::string &s)
+{
+ Set(&OperBlockType::vhost, s);
+}
+
+OperType *Oper::GetType()
+{
+ return OperType::Find(Get(&OperBlockType::type));
+}
+
+void Oper::SetType(OperType *t)
+{
+ Set(&OperBlockType::type, t->GetName());
+}
+
+bool Oper::GetRequireOper()
+{
+ return Get(&OperBlockType::require_oper);
+}
+
+void Oper::SetRequireOper(const bool &b)
+{
+ Set(&OperBlockType::require_oper, b);
+}
+
+Oper *Oper::Find(const Anope::string &name)
+{
+ for (Oper *o : Serialize::GetObjects<Oper *>())
+ if (o->GetName() == name)
return o;
- }
- return NULL;
+ return nullptr;
}
OperType *OperType::Find(const Anope::string &name)
diff --git a/src/pipeengine.cpp b/src/pipeengine.cpp
index 0953387c1..1a133641f 100644
--- a/src/pipeengine.cpp
+++ b/src/pipeengine.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -48,10 +56,11 @@ Pipe::~Pipe()
bool Pipe::ProcessRead()
{
+ char dummy[512];
+ while (read(this->GetFD(), dummy, sizeof(dummy)) == sizeof(dummy));
+
this->OnNotify();
- char dummy[512];
- while (read(this->GetFD(), dummy, 512) == 512);
return true;
}
@@ -76,6 +85,6 @@ bool Pipe::SetWriteBlocking(bool state)
void Pipe::Notify()
{
- this->Write("\0", 1);
+ this->Write("", 1);
}
diff --git a/src/process.cpp b/src/process.cpp
index b095ab40b..356a3b695 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -1,12 +1,20 @@
-/* Main processing code for Services.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -14,7 +22,7 @@
#include "protocol.h"
#include "servers.h"
#include "users.h"
-#include "regchannel.h"
+#include "event.h"
void Anope::Process(const Anope::string &buffer)
{
@@ -50,13 +58,10 @@ void Anope::Process(const Anope::string &buffer)
static const Anope::string proto_name = ModuleManager::FindFirstOf(PROTOCOL) ? ModuleManager::FindFirstOf(PROTOCOL)->name : "";
MessageSource src(source);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnMessage, MOD_RESULT, (src, command, params));
- if (MOD_RESULT == EVENT_STOP)
- return;
- ServiceReference<IRCDMessage> m("IRCDMessage", proto_name + "/" + command.lower());
+ EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::Message::OnMessage, src, command, params);
+
+ ServiceReference<IRCDMessage> m(proto_name + "/" + command.lower());
if (!m)
{
Log(LOG_DEBUG) << "unknown message from server (" << buffer << ")";
@@ -100,11 +105,26 @@ void IRCDProto::Parse(const Anope::string &buffer, Anope::string &source, Anope:
}
}
-Anope::string IRCDProto::Format(const Anope::string &source, const Anope::string &message)
+Anope::string IRCDProto::Format(IRCMessage &message)
{
+ std::stringstream buffer;
+
+ const Anope::string &source = message.GetSource().GetUID();
if (!source.empty())
- return ":" + source + " " + message;
- else
- return message;
+ buffer << ":" << source << " ";
+
+ buffer << message.GetCommand();
+
+ for (unsigned int i = 0; i < message.GetParameters().size(); ++i)
+ {
+ buffer << " ";
+
+ if (i + 1 == message.GetParameters().size())
+ buffer << ":";
+
+ buffer << message.GetParameters()[i];
+ }
+
+ return buffer.str();
}
diff --git a/src/protocol.cpp b/src/protocol.cpp
index c8320e25a..c5b555cad 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -80,7 +88,7 @@ Anope::string IRCDProto::SID_Retrieve()
if (!IRCD || !IRCD->RequiresID)
return "";
- static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<const Anope::string>("id");
+ static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<Anope::string>("id");
if (current_sid.empty())
current_sid = "00A";
@@ -96,61 +104,65 @@ Anope::string IRCDProto::SID_Retrieve()
void IRCDProto::SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
{
- UplinkSocket::Message(source) << "KILL " << target << " :" << reason;
+ Uplink::Send(source, "KILL", target, reason);
}
void IRCDProto::SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf)
{
- UplinkSocket::Message(source) << "KILL " << user->GetUID() << " :" << buf;
+ Uplink::Send(source, "KILL", user->GetUID(), buf);
}
void IRCDProto::SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf)
{
- UplinkSocket::Message(source) << "MODE " << dest->name << " " << buf;
+ IRCMessage message(source, "MODE", dest->name);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
void IRCDProto::SendModeInternal(const MessageSource &source, User *dest, const Anope::string &buf)
{
- UplinkSocket::Message(source) << "MODE " << dest->GetUID() << " " << buf;
+ IRCMessage message(source, "MODE", dest->GetUID());
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
void IRCDProto::SendKickInternal(const MessageSource &source, const Channel *c, User *u, const Anope::string &r)
{
if (!r.empty())
- UplinkSocket::Message(source) << "KICK " << c->name << " " << u->GetUID() << " :" << r;
+ Uplink::Send(source, "KICK", c->name, u->GetUID(), r);
else
- UplinkSocket::Message(source) << "KICK " << c->name << " " << u->GetUID();
+ Uplink::Send(source, "KICK", c->name, u->GetUID());
}
void IRCDProto::SendNoticeInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &msg)
{
- UplinkSocket::Message(source) << "NOTICE " << dest << " :" << msg;
+ Uplink::Send(source, "NOTICE", dest, msg);
}
void IRCDProto::SendPrivmsgInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &buf)
{
- UplinkSocket::Message(source) << "PRIVMSG " << dest << " :" << buf;
+ Uplink::Send(source, "PRIVMSG", dest, buf);
}
void IRCDProto::SendQuitInternal(User *u, const Anope::string &buf)
{
if (!buf.empty())
- UplinkSocket::Message(u) << "QUIT :" << buf;
+ Uplink::Send(u, "QUIT", buf);
else
- UplinkSocket::Message(u) << "QUIT";
+ Uplink::Send(u, "QUIT");
}
void IRCDProto::SendPartInternal(User *u, const Channel *chan, const Anope::string &buf)
{
if (!buf.empty())
- UplinkSocket::Message(u) << "PART " << chan->name << " :" << buf;
+ Uplink::Send(u, "PART", chan->name, buf);
else
- UplinkSocket::Message(u) << "PART " << chan->name;
+ Uplink::Send(u, "PART", chan->name);
}
void IRCDProto::SendGlobopsInternal(const MessageSource &source, const Anope::string &buf)
{
- UplinkSocket::Message(source) << "GLOBOPS :" << buf;
+ Uplink::Send(source, "GLOBOPS", buf);
}
void IRCDProto::SendCTCPInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &buf)
@@ -166,12 +178,15 @@ void IRCDProto::SendNumericInternal(int numeric, const Anope::string &dest, cons
n = "0" + n;
if (numeric < 100)
n = "0" + n;
- UplinkSocket::Message(Me) << n << " " << dest << " " << buf;
+
+ IRCMessage message(Me, n, dest);
+ message.TokenizeAndPush(buf);
+ Uplink::SendMessage(message);
}
void IRCDProto::SendTopic(const MessageSource &source, Channel *c)
{
- UplinkSocket::Message(source) << "TOPIC " << c->name << " :" << c->topic;
+ Uplink::Send(source, "TOPIC", c->name, c->topic);
}
void IRCDProto::SendSVSKill(const MessageSource &source, User *user, const char *fmt, ...)
@@ -264,28 +279,22 @@ void IRCDProto::SendQuit(User *u, const char *fmt, ...)
void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who)
{
if (servname.empty())
- UplinkSocket::Message(Me) << "PING " << who;
+ Uplink::Send(Me, "PING", who);
else
- UplinkSocket::Message(Me) << "PING " << servname << " " << who;
+ Uplink::Send(Me, "PING", servname, who);
}
-/**
- * Send a PONG reply to a received PING.
- * servname should be left NULL to send a one param reply.
- * @param servname Daemon or client that is responding to the PING.
- * @param who Origin of the PING and destination of the PONG message.
- **/
void IRCDProto::SendPong(const Anope::string &servname, const Anope::string &who)
{
if (servname.empty())
- UplinkSocket::Message(Me) << "PONG " << who;
+ Uplink::Send(Me, "PONG", who);
else
- UplinkSocket::Message(Me) << "PONG " << servname << " " << who;
+ Uplink::Send(Me, "PONG", servname, who);
}
void IRCDProto::SendInvite(const MessageSource &source, const Channel *c, User *u)
{
- UplinkSocket::Message(source) << "INVITE " << u->GetUID() << " " << c->name;
+ Uplink::Send(source, "INVITE", u->GetUID(), c->name);
}
void IRCDProto::SendPart(User *user, const Channel *chan, const char *fmt, ...)
@@ -315,17 +324,17 @@ void IRCDProto::SendGlobops(const MessageSource &source, const char *fmt, ...)
void IRCDProto::SendSquit(Server *s, const Anope::string &message)
{
- UplinkSocket::Message() << "SQUIT " << s->GetSID() << " :" << message;
+ Uplink::Send("SQUIT", s->GetSID(), message);
}
void IRCDProto::SendNickChange(User *u, const Anope::string &newnick)
{
- UplinkSocket::Message(u) << "NICK " << newnick << " " << Anope::CurTime;
+ Uplink::Send(u, "NICK", newnick, Anope::CurTime);
}
void IRCDProto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
{
- UplinkSocket::Message() << "SVSNICK " << u->GetUID() << " " << newnick << " " << when;
+ Uplink::Send(u, "SVSNICK", u->GetUID(), newnick, when);
}
void IRCDProto::SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...)
@@ -360,16 +369,16 @@ bool IRCDProto::IsNickValid(const Anope::string &nick)
if (nick.empty())
return false;
-
+
Anope::string special = "[]\\`_^{|}";
-
+
for (unsigned i = 0; i < nick.length(); ++i)
if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z')
&& special.find(nick[i]) == Anope::string::npos
&& (Config && Config->NickChars.find(nick[i]) == Anope::string::npos)
&& (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-')))
return false;
-
+
return true;
}
@@ -407,8 +416,8 @@ bool IRCDProto::IsHostValid(const Anope::string &host)
if (host.empty() || host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
return false;
- const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<const Anope::string>("disallow_start_or_end"),
- vhostchars = Config->GetBlock("networkinfo")->Get<const Anope::string>("vhost_chars");
+ const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<Anope::string>("disallow_start_or_end"),
+ vhostchars = Config->GetBlock("networkinfo")->Get<Anope::string>("vhost_chars");
if (vhostdisablebe.find_first_of(host[0]) != Anope::string::npos)
return false;
@@ -474,6 +483,15 @@ const Anope::string &MessageSource::GetName() const
return this->source;
}
+const Anope::string &MessageSource::GetUID() const
+{
+ if (this->s)
+ return this->s->GetSID();
+ if (this->u)
+ return this->u->GetUID();
+ return this->source;
+}
+
const Anope::string &MessageSource::GetSource() const
{
return this->source;
@@ -484,9 +502,9 @@ User *MessageSource::GetUser() const
return this->u;
}
-BotInfo *MessageSource::GetBot() const
+ServiceBot *MessageSource::GetBot() const
{
- return BotInfo::Find(this->GetName(), true);
+ return ServiceBot::Find(this->GetName(), true);
}
Server *MessageSource::GetServer() const
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
deleted file mode 100644
index 356ceb093..000000000
--- a/src/regchannel.cpp
+++ /dev/null
@@ -1,695 +0,0 @@
-/* Registered channel functions
- *
- * (C) 2003-2016 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 "services.h"
-#include "modules.h"
-#include "regchannel.h"
-#include "account.h"
-#include "access.h"
-#include "channels.h"
-#include "config.h"
-#include "bots.h"
-#include "servers.h"
-
-Serialize::Checker<registered_channel_map> RegisteredChannelList("ChannelInfo");
-
-AutoKick::AutoKick() : Serializable("AutoKick")
-{
-}
-
-AutoKick::~AutoKick()
-{
- if (this->ci)
- {
- std::vector<AutoKick *>::iterator it = std::find(this->ci->akick->begin(), this->ci->akick->end(), this);
- if (it != this->ci->akick->end())
- this->ci->akick->erase(it);
-
- const NickAlias *na = NickAlias::Find(this->mask);
- if (na != NULL)
- na->nc->RemoveChannelReference(this->ci);
- }
-}
-
-void AutoKick::Serialize(Serialize::Data &data) const
-{
- data["ci"] << this->ci->name;
- if (this->nc)
- data["nc"] << this->nc->display;
- else
- data["mask"] << this->mask;
- data["reason"] << this->reason;
- data["creator"] << this->creator;
- data.SetType("addtime", Serialize::Data::DT_INT); data["addtime"] << this->addtime;
- data.SetType("last_used", Serialize::Data::DT_INT); data["last_used"] << this->last_used;
-}
-
-Serializable* AutoKick::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci, snc;
-
- data["ci"] >> sci;
- data["nc"] >> snc;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- AutoKick *ak;
- NickCore *nc = NickCore::Find(snc);
- if (obj)
- {
- ak = anope_dynamic_static_cast<AutoKick *>(obj);
- data["creator"] >> ak->creator;
- data["reason"] >> ak->reason;
- ak->nc = NickCore::Find(snc);
- data["mask"] >> ak->mask;
- data["addtime"] >> ak->addtime;
- data["last_used"] >> ak->last_used;
- }
- else
- {
- time_t addtime, lastused;
- data["addtime"] >> addtime;
- data["last_used"] >> lastused;
-
- Anope::string screator, sreason, smask;
-
- data["creator"] >> screator;
- data["reason"] >> sreason;
- data["mask"] >> smask;
-
- if (nc)
- ak = ci->AddAkick(screator, nc, sreason, addtime, lastused);
- else
- ak = ci->AddAkick(screator, smask, sreason, addtime, lastused);
- }
-
- return ak;
-}
-
-ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInfo"),
- access("ChanAccess"), akick("AutoKick")
-{
- if (chname.empty())
- throw CoreException("Empty channel passed to ChannelInfo constructor");
-
- this->founder = NULL;
- this->successor = NULL;
- this->c = Channel::Find(chname);
- if (this->c)
- this->c->ci = this;
- this->banexpire = 0;
- this->bi = NULL;
- this->last_topic_time = 0;
-
- this->name = chname;
-
- this->bantype = 2;
- this->memos.memomax = 0;
- this->last_used = this->time_registered = Anope::CurTime;
-
- size_t old = RegisteredChannelList->size();
- (*RegisteredChannelList)[this->name] = this;
- if (old == RegisteredChannelList->size())
- Log(LOG_DEBUG) << "Duplicate channel " << this->name << " in registered channel table?";
-
- FOREACH_MOD(OnCreateChan, (this));
-}
-
-ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
- access("ChanAccess"), akick("AutoKick")
-{
- *this = ci;
-
- if (this->founder)
- ++this->founder->channelcount;
-
- this->access->clear();
- this->akick->clear();
-
- FOREACH_MOD(OnCreateChan, (this));
-}
-
-ChannelInfo::~ChannelInfo()
-{
- UnsetExtensibles();
-
- FOREACH_MOD(OnDelChan, (this));
-
- Log(LOG_DEBUG) << "Deleting channel " << this->name;
-
- if (this->c)
- {
- if (this->bi && this->c->FindUser(this->bi))
- this->bi->Part(this->c);
-
- /* Parting the service bot can cause the channel to go away */
-
- if (this->c)
- {
- if (this->c && this->c->CheckDelete())
- this->c->QueueForDeletion();
-
- this->c = NULL;
- }
- }
-
- RegisteredChannelList->erase(this->name);
-
- this->SetFounder(NULL);
- this->SetSuccessor(NULL);
-
- this->ClearAccess();
- this->ClearAkick();
-
- if (!this->memos.memos->empty())
- {
- for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i)
- delete this->memos.GetMemo(i);
- this->memos.memos->clear();
- }
-}
-
-void ChannelInfo::Serialize(Serialize::Data &data) const
-{
- data["name"] << this->name;
- if (this->founder)
- data["founder"] << this->founder->display;
- if (this->successor)
- data["successor"] << this->successor->display;
- data["description"] << this->desc;
- data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
- data.SetType("last_used", Serialize::Data::DT_INT); data["last_used"] << this->last_used;
- data["last_topic"] << this->last_topic;
- data["last_topic_setter"] << this->last_topic_setter;
- data.SetType("last_topic_time", Serialize::Data::DT_INT); data["last_topic_time"] << this->last_topic_time;
- data.SetType("bantype", Serialize::Data::DT_INT); data["bantype"] << this->bantype;
- {
- Anope::string levels_buffer;
- for (Anope::map<int16_t>::const_iterator it = this->levels.begin(), it_end = this->levels.end(); it != it_end; ++it)
- levels_buffer += it->first + " " + stringify(it->second) + " ";
- data["levels"] << levels_buffer;
- }
- if (this->bi)
- data["bi"] << this->bi->nick;
- data.SetType("banexpire", Serialize::Data::DT_INT); data["banexpire"] << this->banexpire;
- data["memomax"] << this->memos.memomax;
- for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
- data["memoignores"] << this->memos.ignores[i] << " ";
-
- Extensible::ExtensibleSerialize(this, this, data);
-}
-
-Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sname, sfounder, ssuccessor, slevels, sbi;
-
- data["name"] >> sname;
- data["founder"] >> sfounder;
- data["successor"] >> ssuccessor;
- data["levels"] >> slevels;
- data["bi"] >> sbi;
-
- ChannelInfo *ci;
- if (obj)
- ci = anope_dynamic_static_cast<ChannelInfo *>(obj);
- else
- ci = new ChannelInfo(sname);
-
- ci->SetFounder(NickCore::Find(sfounder));
- ci->SetSuccessor(NickCore::Find(ssuccessor));
-
- data["description"] >> ci->desc;
- data["time_registered"] >> ci->time_registered;
- data["last_used"] >> ci->last_used;
- data["last_topic"] >> ci->last_topic;
- data["last_topic_setter"] >> ci->last_topic_setter;
- data["last_topic_time"] >> ci->last_topic_time;
- data["bantype"] >> ci->bantype;
- {
- std::vector<Anope::string> v;
- spacesepstream(slevels).GetTokens(v);
- for (unsigned i = 0; i + 1 < v.size(); i += 2)
- try
- {
- ci->levels[v[i]] = convertTo<int16_t>(v[i + 1]);
- }
- catch (const ConvertException &) { }
- }
- BotInfo *bi = BotInfo::Find(sbi, true);
- if (*ci->bi != bi)
- {
- if (bi)
- bi->Assign(NULL, ci);
- else if (ci->bi)
- ci->bi->UnAssign(NULL, ci);
- }
- data["banexpire"] >> ci->banexpire;
- data["memomax"] >> ci->memos.memomax;
- {
- Anope::string buf;
- data["memoignores"] >> buf;
- spacesepstream sep(buf);
- ci->memos.ignores.clear();
- while (sep.GetToken(buf))
- ci->memos.ignores.push_back(buf);
- }
-
- Extensible::ExtensibleUnserialize(ci, ci, data);
-
- /* compat */
- bool b;
- b = false;
- data["extensible:SECURE"] >> b;
- if (b)
- ci->Extend<bool>("CS_SECURE");
- b = false;
- data["extensible:PRIVATE"] >> b;
- if (b)
- ci->Extend<bool>("CS_PRIVATE");
- b = false;
- data["extensible:NO_EXPIRE"] >> b;
- if (b)
- ci->Extend<bool>("CS_NO_EXPIRE");
- b = false;
- data["extensible:FANTASY"] >> b;
- if (b)
- ci->Extend<bool>("BS_FANTASY");
- b = false;
- data["extensible:GREET"] >> b;
- if (b)
- ci->Extend<bool>("BS_GREET");
- b = false;
- data["extensible:PEACE"] >> b;
- if (b)
- ci->Extend<bool>("PEACE");
- b = false;
- data["extensible:SECUREFOUNDER"] >> b;
- if (b)
- ci->Extend<bool>("SECUREFOUNDER");
- b = false;
- data["extensible:RESTRICTED"] >> b;
- if (b)
- ci->Extend<bool>("RESTRICTED");
- b = false;
- data["extensible:KEEPTOPIC"] >> b;
- if (b)
- ci->Extend<bool>("KEEPTOPIC");
- b = false;
- data["extensible:SIGNKICK"] >> b;
- if (b)
- ci->Extend<bool>("SIGNKICK");
- b = false;
- data["extensible:SIGNKICK_LEVEL"] >> b;
- if (b)
- ci->Extend<bool>("SIGNKICK_LEVEL");
- /* end compat */
-
- return ci;
-}
-
-
-void ChannelInfo::SetFounder(NickCore *nc)
-{
- if (this->founder)
- {
- --this->founder->channelcount;
- this->founder->RemoveChannelReference(this);
- }
-
- this->founder = nc;
-
- if (this->founder)
- {
- ++this->founder->channelcount;
- this->founder->AddChannelReference(this);
- }
-}
-
-NickCore *ChannelInfo::GetFounder() const
-{
- return this->founder;
-}
-
-void ChannelInfo::SetSuccessor(NickCore *nc)
-{
- if (this->successor)
- this->successor->RemoveChannelReference(this);
- this->successor = nc;
- if (this->successor)
- this->successor->AddChannelReference(this);
-}
-
-NickCore *ChannelInfo::GetSuccessor() const
-{
- return this->successor;
-}
-
-BotInfo *ChannelInfo::WhoSends() const
-{
- if (this && this->bi)
- return this->bi;
-
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- if (ChanServ)
- return ChanServ;
-
- if (!BotListByNick->empty())
- return BotListByNick->begin()->second;
-
- return NULL;
-}
-
-void ChannelInfo::AddAccess(ChanAccess *taccess)
-{
- this->access->push_back(taccess);
-}
-
-ChanAccess *ChannelInfo::GetAccess(unsigned index) const
-{
- if (this->access->empty() || index >= this->access->size())
- return NULL;
-
- ChanAccess *acc = (*this->access)[index];
- acc->QueueUpdate();
- return acc;
-}
-
-static void FindMatchesRecurse(ChannelInfo *ci, const User *u, const NickCore *account, unsigned int depth, std::vector<ChanAccess::Path> &paths, ChanAccess::Path &path)
-{
- if (depth > ChanAccess::MAX_DEPTH)
- return;
-
- for (unsigned int i = 0; i < ci->GetAccessCount(); ++i)
- {
- ChanAccess *a = ci->GetAccess(i);
- ChannelInfo *next = NULL;
-
- if (a->Matches(u, account, next))
- {
- ChanAccess::Path next_path = path;
- next_path.push_back(a);
-
- paths.push_back(next_path);
- }
- else if (next)
- {
- ChanAccess::Path next_path = path;
- next_path.push_back(a);
-
- FindMatchesRecurse(next, u, account, depth + 1, paths, next_path);
- }
- }
-}
-
-static void FindMatches(AccessGroup &group, ChannelInfo *ci, const User *u, const NickCore *account)
-{
- ChanAccess::Path path;
- FindMatchesRecurse(ci, u, account, 0, group.paths, path);
-}
-
-AccessGroup ChannelInfo::AccessFor(const User *u, bool updateLastUsed)
-{
- AccessGroup group;
-
- if (u == NULL)
- return group;
-
- const NickCore *nc = u->Account();
- if (nc == NULL && !this->HasExt("NS_SECURE") && u->IsRecognized())
- {
- const NickAlias *na = NickAlias::Find(u->nick);
- if (na != NULL)
- nc = na->nc;
- }
-
- group.super_admin = u->super_admin;
- group.founder = IsFounder(u, this);
- group.ci = this;
- group.nc = nc;
-
- FindMatches(group, this, u, u->Account());
-
- if (group.founder || !group.paths.empty())
- {
- if (updateLastUsed)
- this->last_used = Anope::CurTime;
-
- for (unsigned i = 0; i < group.paths.size(); ++i)
- {
- ChanAccess::Path &p = group.paths[i];
-
- for (unsigned int j = 0; j < p.size(); ++j)
- p[j]->last_seen = Anope::CurTime;
- }
- }
-
- return group;
-}
-
-AccessGroup ChannelInfo::AccessFor(const NickCore *nc, bool updateLastUsed)
-{
- AccessGroup group;
-
- group.founder = (this->founder && this->founder == nc);
- group.ci = this;
- group.nc = nc;
-
- FindMatches(group, this, NULL, nc);
-
- if (group.founder || !group.paths.empty())
- if (updateLastUsed)
- this->last_used = Anope::CurTime;
-
- /* don't update access last seen here, this isn't the user requesting access */
-
- return group;
-}
-
-unsigned ChannelInfo::GetAccessCount() const
-{
- return this->access->size();
-}
-
-static unsigned int GetDeepAccessCount(const ChannelInfo *ci, std::set<const ChannelInfo *> &seen, unsigned int depth)
-{
- if (depth > ChanAccess::MAX_DEPTH || seen.count(ci))
- return 0;
- seen.insert(ci);
-
- unsigned int total = 0;
-
- for (unsigned int i = 0; i < ci->GetAccessCount(); ++i)
- {
- ChanAccess::Path path;
- ChanAccess *a = ci->GetAccess(i);
- ChannelInfo *next = NULL;
-
- a->Matches(NULL, NULL, next);
- ++total;
-
- if (next)
- total += GetDeepAccessCount(ci, seen, depth + 1);
- }
-
- return total;
-}
-
-unsigned ChannelInfo::GetDeepAccessCount() const
-{
- std::set<const ChannelInfo *> seen;
- return ::GetDeepAccessCount(this, seen, 0);
-}
-
-ChanAccess *ChannelInfo::EraseAccess(unsigned index)
-{
- if (this->access->empty() || index >= this->access->size())
- return NULL;
-
- ChanAccess *ca = this->access->at(index);
- this->access->erase(this->access->begin() + index);
- return ca;
-}
-
-void ChannelInfo::ClearAccess()
-{
- for (unsigned i = this->access->size(); i > 0; --i)
- delete this->GetAccess(i - 1);
-}
-
-AutoKick *ChannelInfo::AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t, time_t lu)
-{
- AutoKick *autokick = new AutoKick();
- autokick->ci = this;
- autokick->nc = akicknc;
- autokick->reason = reason;
- autokick->creator = user;
- autokick->addtime = t;
- autokick->last_used = lu;
-
- this->akick->push_back(autokick);
-
- akicknc->AddChannelReference(this);
-
- return autokick;
-}
-
-AutoKick *ChannelInfo::AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t, time_t lu)
-{
- AutoKick *autokick = new AutoKick();
- autokick->ci = this;
- autokick->mask = mask;
- autokick->nc = NULL;
- autokick->reason = reason;
- autokick->creator = user;
- autokick->addtime = t;
- autokick->last_used = lu;
-
- this->akick->push_back(autokick);
-
- return autokick;
-}
-
-AutoKick *ChannelInfo::GetAkick(unsigned index) const
-{
- if (this->akick->empty() || index >= this->akick->size())
- return NULL;
-
- AutoKick *ak = (*this->akick)[index];
- ak->QueueUpdate();
- return ak;
-}
-
-unsigned ChannelInfo::GetAkickCount() const
-{
- return this->akick->size();
-}
-
-void ChannelInfo::EraseAkick(unsigned index)
-{
- if (this->akick->empty() || index >= this->akick->size())
- return;
-
- delete this->GetAkick(index);
-}
-
-void ChannelInfo::ClearAkick()
-{
- while (!this->akick->empty())
- delete this->akick->back();
-}
-
-const Anope::map<int16_t> &ChannelInfo::GetLevelEntries()
-{
- return this->levels;
-}
-
-int16_t ChannelInfo::GetLevel(const Anope::string &priv) const
-{
- if (PrivilegeManager::FindPrivilege(priv) == NULL)
- {
- Log(LOG_DEBUG) << "Unknown privilege " + priv;
- return ACCESS_INVALID;
- }
-
- Anope::map<int16_t>::const_iterator it = this->levels.find(priv);
- if (it == this->levels.end())
- return 0;
- return it->second;
-}
-
-void ChannelInfo::SetLevel(const Anope::string &priv, int16_t level)
-{
- if (PrivilegeManager::FindPrivilege(priv) == NULL)
- {
- Log(LOG_DEBUG) << "Unknown privilege " + priv;
- return;
- }
-
- this->levels[priv] = level;
-}
-
-void ChannelInfo::RemoveLevel(const Anope::string &priv)
-{
- this->levels.erase(priv);
-}
-
-void ChannelInfo::ClearLevels()
-{
- this->levels.clear();
-}
-
-Anope::string ChannelInfo::GetIdealBan(User *u) const
-{
- int bt = this ? this->bantype : -1;
- switch (bt)
- {
- case 0:
- return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
- case 1:
- if (u->GetVIdent()[0] == '~')
- return "*!*" + u->GetVIdent() + "@" + u->GetDisplayedHost();
- else
- return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
- case 3:
- return "*!" + u->Mask();
- case 2:
- default:
- return "*!*@" + u->GetDisplayedHost();
- }
-}
-
-ChannelInfo* ChannelInfo::Find(const Anope::string &name)
-{
- registered_channel_map::const_iterator it = RegisteredChannelList->find(name);
- if (it != RegisteredChannelList->end())
- {
- it->second->QueueUpdate();
- return it->second;
- }
-
- return NULL;
-}
-
-bool IsFounder(const User *user, const ChannelInfo *ci)
-{
- if (!user || !ci)
- return false;
-
- if (user->super_admin)
- return true;
-
- if (user->Account() && user->Account() == ci->GetFounder())
- return true;
-
- return false;
-}
-
-
-void ChannelInfo::AddChannelReference(const Anope::string &what)
-{
- ++references[what];
-}
-
-void ChannelInfo::RemoveChannelReference(const Anope::string &what)
-{
- int &i = references[what];
- if (--i <= 0)
- references.erase(what);
-}
-
-void ChannelInfo::GetChannelReferences(std::deque<Anope::string> &chans)
-{
- chans.clear();
- for (Anope::map<int>::iterator it = references.begin(); it != references.end(); ++it)
- chans.push_back(it->first);
-}
diff --git a/src/serialize.cpp b/src/serialize.cpp
index 3c54b933d..099151191 100644
--- a/src/serialize.cpp
+++ b/src/serialize.cpp
@@ -1,178 +1,318 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "anope.h"
#include "serialize.h"
#include "modules.h"
-#include "account.h"
-#include "bots.h"
-#include "regchannel.h"
-#include "xline.h"
-#include "access.h"
+#include "event.h"
using namespace Serialize;
-std::vector<Anope::string> Type::TypeOrder;
-std::map<Anope::string, Type *> Serialize::Type::Types;
-std::list<Serializable *> *Serializable::SerializableItems;
+std::unordered_map<ID, Object *> Serialize::objects;
-void Serialize::RegisterTypes()
-{
- static Type nc("NickCore", NickCore::Unserialize), na("NickAlias", NickAlias::Unserialize), bi("BotInfo", BotInfo::Unserialize),
- ci("ChannelInfo", ChannelInfo::Unserialize), access("ChanAccess", ChanAccess::Unserialize),
- akick("AutoKick", AutoKick::Unserialize), memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize);
-}
+std::vector<FieldBase *> Serialize::serializableFields;
+
+std::multimap<Anope::string, Anope::string> Serialize::child_types;
-void Serialize::CheckTypes()
+static ID curid;
+
+
+Object *Serialize::GetID(ID id)
{
- for (std::map<Anope::string, Serialize::Type *>::const_iterator it = Serialize::Type::GetTypes().begin(), it_end = Serialize::Type::GetTypes().end(); it != it_end; ++it)
- {
- Serialize::Type *t = it->second;
- t->Check();
- }
+ auto it = objects.find(id);
+ if (it != objects.end())
+ return it->second;
+ return nullptr;
}
-Serializable::Serializable(const Anope::string &serialize_type) : last_commit(0), last_commit_time(0), id(0), redis_ignore(0)
+void Serialize::Clear()
{
- if (SerializableItems == NULL)
- SerializableItems = new std::list<Serializable *>();
- SerializableItems->push_back(this);
+ std::unordered_map<ID, Object *> o;
+ objects.swap(o);
- this->s_type = Type::Find(serialize_type);
+ for (const std::pair<ID, Object *> &p : o)
+ delete p.second;
+}
- this->s_iter = SerializableItems->end();
- --this->s_iter;
+void Serialize::Unregister(Module *m)
+{
+ for (TypeBase *s : ServiceManager::Get()->FindServices<Serialize::TypeBase *>())
+ if (s->GetOwner() == m)
+ s->Unregister();
- FOREACH_MOD(OnSerializableConstruct, (this));
+ for (FieldBase *field : serializableFields)
+ if (field->GetOwner() == m)
+ field->Unregister();
}
-Serializable::Serializable(const Serializable &other) : last_commit(0), last_commit_time(0), id(0), redis_ignore(0)
+std::vector<Edge> Object::GetRefs(TypeBase *type)
{
- SerializableItems->push_back(this);
- this->s_iter = SerializableItems->end();
- --this->s_iter;
+ std::vector<Edge> refs;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeGetRefs, this, type, refs);
+ if (result == EVENT_ALLOW)
+ return refs;
- this->s_type = other.s_type;
+ if (type == nullptr)
+ {
+ refs.clear();
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : edges)
+ {
+ const std::vector<Edge> &e = p.second;
+ refs.insert(refs.end(), e.begin(), e.end());
+ }
+ return refs;
+ }
- FOREACH_MOD(OnSerializableConstruct, (this));
+ auto it = edges.find(type);
+ if (it != edges.end())
+ return it->second;
+ return std::vector<Edge>();
}
-Serializable::~Serializable()
+Object::Object(TypeBase *type)
{
- FOREACH_MOD(OnSerializableDestruct, (this));
+ ID i;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializableGetId, i);
+ if (result != EVENT_ALLOW)
+ {
+ while (GetID(++curid));
+ i = curid;
+ }
+
+ id = i;
+ objects[id] = this;
+
+ this->s_type = type;
+
+ type->objects.insert(this);
+
+ Log(LOG_DEBUG_2) << "Creating object id #" << id << " address " << static_cast<void *>(this) << " type " << type->GetName();
- SerializableItems->erase(this->s_iter);
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializableCreate, this);
}
-Serializable &Serializable::operator=(const Serializable &)
+Object::Object(TypeBase *type, ID i)
{
- return *this;
+ this->id = i;
+ objects[i] = this;
+
+ this->s_type = type;
+
+ type->objects.insert(this);
+
+ Log(LOG_DEBUG_2) << "Creating object from id #" << id << " address " << static_cast<void *>(this) << " type " << type->GetName();
}
-void Serializable::QueueUpdate()
+Object::~Object()
{
- /* Schedule updater */
- FOREACH_MOD(OnSerializableUpdate, (this));
+ Log(LOG_DEBUG_2) << "Destructing object id #" << id << " address " << static_cast<void *>(this) << " type " << s_type->GetName();
- /* Check for modifications now - this can delete this object! */
- FOREACH_MOD(OnSerializeCheck, (this->GetSerializableType()));
+ /* Remove in memory edges */
+ cont:
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : edges)
+ for (const Edge &edge : p.second)
+ {
+ if (!edge.direction)
+ {
+ Log(LOG_DEBUG_2) << "Removing edge from object id #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName() << " on field " << edge.field->serialize_name;
+ edge.other->RemoveEdge(this, edge.field);
+ }
+ else
+ {
+ Log(LOG_DEBUG_2) << "Removing edge to object id #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName() << " on field " << edge.field->serialize_name;
+ this->RemoveEdge(edge.other, edge.field);
+ }
+ goto cont;
+ }
+
+ objects.erase(id);
+ s_type->objects.erase(this);
}
-bool Serializable::IsCached(Serialize::Data &data)
+void Object::Delete()
{
- return this->last_commit == data.Hash();
+ Log(LOG_DEBUG_2) << "Deleting object id #" << id << " type " << s_type->GetName();
+
+ /* Delete dependant objects */
+ for (const Edge &edge : GetRefs(nullptr))
+ {
+ Object *other = edge.other;
+ FieldBase *field = edge.field;
+
+ if (edge.direction)
+ continue;
+
+ if (field->depends)
+ {
+ Log(LOG_DEBUG_2) << "Deleting dependent object #" << other->id << " type " << other->GetSerializableType()->GetName() << " due to edge on " << field->serialize_name;
+ other->Delete();
+ }
+ else
+ {
+ Log(LOG_DEBUG_2) << "Unsetting field " << field->serialize_name << " on object #" << other->id << " type " << other->GetSerializableType()->GetName();
+ field->UnsetS(other);
+ }
+ }
+
+ EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializableDelete, this);
+
+ delete this;
}
-void Serializable::UpdateCache(Serialize::Data &data)
+void Object::AddEdge(Object *other, FieldBase *field)
{
- this->last_commit = data.Hash();
+ // field = the field on 'this' object
+ this->edges[other->GetSerializableType()].emplace_back(other, field, true);
+ // field = the field on the other object
+ other->edges[this->GetSerializableType()].emplace_back(this, field, false);
}
-bool Serializable::IsTSCached()
+void Object::RemoveEdge(Object *other, FieldBase *field)
{
- return this->last_commit_time == Anope::CurTime;
+ std::vector<Edge> &myedges = this->edges[other->GetSerializableType()];
+ auto it = std::find(myedges.begin(), myedges.end(), Edge(other, field, true));
+ if (it != myedges.end())
+ myedges.erase(it);
+ else
+ Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " -> #" << other->id << " type " << other->GetSerializableType()->GetName();
+
+ std::vector<Edge> &theiredges = other->edges[this->GetSerializableType()];
+ it = std::find(theiredges.begin(), theiredges.end(), Edge(this, field, false));
+ if (it != theiredges.end())
+ theiredges.erase(it);
+ else
+ Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " <- #" << other->id << " type " << other->GetSerializableType()->GetName();
}
-void Serializable::UpdateTS()
+TypeBase::TypeBase(Module *o, const Anope::string &n) : Service(o, TypeBase::NAME, n), name(n), owner(o)
{
- this->last_commit_time = Anope::CurTime;
}
-const std::list<Serializable *> &Serializable::GetItems()
+TypeBase::~TypeBase()
{
- return *SerializableItems;
+ if (!Serialize::GetObjects<Object *>(this->GetName()).empty())
+ throw CoreException("Type destructing with objects still alive");
}
-Type::Type(const Anope::string &n, unserialize_func f, Module *o) : name(n), unserialize(f), owner(o), timestamp(0)
+void TypeBase::Unregister()
{
- TypeOrder.push_back(this->name);
- Types[this->name] = this;
+ Log(LOG_DEBUG_2) << "Unregistering type " << this->GetName();
- FOREACH_MOD(OnSerializeTypeCreate, (this));
+ for (Object *obj : GetObjects<Object *>(this->GetName()))
+ obj->Delete();
+
+ for (FieldBase *field : serializableFields)
+ {
+ if (field->serialize_type == this->GetName())
+ {
+ field->Unregister();
+ }
+ }
}
-Type::~Type()
+Serialize::FieldBase *TypeBase::GetField(const Anope::string &fname)
{
- /* null the type of existing serializable objects of this type */
- if (Serializable::SerializableItems != NULL)
- for (std::list<Serializable *>::iterator it = Serializable::SerializableItems->begin(); it != Serializable::SerializableItems->end(); ++it)
- {
- Serializable *s = *it;
+ /* is this too slow? */
+ for (FieldBase *fb : ServiceManager::Get()->FindServices<FieldBase *>())
+ if (fb->serialize_type == this->GetName() && fb->serialize_name == fname)
+ return fb;
- if (s->s_type == this)
- s->s_type = NULL;
- }
+ Log(LOG_DEBUG_2) << "GetField() for unknown field " << fname << " on " << this->GetName();
- std::vector<Anope::string>::iterator it = std::find(TypeOrder.begin(), TypeOrder.end(), this->name);
- if (it != TypeOrder.end())
- TypeOrder.erase(it);
- Types.erase(this->name);
+ return nullptr;
}
-Serializable *Type::Unserialize(Serializable *obj, Serialize::Data &data)
+std::vector<Serialize::FieldBase *> TypeBase::GetFields()
{
- return this->unserialize(obj, data);
+ std::vector<Serialize::FieldBase *> fields;
+
+ for (FieldBase *fb : ServiceManager::Get()->FindServices<FieldBase *>())
+ if (fb->serialize_type == this->GetName())
+ fields.push_back(fb);
+
+ return fields;
}
-void Type::Check()
+TypeBase *TypeBase::Find(const Anope::string &name)
{
- FOREACH_MOD(OnSerializeCheck, (this));
+ return ServiceManager::Get()->FindService<TypeBase *>(name);
}
-time_t Type::GetTimestamp() const
+FieldBase::FieldBase(Module *c, const Anope::string &n, const Anope::string &t, bool d)
+ : Service(c, FieldBase::NAME)
+ , serialize_type(t)
+ , serialize_name(n)
+ , depends(d)
{
- return this->timestamp;
+ serializableFields.push_back(this);
}
-void Type::UpdateTimestamp()
+FieldBase::~FieldBase()
{
- this->timestamp = Anope::CurTime;
+ auto it = std::find(serializableFields.begin(), serializableFields.end(), this);
+ if (it != serializableFields.end())
+ serializableFields.erase(it);
}
-Type *Serialize::Type::Find(const Anope::string &name)
+void FieldBase::Unregister()
{
- std::map<Anope::string, Type *>::iterator it = Types.find(name);
- if (it != Types.end())
- return it->second;
- return NULL;
+ Log(LOG_DEBUG_2) << "Unregistering field " << serialize_name << " on " << serialize_type;
+
+ /* find edges on this field */
+ for (Object *s : Serialize::GetObjects<Object *>(serialize_type))
+ {
+ for (const std::pair<TypeBase *, std::vector<Edge>> &p : s->edges)
+ for (const Edge &edge : p.second)
+ if (edge.direction && edge.field == this)
+ {
+ Log(LOG_DEBUG_2) << "Removing edge on #" << s->id << " type " << s->GetSerializableType()->GetName() << " -> #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName();
+ s->RemoveEdge(edge.other, edge.field);
+
+ goto cont;
+ }
+ cont:;
+ }
}
-const std::vector<Anope::string> &Type::GetTypeOrder()
+void Serialize::SetParent(const Anope::string &child, const Anope::string &parent)
{
- return TypeOrder;
+ child_types.insert(std::make_pair(parent, child));
}
-const std::map<Anope::string, Serialize::Type *>& Type::GetTypes()
+std::vector<Serialize::TypeBase *> Serialize::GetTypes(const Anope::string &name)
{
- return Types;
-}
+ std::vector<Serialize::TypeBase *> v;
+ Serialize::TypeBase *t = Serialize::TypeBase::Find(name);
+ if (t != nullptr)
+ v.push_back(t);
+ else
+ Log(LOG_DEBUG_2) << "GetTypes for unknown type " << name;
+
+ auto its = child_types.equal_range(name);
+ for (; its.first != its.second; ++its.first)
+ {
+ t = Serialize::TypeBase::Find(its.first->second);
+ if (t != nullptr)
+ v.push_back(t);
+ }
+
+ return v;
+}
diff --git a/src/servers.cpp b/src/servers.cpp
index b78cd19f7..5f48a5e7c 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -1,12 +1,20 @@
-/* Routines to maintain a list of connected servers
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2004-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -14,10 +22,11 @@
#include "xline.h"
#include "servers.h"
#include "bots.h"
-#include "regchannel.h"
#include "protocol.h"
#include "config.h"
#include "channels.h"
+#include "event.h"
+#include "modules/chanserv.h"
/* Anope */
Server *Me = NULL;
@@ -46,93 +55,10 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
/* Check to be sure this isn't a juped server */
if (Me == this->uplink && !juped)
- {
- /* Now do mode related stuff as we know what modes exist .. */
- for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- {
- BotInfo *bi = it->second;
- Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : IRCD->DefaultPseudoclientModes;
-
- bi->SetModesInternal(bi, modes.c_str());
- for (unsigned i = 0; i < bi->botchannels.size(); ++i)
- {
- size_t h = bi->botchannels[i].find('#');
- if (h == Anope::string::npos)
- continue;
- Anope::string chname = bi->botchannels[i].substr(h);
- Channel *c = Channel::Find(chname);
- if (c && c->FindUser(bi))
- {
- Anope::string want_modes = bi->botchannels[i].substr(0, h);
- for (unsigned j = 0; j < want_modes.length(); ++j)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
- if (cm == NULL)
- cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
- if (cm && cm->type == MODE_STATUS)
- {
- MessageSource ms = bi;
- c->SetModeInternal(ms, cm, bi->nick);
- }
- }
- }
- }
- }
-
- IRCD->SendBOB();
-
- for (unsigned i = 0; i < Me->GetLinks().size(); ++i)
- {
- Server *s = Me->GetLinks()[i];
-
- if (s->juped)
- IRCD->SendServer(s);
- }
-
- /* We make the bots go online */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
-
- BotInfo *bi = BotInfo::Find(u->GetUID());
- if (bi)
- {
- XLine x(bi->nick, "Reserved for services");
- IRCD->SendSQLine(NULL, &x);
- }
-
- IRCD->SendClientIntroduction(u);
- if (bi)
- bi->introduced = true;
- }
-
- for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
- {
- Channel *c = it->second;
-
- if (c->users.empty())
- IRCD->SendChannel(c);
- else
- for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit)
- IRCD->SendJoin(cit->second->user, c, &cit->second->status);
-
- for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName(it2->first);
- if (!cm || cm->type != MODE_LIST)
- continue;
- ModeManager::StackerAdd(c->ci->WhoSends(), c, cm, true, it2->second);
- }
-
- if (!c->topic.empty() && !c->topic_setter.empty())
- IRCD->SendTopic(c->ci->WhoSends(), c);
-
- c->syncing = true;
- }
- }
+ Burst();
}
- FOREACH_MOD(OnNewServer, (this));
+ EventManager::Get()->Dispatch(&Event::NewServer::OnNewServer, this);
}
Server::~Server()
@@ -157,7 +83,7 @@ Server::~Server()
for (unsigned i = this->links.size(); i > 0; --i)
this->links[i - 1]->Delete(this->quit_reason);
-
+
Servers::ByName.erase(this->name);
if (!this->sid.empty())
Servers::ByID.erase(this->sid);
@@ -167,10 +93,64 @@ void Server::Delete(const Anope::string &reason)
{
this->quit_reason = reason;
this->quitting = true;
- FOREACH_MOD(OnServerQuit, (this));
+ EventManager::Get()->Dispatch(&Event::ServerQuit::OnServerQuit, this);
delete this;
}
+void Server::Burst()
+{
+ IRCD->SendBOB();
+
+ for (unsigned i = 0; i < Me->GetLinks().size(); ++i)
+ {
+ Server *s = Me->GetLinks()[i];
+
+ if (s->juped)
+ IRCD->SendServer(s);
+ }
+
+ /* We make the bots go online */
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+
+ ServiceBot *bi = ServiceBot::Find(u->GetUID());
+ if (bi)
+ {
+ //XLine x(bi->nick, "Reserved for services");
+ //IRCD->SendSQLine(NULL, &x);
+ }
+
+ IRCD->SendClientIntroduction(u);
+ if (bi)
+ bi->introduced = true;
+ }
+
+ for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
+ {
+ Channel *c = it->second;
+
+ if (c->users.empty())
+ IRCD->SendChannel(c);
+ else
+ for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit)
+ IRCD->SendJoin(cit->second->user, c, &cit->second->status);
+
+ for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(it2->first);
+ if (!cm || cm->type != MODE_LIST)
+ continue;
+ ModeManager::StackerAdd(c->ci->WhoSends(), c, cm, true, it2->second);
+ }
+
+ if (!c->topic.empty() && !c->topic_setter.empty())
+ IRCD->SendTopic(c->ci->WhoSends(), c);
+
+ c->syncing = true;
+ }
+}
+
const Anope::string &Server::GetName() const
{
return this->name;
@@ -255,7 +235,7 @@ void Server::Sync(bool sync_links)
Log(this, "sync") << "is done syncing";
- FOREACH_MOD(OnServerSync, (this));
+ EventManager::Get()->Dispatch(&Event::ServerSync::OnServerSync, this);
if (sync_links && !this->links.empty())
{
@@ -267,7 +247,7 @@ void Server::Sync(bool sync_links)
if (me)
{
- FOREACH_MOD(OnPreUplinkSync, (this));
+ EventManager::Get()->Dispatch(&Event::PreUplinkSync::OnPreUplinkSync, this);
}
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
@@ -284,7 +264,7 @@ void Server::Sync(bool sync_links)
IRCD->SendEOB();
Me->Sync(false);
- FOREACH_MOD(OnUplinkSync, (this));
+ EventManager::Get()->Dispatch(&Event::UplinkSync::OnUplinkSync, this);
if (!Anope::NoFork)
{
@@ -325,7 +305,7 @@ bool Server::IsQuitting() const
return quitting;
}
-void Server::Notice(BotInfo *source, const Anope::string &message)
+void Server::Notice(ServiceBot *source, const Anope::string &message)
{
if (Config->UsePrivmsg && Config->DefPrivmsg)
IRCD->SendGlobalPrivmsg(source, this, message);
@@ -336,18 +316,18 @@ void Server::Notice(BotInfo *source, const Anope::string &message)
Server *Server::Find(const Anope::string &name, bool name_only)
{
Anope::map<Server *>::iterator it;
-
+
if (!name_only)
{
it = Servers::ByID.find(name);
if (it != Servers::ByID.end())
return it->second;
}
-
+
it = Servers::ByName.find(name);
if (it != Servers::ByName.end())
return it->second;
-
+
return NULL;
}
diff --git a/src/service.cpp b/src/service.cpp
new file mode 100644
index 000000000..9e99d0cad
--- /dev/null
+++ b/src/service.cpp
@@ -0,0 +1,67 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Adam <Adam@anope.org>
+ * Copyright (C) 2014-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "services.h"
+#include "service.h"
+#include "modules/nickserv.h"
+#include "modules/chanserv.h"
+#include "modules/memoserv.h"
+
+NickServ::NickServService *NickServ::service = nullptr;
+ChanServ::ChanServService *ChanServ::service = nullptr;
+MemoServ::MemoServService *MemoServ::service = nullptr;
+
+ServiceReferenceBase::ServiceReferenceBase(const Anope::string &_type, const Anope::string &_name) : type(_type), name(_name)
+{
+ ServiceManager::Get()->RegisterReference(this);
+}
+
+ServiceReferenceBase::ServiceReferenceBase(const Anope::string &_type) : ServiceReferenceBase(_type, "")
+{
+}
+
+ServiceReferenceBase::~ServiceReferenceBase()
+{
+ ServiceManager::Get()->UnregisterReference(this);
+}
+
+void ServiceReferenceBase::SetService(Service *service)
+{
+ if (service == nullptr)
+ this->services.clear();
+ else
+ this->services = { service };
+}
+
+void ServiceReferenceBase::SetServices(const std::vector<Service *> &s)
+{
+ this->services = s;
+}
+
+Service::Service(Module *o, const Anope::string &t, const Anope::string &n) : owner(o), type(t), name(n)
+{
+ ServiceManager::Get()->Register(this);
+}
+
+Service::~Service()
+{
+ ServiceManager::Get()->Unregister(this);
+}
+
diff --git a/src/service_manager.cpp b/src/service_manager.cpp
new file mode 100644
index 000000000..ef26fb13b
--- /dev/null
+++ b/src/service_manager.cpp
@@ -0,0 +1,138 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Adam <Adam@anope.org>
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "services.h"
+#include "service.h"
+#include "logger.h"
+
+ServiceManager *ServiceManager::manager = nullptr;
+
+void ServiceManager::Init()
+{
+ assert(manager == nullptr);
+ manager = new ServiceManager();
+}
+
+ServiceManager *ServiceManager::Get()
+{
+ return manager;
+}
+
+void ServiceManager::Destroy()
+{
+ delete manager;
+ manager = nullptr;
+}
+
+Service *ServiceManager::FindService(const Anope::string &name)
+{
+ for (Service *s : services)
+ if (s->GetName() == name)
+ return s;
+ return nullptr;
+}
+
+Service *ServiceManager::FindService(const Anope::string &type, const Anope::string &name)
+{
+ for (Service *s : services)
+ if (s->GetType() == type && s->GetName() == name)
+ return s;
+ return nullptr;
+}
+
+std::vector<Service *> ServiceManager::FindServices(const Anope::string &type)
+{
+ std::vector<Service *> v;
+
+ for (Service *s : services)
+ if (s->GetType() == type)
+ v.push_back(s);
+
+ return v;
+}
+
+void ServiceManager::Register(Service *service)
+{
+ // assert type
+ if (service->GetType().empty())
+ throw ModuleException("Service type must be non empty");
+
+ if (service->GetName().empty() == false)
+ {
+ Service *s = FindService(service->GetType(), service->GetName());
+
+ if (s != nullptr)
+ throw ModuleException("Service of type " + service->GetType() + " with name " + service->GetName() + " already exists");
+ }
+
+ Log(LOG_DEBUG_2) << "Service registered: " << service->GetType() << " " << service->GetName() << " address " << static_cast<void *>(this) << " by " << service->GetOwner();
+
+ services.push_back(service);
+
+ LookupAll();
+}
+
+void ServiceManager::Unregister(Service *service)
+{
+ Log(LOG_DEBUG_2) << "Service unregistered: " << service->GetType() << " " << service->GetName() << " address " << static_cast<void *>(service) << " by " << service->GetOwner();
+
+ auto it = std::find(services.begin(), services.end(), service);
+ if (it != services.end())
+ {
+ services.erase(it);
+
+ LookupAll();
+ }
+}
+
+void ServiceManager::Lookup(ServiceReferenceBase *reference)
+{
+ if (reference->GetName().empty())
+ {
+ std::vector<Service *> services = this->FindServices(reference->GetType());
+ Log(LOG_DEBUG_2) << "Service lookup " << static_cast<void *>(reference) << " type " << reference->GetType() << " name " << reference->GetName() << ": " << services.size() << " services";
+ reference->SetServices(services);
+ }
+ else
+ {
+ Service *service = this->FindService(reference->GetType(), reference->GetName());
+ Log(LOG_DEBUG_2) << "Service lookup " << static_cast<void *>(reference) << " type " << reference->GetType() << " name " << reference->GetName() << ": " << service;
+ reference->SetService(service);
+ }
+}
+
+void ServiceManager::LookupAll()
+{
+ for (ServiceReferenceBase *s : references)
+ Lookup(s);
+}
+
+void ServiceManager::RegisterReference(ServiceReferenceBase *reference)
+{
+ Lookup(reference);
+ this->references.push_back(reference);
+}
+
+void ServiceManager::UnregisterReference(ServiceReferenceBase *reference)
+{
+ auto it = std::find(this->references.begin(), this->references.end(), reference);
+ if (it != this->references.end())
+ this->references.erase(it);
+}
diff --git a/src/socket_clients.cpp b/src/socket_clients.cpp
index bb0618f31..278ba7c21 100644
--- a/src/socket_clients.cpp
+++ b/src/socket_clients.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
diff --git a/src/socket_transport.cpp b/src/socket_transport.cpp
index 070807264..2ffeadd03 100644
--- a/src/socket_transport.cpp
+++ b/src/socket_transport.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2011-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -32,7 +40,7 @@ bool BufferedSocket::ProcessRead()
return false;
if (len < 0)
return SocketEngine::IgnoreErrno();
-
+
tbuffer[len] = 0;
this->read_buffer.append(tbuffer);
this->recv_len = len;
@@ -130,7 +138,7 @@ bool BinarySocket::ProcessRead()
int len = this->io->Recv(this, tbuffer, sizeof(tbuffer));
if (len <= 0)
return false;
-
+
return this->Read(tbuffer, len);
}
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index f132ba2b9..3c0c22f40 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -1,6 +1,6 @@
/*
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -28,7 +28,7 @@ void SocketEngine::Init()
if (EngineHandle == -1)
throw SocketException("Could not initialize epoll socket engine: " + Anope::LastError());
-
+
events.resize(DefaultSize);
}
@@ -46,7 +46,7 @@ void SocketEngine::Change(Socket *s, bool set, SocketFlag flag)
bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE];
s->flags[flag] = set;
-
+
bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE];
epoll_event ev;
@@ -65,7 +65,7 @@ void SocketEngine::Change(Socket *s, bool set, SocketFlag flag)
mod = EPOLL_CTL_MOD;
else
return;
-
+
if (epoll_ctl(EngineHandle, mod, ev.data.fd, &ev) == -1)
throw SocketException("Unable to epoll_ctl() fd " + stringify(ev.data.fd) + " to epoll: " + Anope::LastError());
}
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index 9ccf128d5..5c5c99afe 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -1,6 +1,6 @@
/*
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -39,7 +39,7 @@ void SocketEngine::Init()
if (kq_fd < 0)
throw SocketException("Unable to create kqueue engine: " + Anope::LastError());
-
+
change_events.resize(DefaultSize);
event_events.resize(DefaultSize);
}
@@ -56,7 +56,7 @@ void SocketEngine::Change(Socket *s, bool set, SocketFlag flag)
return;
s->flags[flag] = set;
-
+
int mod;
if (flag == SF_READABLE)
mod = EVFILT_READ;
diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp
index 8475dd414..422959df2 100644
--- a/src/socketengines/socketengine_poll.cpp
+++ b/src/socketengines/socketengine_poll.cpp
@@ -1,6 +1,6 @@
/*
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -113,7 +113,7 @@ void SocketEngine::Process()
for (unsigned i = 0, processed = 0; i < events.size() && processed != static_cast<unsigned>(total); ++i)
{
pollfd *ev = &events[i];
-
+
if (ev->revents != 0)
++processed;
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index 86b2085ea..f1f4fb8d8 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -1,6 +1,6 @@
/*
*
- * (C) 2003-2016 Anope Team
+ * (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -46,7 +46,7 @@ void SocketEngine::Change(Socket *s, bool set, SocketFlag flag)
bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE];
s->flags[flag] = set;
-
+
bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE];
if (!before_registered && now_registered)
diff --git a/src/sockets.cpp b/src/sockets.cpp
index f15f0ccbd..70c9fef0d 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -282,7 +290,7 @@ bool cidr::operator<(const cidr &other) const
{
if (this->addr.sa.sa_family != other.addr.sa.sa_family)
return this->addr.sa.sa_family < other.addr.sa.sa_family;
-
+
switch (this->addr.sa.sa_family)
{
case AF_INET:
diff --git a/src/threadengine.cpp b/src/threadengine.cpp
index f392ac472..bfd7605c3 100644
--- a/src/threadengine.cpp
+++ b/src/threadengine.cpp
@@ -1,48 +1,26 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "threadengine.h"
#include "anope.h"
-
-#ifndef _WIN32
-#include <pthread.h>
-#endif
-
-static inline pthread_attr_t *get_engine_attr()
-{
- /* Threadengine attributes used by this thread engine */
- static pthread_attr_t attr;
- static bool inited = false;
-
- if (inited == false)
- {
- if (pthread_attr_init(&attr))
- throw CoreException("Error calling pthread_attr_init");
- if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE))
- throw CoreException("Unable to mark threads as joinable");
- inited = true;
- }
-
- return &attr;
-}
-
-static void *entry_point(void *parameter)
-{
- Thread *thread = static_cast<Thread *>(parameter);
- thread->Run();
- thread->SetExitState();
- pthread_exit(0);
- return NULL;
-}
+#include <system_error>
Thread::Thread() : exit(false)
{
@@ -55,7 +33,15 @@ Thread::~Thread()
void Thread::Join()
{
this->SetExitState();
- pthread_join(handle, NULL);
+ try
+ {
+ if (this->handle.joinable())
+ this->handle.join();
+ }
+ catch (const std::system_error &error)
+ {
+ throw CoreException("Unable to join thread: " + Anope::string(error.what()));
+ }
}
void Thread::SetExitState()
@@ -64,18 +50,28 @@ void Thread::SetExitState()
exit = true;
}
-void Thread::Exit()
-{
- this->SetExitState();
- pthread_exit(0);
-}
-
void Thread::Start()
{
- if (pthread_create(&this->handle, get_engine_attr(), entry_point, this))
+ try
+ {
+ this->handle = std::thread([this]()
+ {
+ try
+ {
+ this->Run();
+ }
+ catch (...)
+ {
+ this->SetExitState();
+ throw;
+ }
+ this->SetExitState();
+ });
+ }
+ catch (const std::system_error &error)
{
this->flags[SF_DEAD] = true;
- throw CoreException("Unable to create thread: " + Anope::LastError());
+ throw CoreException("Unable to create thread: " + Anope::string(error.what()));
}
}
@@ -90,47 +86,28 @@ void Thread::OnNotify()
this->flags[SF_DEAD] = true;
}
-Mutex::Mutex()
-{
- pthread_mutex_init(&mutex, NULL);
-}
-
-Mutex::~Mutex()
-{
- pthread_mutex_destroy(&mutex);
-}
-
void Mutex::Lock()
{
- pthread_mutex_lock(&mutex);
-}
-
-void Mutex::Unlock()
-{
- pthread_mutex_unlock(&mutex);
+ this->m.lock();
}
bool Mutex::TryLock()
{
- return pthread_mutex_trylock(&mutex) == 0;
+ return this->m.try_lock();
}
-Condition::Condition() : Mutex()
+void Mutex::Unlock()
{
- pthread_cond_init(&cond, NULL);
+ this->m.unlock();
}
-Condition::~Condition()
+void Condition::Wait()
{
- pthread_cond_destroy(&cond);
+ this->cv.wait(this->m);
}
void Condition::Wakeup()
{
- pthread_cond_signal(&cond);
+ this->cv.notify_one();
}
-void Condition::Wait()
-{
- pthread_cond_wait(&cond, &mutex);
-}
diff --git a/src/timers.cpp b/src/timers.cpp
index a4538c05d..dd32a9395 100644
--- a/src/timers.cpp
+++ b/src/timers.cpp
@@ -1,9 +1,20 @@
-/* Timer stuff.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2009-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index ef2f3b15b..4d64f6fd9 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -1,6 +1,6 @@
# Find all the *.cpp files within the current source directory, and sort the list
file(GLOB TOOLS_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
-sort_list(TOOLS_SRCS)
+list(SORT TOOLS_SRCS)
# Set all the files to use C++ as well as set their compile flags
set_source_files_properties(${TOOLS_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
@@ -9,31 +9,19 @@ set_source_files_properties(${TOOLS_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS
foreach(SRC ${TOOLS_SRCS})
# Convert the source file extension to have no extension
string(REGEX REPLACE "\\.cpp$" "" EXE ${SRC})
- # Calculate the header file dependencies for the given source file
- calculate_depends(${SRC})
- # Only continue if this file isn't skipped
- if(NOT SKIP)
- # Generate the executable and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
- add_executable(${EXE} ${SRC})
- set_target_properties(${EXE} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}")
- add_dependencies(${EXE} ${PROGRAM_NAME})
- # Only for Windows, set anopesmtp to require the wsock32 library
- if(WIN32 AND ${EXE} STREQUAL anopesmtp)
- target_link_libraries(${EXE} wsock32)
- endif(WIN32 AND ${EXE} STREQUAL anopesmtp)
- if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" AND ${EXE} STREQUAL anopesmtp)
- target_link_libraries(${EXE} socket nsl)
- endif(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" AND ${EXE} STREQUAL anopesmtp)
- # Set the executable to be installed to the bin directory under the main directory
- install(TARGETS ${EXE}
- DESTINATION ${BIN_DIR}
- )
- # Add the executable to the list of files for CPack to ignore
- get_target_property(EXE_BINARY ${EXE} LOCATION)
- get_filename_component(EXE_BINARY ${EXE_BINARY} NAME)
- add_to_cpack_ignored_files("${EXE_BINARY}$" TRUE)
- endif(NOT SKIP)
-endforeach(SRC)
+ # Generate the executable and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
+ add_executable(${EXE} ${SRC})
+ set_target_properties(${EXE} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}")
+ add_dependencies(${EXE} ${PROGRAM_NAME})
+ # Set the executable to be installed to the bin directory under the main directory
+ install(TARGETS ${EXE}
+ DESTINATION ${BIN_DIR}
+ )
+ # Add the executable to the list of files for CPack to ignore
+ get_target_property(EXE_BINARY ${EXE} LOCATION)
+ get_filename_component(EXE_BINARY ${EXE_BINARY} NAME)
+ add_to_cpack_ignored_files("${EXE_BINARY}$" TRUE)
+endforeach()
# If not on Windows, generate anoperc and install it along with mydbgen
if(NOT WIN32)
@@ -44,9 +32,9 @@ if(NOT WIN32)
install (PROGRAMS geoipupdate.sh
DESTINATION ${BIN_DIR}
)
-endif(NOT WIN32)
+endif()
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the tools directory
if(NOT WIN32 AND RUNGROUP)
install(CODE "execute_process(COMMAND ${CHMOD} 2770 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin\")")
-endif(NOT WIN32 AND RUNGROUP)
+endif()
diff --git a/src/tools/anoperc.in b/src/tools/anoperc.in
index 2802e57e2..dce1e035e 100644
--- a/src/tools/anoperc.in
+++ b/src/tools/anoperc.in
@@ -2,7 +2,7 @@
#
# Configuration script for Services
#
-# (C) 2003-2016 Anope Team
+# (C) 2003-2014 Anope Team
# Contact us at team@anope.org
#
# Please read COPYING and README for further details.
@@ -14,8 +14,8 @@
-ANOPEPID="@INSTDIR@/data/services.pid"
-ANOPROG="@INSTDIR@/bin/services"
+ANOPEPID="@INSTDIR@/data/anope.pid"
+ANOPROG="@INSTDIR@/bin/anope"
LOG="@INSTDIR@/logs/"
ARCVERSION="2"
diff --git a/src/tools/anopesmtp.cpp b/src/tools/anopesmtp.cpp
deleted file mode 100644
index 392c6e627..000000000
--- a/src/tools/anopesmtp.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-/* smtp stuff handler for win32.
- *
- * (C) 2003-2016 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.
- *
- * Written by Dominick Meglio <codemastr@unrealircd.com>
- * *nix port by Trystan Scott Lee <trystan@nomadirc.net>
- */
-
-#include "sysconf.h"
-
-/* Some Linux boxes (or maybe glibc includes) require this for the
- * prototype of strsignal(). */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#include <string>
-#include <vector>
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <cerrno>
-#include <iostream>
-#include <fstream>
-
-#ifndef _WIN32
-# include <unistd.h>
-# include <netdb.h>
-# include <netinet/in.h>
-# include <sys/socket.h>
-# include <arpa/inet.h>
-# include <sys/time.h>
-#else
-# include <winsock.h>
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#endif
-
-#include <sys/types.h>
-
-#ifdef _AIX
-extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, size_t);
-# if 0 /* These break on some AIX boxes (4.3.1 reported). */
-extern int socket(int, int, int);
-extern int connect(int, struct sockaddr *, int);
-# endif
-#endif /* _AIX */
-
-/* Some SUN fixs */
-#ifdef __sun
-/* Solaris specific code, types that do not exist in Solaris'
- * * sys/types.h
- * **/
-# ifndef INADDR_NONE
-# define INADDR_NONE (-1)
-# endif
-#endif
-
-#ifdef _WIN32
-typedef SOCKET ano_socket_t;
-#define ano_sockclose(fd) closesocket(fd)
-#define ano_sockread(fd, buf, len) recv(fd, buf, len, 0)
-#define ano_sockwrite(fd, buf, len) send(fd, buf, len, 0)
-#else
-typedef int ano_socket_t;
-#define ano_sockclose(fd) close(fd)
-#define ano_sockread(fd, buf, len) read(fd, buf, len)
-#define ano_sockwrite(fd, buf, len) write(fd, buf, len)
-#define SOCKET_ERROR -1
-#endif
-
-/* Data structures */
-struct smtp_message
-{
- std::vector<std::string> smtp_headers;
- std::vector<std::string> smtp_body;
- std::string from;
- std::string to;
- ano_socket_t sock;
-};
-
-int smtp_debug = 0;
-
-struct smtp_message smail;
-
-static std::string get_logname(struct tm *tm = NULL)
-{
- char timestamp[32];
-
- if (!tm)
- {
- time_t t = time(NULL);
- tm = localtime(&t);
- }
-
- strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
- std::string name = std::string("anopesmtp.") + timestamp;
- return name;
-}
-
-/* Log stuff to the log file with a datestamp. Note that errno is
- * preserved by this routine and log_perror().
- */
-
-void alog(const char *fmt, ...)
-{
- if (!smtp_debug || !fmt)
- return;
-
- std::fstream file;
- file.open(get_logname().c_str(), std::ios_base::out | std::ios_base::app);
-
- if (!file.is_open())
- return;
-
- va_list args;
- va_start(args, fmt);
-
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
-
- char buf[256];
- strftime(buf, sizeof(buf) - 1, "[%b %d %H:%M:%S %Y] ", tm);
- file << buf;
- vsnprintf(buf, sizeof(buf), fmt, args);
- file << buf << std::endl;
- va_end(args);
- va_end(args);
-
- file.close();
-}
-
-/* Remove a trailing \r\n */
-std::string strip(const std::string &buf)
-{
- std::string newbuf = buf;
- char c = newbuf[newbuf.size() - 1];
- while (c == '\n' || c == '\r')
- {
- newbuf.erase(newbuf.end() - 1);
- c = newbuf[newbuf.size() - 1];
- }
- return newbuf;
-}
-
-/* Is the buffer a header? */
-bool smtp_is_header(const std::string &buf)
-{
- size_t tmp = buf.find(' ');
-
- if (tmp == std::string::npos)
- return false;
-
- if (tmp > 0 && buf[tmp - 1] == ':')
- return true;
- return false;
-}
-
-/* Parse a header into a name and value */
-void smtp_parse_header(const std::string &buf, std::string &header, std::string &value)
-{
- std::string newbuf = strip(buf);
-
- size_t space = newbuf.find(' ');
- if (space != std::string::npos)
- {
- header = newbuf.substr(0, space);
- value = newbuf.substr(space + 1);
- }
- else
- {
- header = newbuf;
- value = "";
- }
-}
-
-/* Have we reached the end of input? */
-bool smtp_is_end(const std::string &buf)
-{
- if (buf[0] == '.')
- if (buf[1] == '\r' || buf[1] == '\n')
- return true;
-
- return false;
-}
-
-/* Set who the email is to */
-void smtp_set_to(const std::string &to)
-{
- smail.to = to;
- size_t c = smail.to.rfind('<');
- if (c != std::string::npos && c + 1 < smail.to.size())
- {
- smail.to = smail.to.substr(c + 1);
- smail.to.erase(smail.to.end() - 1);
- }
-}
-
-/* Establish a connection to the SMTP server */
-int smtp_connect(const char *host, unsigned short port)
-{
- struct sockaddr_in addr;
-
- if ((smail.sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
- return 0;
-
- if ((addr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
- {
- struct hostent *hent;
- if (!(hent = gethostbyname(host)))
- return 0;
- memcpy(&addr.sin_addr, hent->h_addr, hent->h_length);
- }
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port ? port : 25);
- if (connect(smail.sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_in)) == SOCKET_ERROR)
- {
- ano_sockclose(smail.sock);
- return 0;
- }
-
- return 1;
-}
-
-/* Send a line of text */
-int smtp_send(const char *text)
-{
- int result = ano_sockwrite(smail.sock, text, strlen(text));
-
- alog("SMTP: sent %s",text);
-
- if (result == SOCKET_ERROR)
- ano_sockclose(smail.sock);
-
- return result;
-}
-
-/* Read a line of text */
-int smtp_read(char *buf, int len)
-{
- int result;
-
- memset(buf, 0, len);
- result = ano_sockread(smail.sock, buf, len);
-
- if (result == SOCKET_ERROR)
- ano_sockclose(smail.sock);
-
- return result;
-}
-
-/* Retrieve a response code */
-int smtp_get_code(const std::string &text)
-{
- size_t tmp = text.find(' ');
-
- if (tmp == std::string::npos)
- return 0;
-
- return atol(text.substr(0, tmp).c_str());
-}
-
-/* Send the email */
-int smtp_send_email()
-{
- char buf[1024];
- if (!smtp_read(buf, 1024))
- {
- alog("SMTP: error reading buffer");
- return 0;
- }
-
- int code = smtp_get_code(buf);
- if (code != 220)
- {
- alog("SMTP: error expected code 220 got %d",code);
- return 0;
- }
-
- if (!smtp_send("HELO anope\r\n"))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- if (!smtp_read(buf, 1024))
- {
- alog("SMTP: error reading buffer");
- return 0;
- }
-
- code = smtp_get_code(buf);
- if (code != 250)
- {
- alog("SMTP: error expected code 250 got %d",code);
- return 0;
- }
-
- strcpy(buf, "MAIL FROM: <");
- strcat(buf, smail.from.c_str());
- strcat(buf, ">\r\n");
-
- if (!smtp_send(buf))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- if (!smtp_read(buf, 1024))
- {
- alog("SMTP: error reading buffer");
- return 0;
- }
-
- code = smtp_get_code(buf);
- if (code != 250)
- return 0;
-
- strcpy(buf, "RCPT TO: <");
- strcat(buf, smail.to.c_str());
- strcat(buf, ">\r\n");
-
- if (!smtp_send(buf))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- if (!smtp_read(buf, 1024))
- {
- alog("SMTP: error reading buffer");
- return 0;
- }
-
- code = smtp_get_code(buf);
- if (smtp_get_code(buf) != 250)
- {
- alog("SMTP: error expected code 250 got %d",code);
- return 0;
- }
-
- if (!smtp_send("DATA\r\n"))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- if (!smtp_read(buf, 1024))
- {
- alog("SMTP: error reading buffer");
- return 0;
- }
-
- code = smtp_get_code(buf);
- if (code != 354)
- {
- alog("SMTP: error expected code 354 got %d",code);
- return 0;
- }
-
- for (std::vector<std::string>::const_iterator it = smail.smtp_headers.begin(), it_end = smail.smtp_headers.end(); it != it_end; ++it)
- if (!smtp_send(it->c_str()))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- if (!smtp_send("\r\n"))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- bool skip_done = false;
- for (std::vector<std::string>::const_iterator it = smail.smtp_body.begin(), it_end = smail.smtp_body.end(); it != it_end; ++it)
- if (skip_done)
- {
- if (!smtp_send(it->c_str()))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
- }
- else
- skip_done = true;
-
- if (!smtp_send("\r\n.\r\n"))
- {
- alog("SMTP: error writting to socket");
- return 0;
- }
-
- return 1;
-}
-
-void smtp_disconnect()
-{
- smtp_send("QUIT\r\n");
- ano_sockclose(smail.sock);
-}
-
-int main(int argc, char *argv[])
-{
- /* Win32 stuff */
-#ifdef _WIN32
- WSADATA wsa;
-#endif
-
- if (argc == 1)
- return 0;
-
- if (argc == 3 && !strcmp(argv[2], "--debug"))
- smtp_debug = 1;
-
- char *server = strtok(argv[1], ":"), *aport;
- short port;
- if ((aport = strtok(NULL, "")))
- port = atoi(aport);
- else
- port = 25;
-
- if (!server)
- {
- alog("No Server");
- /* Bad, bad, bad. This was a return from main with no value! -GD */
- return 0;
- }
- else
- alog("SMTP: server %s port %d",server,port);
-
- /* The WSAStartup function initiates use of WS2_32.DLL by a process. */
- /* guessing we can skip it under *nix */
-#ifdef _WIN32
- if (WSAStartup(MAKEWORD(1, 1), &wsa))
- return 0;
-#endif
-
- char buf[8192];
- bool headers_done = false;
- /* Read the message and parse it */
- while (fgets(buf, 8192, stdin))
- {
- if (smtp_is_header(buf) && !headers_done)
- {
- smail.smtp_headers.push_back(strip(buf) + "\r\n");
- std::string header, value;
- smtp_parse_header(buf, header, value);
- if (header == "From:")
- {
- alog("SMTP: from: %s", value.c_str());
- smail.from = value;
- }
- else if (header == "To:")
- {
- alog("SMTP: to: %s", value.c_str());
- smtp_set_to(value);
- }
- else if (smtp_is_end(buf))
- break;
- else
- {
- headers_done = true;
- smail.smtp_body.push_back(strip(buf) + "\r\n");
- }
- }
- else
- smail.smtp_body.push_back(strip(buf) + "\r\n");
- }
-
- if (!smtp_connect(server, port))
- {
- alog("SMTP: failed to connect to %s:%d", server, port);
- return 0;
- }
- if (!smtp_send_email())
- {
- alog("SMTP: error during sending of mail");
- return 0;
- }
- smtp_disconnect();
-
- return 1;
-}
diff --git a/src/uplink.cpp b/src/uplink.cpp
index df38f98f2..c2b7579c5 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -1,12 +1,20 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "uplink.h"
@@ -14,6 +22,10 @@
#include "config.h"
#include "protocol.h"
#include "servers.h"
+#include "event.h"
+#include "bots.h"
+#include "timers.h"
+#include "modules.h"
UplinkSocket *UplinkSock = NULL;
@@ -22,7 +34,7 @@ class ReconnectTimer : public Timer
public:
ReconnectTimer(int wait) : Timer(wait) { }
- void Tick(time_t)
+ void Tick(time_t) override
{
try
{
@@ -49,9 +61,9 @@ void Uplink::Connect()
Configuration::Uplink &u = Config->Uplinks[Anope::CurrentUplink];
new UplinkSocket();
- if (!Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost").empty())
- UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost"));
- FOREACH_MOD(OnPreServerConnect, ());
+ if (!Config->GetBlock("serverinfo")->Get<Anope::string>("localhost").empty())
+ UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<Anope::string>("localhost"));
+ EventManager::Get()->Dispatch(&Event::PreServerConnect::OnPreServerConnect);
Anope::string ip = Anope::Resolve(u.host, u.ipv6 ? AF_INET6 : AF_INET);
Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u.host << " (" << ip << "), port " << u.port;
UplinkSock->Connect(ip, u.port);
@@ -77,7 +89,7 @@ UplinkSocket::~UplinkSocket()
if (IRCD && Servers::GetUplink() && Servers::GetUplink()->IsSynced())
{
- FOREACH_MOD(OnServerDisconnect, ());
+ EventManager::Get()->Dispatch(&Event::ServerDisconnect::OnServerDisconnect);
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
{
@@ -87,7 +99,7 @@ UplinkSocket::~UplinkSocket()
{
/* Don't use quitmsg here, it may contain information you don't want people to see */
IRCD->SendQuit(u, "Shutting down");
- BotInfo* bi = BotInfo::Find(u->GetUID());
+ ServiceBot* bi = ServiceBot::Find(u->GetUID());
if (bi != NULL)
bi->introduced = false;
}
@@ -144,7 +156,7 @@ void UplinkSocket::OnConnect()
{
Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port;
IRCD->SendConnect();
- FOREACH_MOD(OnServerConnect, ());
+ EventManager::Get()->Dispatch(&Event::ServerConnect::OnServerConnect);
}
void UplinkSocket::OnError(const Anope::string &err)
@@ -154,60 +166,45 @@ void UplinkSocket::OnError(const Anope::string &err)
error |= !err.empty();
}
-UplinkSocket::Message::Message() : source(Me)
-{
-}
-
-UplinkSocket::Message::Message(const MessageSource &src) : source(src)
-{
-}
-
-UplinkSocket::Message::~Message()
+void Uplink::SendMessage(IRCMessage &message)
{
- Anope::string message_source;
+ const MessageSource &source = message.GetSource();
+ Anope::string buffer = IRCD->Format(message);
- if (this->source.GetServer() != NULL)
+ if (source.GetServer() != NULL)
{
- const Server *s = this->source.GetServer();
+ const Server *s = source.GetServer();
if (s != Me && !s->IsJuped())
{
- Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << s->GetName() << " who is not from me?";
+ Log(LOG_DEBUG) << "Attempted to send \"" << buffer << "\" from " << s->GetName() << " who is not from me?";
return;
}
-
- message_source = s->GetSID();
}
- else if (this->source.GetUser() != NULL)
+ else if (source.GetUser() != NULL)
{
- const User *u = this->source.GetUser();
+ const User *u = source.GetUser();
if (u->server != Me && !u->server->IsJuped())
{
- Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << u->nick << " who is not from me?";
+ Log(LOG_DEBUG) << "Attempted to send \"" << buffer << "\" from " << u->nick << " who is not from me?";
return;
}
- const BotInfo *bi = this->source.GetBot();
+ const ServiceBot *bi = source.GetBot();
if (bi != NULL && bi->introduced == false)
{
- Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced";
+ Log(LOG_DEBUG) << "Attempted to send \"" << buffer << "\" from " << bi->nick << " when not introduced";
return;
}
-
- message_source = u->GetUID();
}
if (!UplinkSock)
{
- if (!message_source.empty())
- Log(LOG_DEBUG) << "Attempted to send \"" << message_source << " " << this->buffer.str() << "\" with UplinkSock NULL";
- else
- Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL";
+ Log(LOG_DEBUG) << "Attempted to send \"" << buffer << "\" with UplinkSock NULL";
return;
}
- Anope::string sent = IRCD->Format(message_source, this->buffer.str());
- UplinkSock->Write(sent);
- Log(LOG_RAWIO) << "Sent: " << sent;
+ UplinkSock->Write(buffer);
+ Log(LOG_RAWIO) << "Sent: " << buffer;
}
diff --git a/src/users.cpp b/src/users.cpp
index 264f5ceba..3d4b7e1b7 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1,18 +1,25 @@
-/* Routines to maintain a list of online users.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
#include "modules.h"
#include "users.h"
-#include "account.h"
#include "protocol.h"
#include "servers.h"
#include "channels.h"
@@ -22,16 +29,17 @@
#include "language.h"
#include "sockets.h"
#include "uplink.h"
+#include "event.h"
+#include "modules/nickserv.h"
-user_map UserListByNick, UserListByUID;
+user_map UserListByNick;
+uid_map UserListByUID;
int OperCount = 0;
-unsigned MaxUserCount = 0;
-time_t MaxUserTime = 0;
std::list<User *> User::quitting_users;
-User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &uip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *account) : ip(uip)
+User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &uip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *account) : ip(uip)
{
if (snick.empty() || sident.empty() || shost.empty())
throw CoreException("Bad args passed to User::User");
@@ -53,7 +61,6 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->SetModesInternal(sserver, "%s", smodes.c_str());
this->uid = suid;
this->super_admin = false;
- this->nc = NULL;
size_t old = UserListByNick.size();
UserListByNick[snick] = this;
@@ -72,18 +79,10 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
Log(this, "connect") << (!vhost.empty() && vhost != host ? "(" + vhost + ") " : "") << "(" << srealname << ") " << (!uip.empty() && uip != host ? "[" + uip + "] " : "") << "connected to the network (" << sserver->GetName() << ")";
}
- if (UserListByNick.size() > MaxUserCount)
- {
- MaxUserCount = UserListByNick.size();
- MaxUserTime = Anope::CurTime;
- if (sserver && sserver->IsSynced())
- Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size();
- }
-
bool exempt = false;
if (server && server->IsULined())
exempt = true;
- FOREACH_MOD(OnUserConnect, (this, exempt));
+ EventManager::Get()->Dispatch(&Event::UserConnect::OnUserConnect, this, exempt);
}
static void CollideKill(User *target, const Anope::string &reason)
@@ -96,7 +95,7 @@ static void CollideKill(User *target, const Anope::string &reason)
IRCD->SendQuit(target, "%s", reason.c_str());
// Reintroduce my client
- if (BotInfo *bi = dynamic_cast<BotInfo *>(target))
+ if (ServiceBot *bi = dynamic_cast<ServiceBot *>(target))
bi->OnKill();
else
target->Quit(reason);
@@ -111,7 +110,7 @@ static void Collide(User *u, const Anope::string &id, const Anope::string &type)
CollideKill(u, type);
}
-User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc)
+User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *nc)
{
// How IRCds handle collisions varies a lot, for safety well just always kill both sides
// With properly set qlines, this can almost never happen anyway
@@ -141,7 +140,7 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
/* Sanity check to make sure we don't segfault */
if (newnick.empty())
throw CoreException("User::ChangeNick() got a bad argument");
-
+
this->super_admin = false;
Log(this, "nick") << "(" << this->realname << ") changed nick to " << newnick;
@@ -152,10 +151,10 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
this->nick = newnick;
else
{
- NickAlias *old_na = NickAlias::Find(this->nick);
+ NickServ::Nick *old_na = NickServ::FindNick(this->nick);
if (old_na && (this->IsIdentified(true) || this->IsRecognized()))
- old_na->last_seen = Anope::CurTime;
-
+ old_na->SetLastSeen(Anope::CurTime);
+
UserListByNick.erase(this->nick);
this->nick = newnick;
@@ -170,18 +169,23 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
other = this;
on_access = false;
- NickAlias *na = NickAlias::Find(this->nick);
- if (na)
- on_access = na->nc->IsOnAccess(this);
-
- if (na && na->nc == this->Account())
+ if (NickServ::service)
{
- na->last_seen = Anope::CurTime;
- this->UpdateHost();
+ NickServ::Nick *na = NickServ::service->FindNick(this->nick);
+ if (na)
+ {
+ on_access = na->GetAccount()->IsOnAccess(this);
+
+ if (na->GetAccount() == this->Account())
+ {
+ na->SetLastSeen(Anope::CurTime);
+ this->UpdateHost();
+ }
+ }
}
}
- FOREACH_MOD(OnUserNickChange, (this, old));
+ EventManager::Get()->Dispatch(&Event::UserNickChange::OnUserNickChange, this, old);
}
void User::SetDisplayedHost(const Anope::string &shost)
@@ -193,7 +197,7 @@ void User::SetDisplayedHost(const Anope::string &shost)
Log(this, "host") << "changed vhost to " << shost;
- FOREACH_MOD(OnSetDisplayedHost, (this));
+ EventManager::Get()->Dispatch(&Event::SetDisplayedHost::OnSetDisplayedHost, this);
this->UpdateHost();
}
@@ -280,18 +284,18 @@ void User::SetRealname(const Anope::string &srealname)
throw CoreException("realname empty in SetRealname");
this->realname = srealname;
- NickAlias *na = NickAlias::Find(this->nick);
+
+ //XXX event
+ NickServ::Nick *na = NickServ::FindNick(this->nick);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
- na->last_realname = srealname;
+ na->SetLastRealname(srealname);
Log(this, "realname") << "changed realname to " << srealname;
}
User::~User()
{
- UnsetExtensibles();
-
if (this->server != NULL)
{
if (this->server->IsSynced())
@@ -299,7 +303,7 @@ User::~User()
--this->server->users;
}
- FOREACH_MOD(OnPreUserLogoff, (this));
+ EventManager::Get()->Dispatch(&Event::PreUserLogoff::OnPreUserLogoff, this);
ModeManager::StackerDel(this);
this->Logout();
@@ -314,25 +318,10 @@ User::~User()
if (!this->uid.empty())
UserListByUID.erase(this->uid);
- FOREACH_MOD(OnPostUserLogoff, (this));
+ EventManager::Get()->Dispatch(&Event::PostUserLogoff::OnPostUserLogoff, this);
}
-void User::SendMessage(BotInfo *source, const char *fmt, ...)
-{
- va_list args;
- char buf[BUFSIZE] = "";
-
- const char *translated_message = Language::Translate(this, fmt);
-
- va_start(args, fmt);
- vsnprintf(buf, BUFSIZE - 1, translated_message, args);
-
- this->SendMessage(source, Anope::string(buf));
-
- va_end(args);
-}
-
-void User::SendMessage(BotInfo *source, const Anope::string &msg)
+void User::SendMessage(const MessageSource &source, const Anope::string &msg)
{
const char *translated_message = Language::Translate(this, msg.c_str());
@@ -341,54 +330,77 @@ void User::SendMessage(BotInfo *source, const Anope::string &msg)
* - The user is not registered and NSDefMsg is enabled
* - The user is registered and has set /ns set msg on
*/
- bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasExt("MSG")));
+ bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasFieldS("MSG")));
sepstream sep(translated_message, '\n', true);
for (Anope::string tok; sep.GetToken(tok);)
{
- if (send_privmsg)
- IRCD->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str());
- else
- IRCD->SendNotice(source, this->GetUID(), "%s", tok.c_str());
+ if (tok.empty())
+ tok = " ";
+ spacesepstream ssep(tok, true);
+ Anope::string buf;
+ for (Anope::string word; ssep.GetToken(word);)
+ {
+ Anope::string add = buf.empty() ? word : " " + word;
+ if (buf.length() + add.length() > Config->LineWrap)
+ {
+ if (send_privmsg)
+ IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
+ else
+ IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
+ buf.clear();
+ add = word;
+ }
+ buf.append(add);
+ }
+
+ if (!buf.empty())
+ {
+ if (send_privmsg)
+ IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
+ else
+ IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
+ }
}
}
-void User::Identify(NickAlias *na)
+void User::Identify(NickServ::Nick *na)
{
- if (this->nick.equals_ci(na->nick))
+ if (this->nick.equals_ci(na->GetNick()))
{
- na->last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
- na->last_realhost = this->GetIdent() + "@" + this->host;
- na->last_realname = this->realname;
- na->last_seen = Anope::CurTime;
+ na->SetLastUsermask(this->GetIdent() + "@" + this->GetDisplayedHost());
+ na->SetLastRealhost(this->GetIdent() + "@" + this->host);
+ na->SetLastRealname(this->realname);
+ na->SetLastSeen(Anope::CurTime);
}
IRCD->SendLogin(this, na);
- this->Login(na->nc);
+ this->Login(na->GetAccount());
- FOREACH_MOD(OnNickIdentify, (this));
+ EventManager::Get()->Dispatch(&Event::NickIdentify::OnNickIdentify, this);
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(NULL, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m.c_str());
UserMode *um = ModeManager::FindUserModeByName("OPER");
- if (um && !this->HasMode("OPER") && this->nc->o->ot->modes.find(um->mchar) != Anope::string::npos)
+ if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(NULL, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
-void User::Login(NickCore *core)
+void User::Login(NickServ::Account *core)
{
if (!core || core == this->nc)
return;
@@ -400,26 +412,26 @@ void User::Login(NickCore *core)
this->UpdateHost();
if (this->server->IsSynced())
- Log(this, "account") << "is now identified as " << this->nc->display;
-
- FOREACH_MOD(OnUserLogin, (this));
+ Log(this, "account") << "is now identified as " << this->nc->GetDisplay();
+
+ EventManager::Get()->Dispatch(&Event::UserLogin::OnUserLogin, this);
}
void User::Logout()
{
if (!this->nc)
return;
-
- Log(this, "account") << "is no longer identified as " << this->nc->display;
- std::list<User *>::iterator it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
+ Log(this, "account") << "is no longer identified as " << this->nc->GetDisplay();
+
+ auto it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
if (it != this->nc->users.end())
this->nc->users.erase(it);
this->nc = NULL;
}
-NickCore *User::Account() const
+NickServ::Account *User::Account() const
{
return this->nc;
}
@@ -428,8 +440,8 @@ bool User::IsIdentified(bool check_nick) const
{
if (check_nick && this->nc)
{
- NickAlias *na = NickAlias::Find(this->nick);
- return na && *na->nc == *this->nc;
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ return na && na->GetAccount() == *this->nc;
}
return this->nc ? true : false;
@@ -439,9 +451,9 @@ bool User::IsRecognized(bool check_secure) const
{
if (check_secure && on_access)
{
- const NickAlias *na = NickAlias::Find(this->nick);
+ NickServ::Nick *na = NickServ::FindNick(nick);
- if (!na || na->nc->HasExt("NS_SECURE"))
+ if (!na || na->GetAccount()->HasFieldS("NS_SECURE"))
return false;
}
@@ -453,24 +465,27 @@ bool User::IsServicesOper()
if (!this->nc || !this->nc->IsServicesOper())
// No opertype.
return false;
- else if (this->nc->o->require_oper && !this->HasMode("OPER"))
+ else if (this->nc->o->GetRequireOper() && !this->HasMode("OPER"))
return false;
- else if (!this->nc->o->certfp.empty() && this->fingerprint != this->nc->o->certfp)
+ else if (!this->nc->o->GetCertFP().empty() && this->fingerprint != this->nc->o->GetCertFP())
// Certfp mismatch
return false;
- else if (!this->nc->o->hosts.empty())
+ else if (!this->nc->o->GetHost().empty())
{
+ std::vector<Anope::string> hosts;
+ spacesepstream(this->nc->o->GetHost()).GetTokens(hosts);
+
bool match = false;
Anope::string match_host = this->GetIdent() + "@" + this->host;
- for (unsigned i = 0; i < this->nc->o->hosts.size(); ++i)
- if (Anope::Match(match_host, this->nc->o->hosts[i]))
+ for (Anope::string h : hosts)
+ if (Anope::Match(match_host, h))
match = true;
if (match == false)
return false;
}
EventReturn MOD_RESULT;
- FOREACH_RESULT(IsServicesOper, MOD_RESULT, (this));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::IsServicesOperEvent::IsServicesOper, this);
if (MOD_RESULT == EVENT_STOP)
return false;
@@ -480,14 +495,14 @@ bool User::IsServicesOper()
bool User::HasCommand(const Anope::string &command)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasCommand(command);
+ return this->nc->o->GetType()->HasCommand(command);
return false;
}
bool User::HasPriv(const Anope::string &priv)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasPriv(priv);
+ return this->nc->o->GetType()->HasPriv(priv);
return false;
}
@@ -496,19 +511,20 @@ void User::UpdateHost()
if (this->host.empty())
return;
- NickAlias *na = NickAlias::Find(this->nick);
+ //XXX event
+ NickServ::Nick *na = NickServ::FindNick(this->nick);
on_access = false;
if (na)
- on_access = na->nc->IsOnAccess(this);
+ on_access = na->GetAccount()->IsOnAccess(this);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
{
Anope::string last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
Anope::string last_realhost = this->GetIdent() + "@" + this->host;
- na->last_usermask = last_usermask;
- na->last_realhost = last_realhost;
+ na->SetLastUsermask(last_usermask);
+ na->SetLastRealhost(last_realhost);
// This is called on signon, and if users are introduced with an account it won't update
- na->last_realname = this->realname;
+ na->SetLastRealname(this->realname);
}
}
@@ -530,19 +546,20 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(NULL, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m);
UserMode *oper = ModeManager::FindUserModeByName("OPER");
- if (oper && !this->HasMode("OPER") && this->nc->o->ot->modes.find(oper->mchar) != Anope::string::npos)
+ if (oper && !this->HasMode("OPER") && m.find(oper->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(NULL, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
@@ -550,7 +567,7 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
if (um->name == "CLOAK" || um->name == "VHOST")
this->UpdateHost();
- FOREACH_MOD(OnUserModeSet, (source, this, um->name));
+ EventManager::Get()->Dispatch(&Event::UserModeSet::OnUserModeSet, source, this, um->name);
}
void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
@@ -569,10 +586,10 @@ void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
this->UpdateHost();
}
- FOREACH_MOD(OnUserModeUnset, (source, this, um->name));
+ EventManager::Get()->Dispatch(&Event::UserModeUnset::OnUserModeUnset, source, this, um->name);
}
-void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || HasMode(um->name))
return;
@@ -581,12 +598,12 @@ void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
SetModeInternal(bi, um, param);
}
-void User::SetMode(BotInfo *bi, const Anope::string &uname, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, const Anope::string &uname, const Anope::string &param)
{
SetMode(bi, ModeManager::FindUserModeByName(uname), param);
}
-void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || !HasMode(um->name))
return;
@@ -595,12 +612,12 @@ void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
RemoveModeInternal(bi, um);
}
-void User::RemoveMode(BotInfo *bi, const Anope::string &name, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, const Anope::string &name, const Anope::string &param)
{
RemoveMode(bi, ModeManager::FindUserModeByName(name), param);
}
-void User::SetModes(BotInfo *bi, const char *umodes, ...)
+void User::SetModes(ServiceBot *bi, const char *umodes, ...)
{
char buf[BUFSIZE] = "";
va_list args;
@@ -756,7 +773,7 @@ void User::Quit(const Anope::string &reason)
return;
}
- FOREACH_MOD(OnUserQuit, (this, reason));
+ EventManager::Get()->Dispatch(&Event::UserQuit::OnUserQuit, this, reason);
this->quit = true;
quitting_users.push_back(this);
@@ -818,7 +835,7 @@ User* User::Find(const Anope::string &name, bool nick_only)
{
if (!nick_only && IRCD->RequiresID)
{
- user_map::iterator it = UserListByUID.find(name);
+ uid_map::iterator it = UserListByUID.find(name);
if (it != UserListByUID.end())
return it->second;
diff --git a/src/version.sh b/src/version.sh
index ef928b914..db1881df3 100644
--- a/src/version.sh
+++ b/src/version.sh
@@ -1,7 +1,7 @@
#!/bin/sh
VERSION_MAJOR=2
-VERSION_MINOR=0
-VERSION_PATCH=4
-VERSION_EXTRA="-git"
+VERSION_MINOR=1
+VERSION_PATCH=0
+VERSION_EXTRA="-exploding-tacos"
diff --git a/src/win32/Config.cs b/src/win32/Config.cs
deleted file mode 100644
index d7c9661ec..000000000
--- a/src/win32/Config.cs
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Config.cs - Windows Configuration
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * This program is free but copyrighted software; see the file COPYING for
- * details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- * Written by Scott <stealtharcher.scott@gmail.com>
- * Written by Adam <Adam@anope.org>
- * Cleaned up by Naram Qashat <cyberbotx@anope.org>
- *
- * Compile with: csc /out:../../Config.exe /win32icon:anope-icon.ico Config.cs
- */
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-
-namespace Config
-{
- class Config
- {
- static string ExecutablePath, InstallDirectory, ExtraIncludeDirs, ExtraLibDirs, ExtraArguments;
- static bool UseNMake = true, BuildDebug = false;
-
- static bool CheckResponse(string InstallerResponse)
- {
- if (string.Compare(InstallerResponse, "yes", true) == 0 || string.Compare(InstallerResponse, "y", true) == 0)
- return true;
- return false;
- }
-
- static bool LoadCache()
- {
- try
- {
- string[] cache = File.ReadAllLines(string.Format(@"{0}\config.cache", ExecutablePath));
- if (cache.Length > 0)
- Console.WriteLine("Using defaults from config.cache");
- foreach (string line in cache)
- {
- int e = line.IndexOf('=');
- string name = line.Substring(0, e);
- string value = line.Substring(e + 1);
-
- if (name == "INSTDIR")
- InstallDirectory = value;
- else if (name == "DEBUG")
- BuildDebug = CheckResponse(value);
- else if (name == "USENMAKE")
- UseNMake = CheckResponse(value);
- else if (name == "EXTRAINCLUDE")
- ExtraIncludeDirs = value;
- else if (name == "EXTRALIBS")
- ExtraLibDirs = value;
- else if (name == "EXTRAARGS")
- ExtraArguments = value;
- }
-
- return true;
- }
- catch (Exception)
- {
- }
-
- return false;
- }
-
- static void SaveCache()
- {
- using (TextWriter tw = new StreamWriter(string.Format(@"{0}\config.cache", ExecutablePath)))
- {
- tw.WriteLine("INSTDIR={0}", InstallDirectory);
- tw.WriteLine("DEBUG={0}", BuildDebug ? "yes" : "no");
- tw.WriteLine("USENMAKE={0}", UseNMake ? "yes" : "no");
- tw.WriteLine("EXTRAINCLUDE={0}", ExtraIncludeDirs);
- tw.WriteLine("EXTRALIBS={0}", ExtraLibDirs);
- tw.WriteLine("EXTRAARGS={0}", ExtraArguments);
- }
- }
-
- static string HandleCache(int i)
- {
- switch (i)
- {
- case 0:
- Console.Write("[{0}] ", InstallDirectory);
- return InstallDirectory;
- case 1:
- Console.Write("[{0}] ", UseNMake ? "yes" : "no");
- return UseNMake ? "yes" : "no";
- case 2:
- Console.Write("[{0}] ", BuildDebug ? "yes" : "no");
- return BuildDebug ? "yes" : "no";
- case 3:
- Console.Write("[{0}] ", ExtraIncludeDirs);
- return ExtraIncludeDirs;
- case 4:
- Console.Write("[{0}] ", ExtraLibDirs);
- return ExtraLibDirs;
- case 5:
- Console.Write("[{0}] ", ExtraArguments);
- return ExtraArguments;
- default:
- break;
- }
-
- return null;
- }
-
- static string FindAnopeVersion()
- {
- if (!File.Exists(string.Format(@"{0}\src\version.sh", ExecutablePath)))
- return "Unknown";
-
- Dictionary<string, string> versions = new Dictionary<string, string>();
- string[] versionfile = File.ReadAllLines(string.Format(@"{0}\src\version.sh", ExecutablePath));
- foreach (string line in versionfile)
- if (line.StartsWith("VERSION_"))
- {
- string key = line.Split('_')[1].Split('=')[0];
- if (!versions.ContainsKey(key))
- versions.Add(key, line.Split('=')[1].Replace("\"", "").Replace("\'", ""));
- }
-
- try
- {
- if (versions.ContainsKey("BUILD"))
- return string.Format("{0}.{1}.{2}.{3}{4}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["BUILD"], versions["EXTRA"]);
- else
- return string.Format("{0}.{1}.{2}{3}", versions["MAJOR"], versions["MINOR"], versions["PATCH"], versions["EXTRA"]);
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- return "Unknown";
- }
- }
-
- static void RunCMake(string cMake)
- {
- Console.WriteLine("cmake {0}", cMake);
- try
- {
- ProcessStartInfo processStartInfo = new ProcessStartInfo("cmake")
- {
- RedirectStandardError = true,
- RedirectStandardOutput = true,
- UseShellExecute = false,
- Arguments = cMake
- };
- Process pCMake = Process.Start(processStartInfo);
- StreamReader stdout = pCMake.StandardOutput, stderr = pCMake.StandardError;
- string stdoutr, stderrr;
- List<string> errors = new List<string>();
- while (!pCMake.HasExited)
- {
- if ((stdoutr = stdout.ReadLine()) != null)
- Console.WriteLine(stdoutr);
- if ((stderrr = stderr.ReadLine()) != null)
- errors.Add(stderrr);
- }
- foreach (string error in errors)
- Console.WriteLine(error);
- Console.WriteLine();
- if (pCMake.ExitCode == 0)
- {
- if (UseNMake)
- Console.WriteLine("To compile Anope, run 'nmake'. To install, run 'nmake install'");
- else
- Console.WriteLine("To compile Anope, open Anope.sln and build the solution. To install, do a build on the INSTALL project");
- }
- else
- Console.WriteLine("There was an error attempting to run CMake! Check the above error message, and contact the Anope team if you are unsure how to proceed.");
- }
- catch (Exception e)
- {
- Console.WriteLine();
- Console.WriteLine(DateTime.UtcNow + " UTC: " + e.Message);
- Console.WriteLine("There was an error attempting to run CMake! Check the above error message, and contact the Anope team if you are unsure how to proceed.");
- }
- }
-
- static int Main(string[] args)
- {
- bool IgnoreCache = false, NoIntro = false, DoQuick = false;
-
- if (args.Length > 0)
- {
- if (args[0] == "--help")
- {
- Console.WriteLine("Config utility for Anope");
- Console.WriteLine("------------------------");
- Console.WriteLine("Syntax: .\\Config.exe [options]");
- Console.WriteLine("-nocache Ignore settings saved in config.cache");
- Console.WriteLine("-nointro Skip intro (disclaimer, etc)");
- Console.WriteLine("-quick or -q Skip questions, go straight to cmake");
- return 0;
- }
- else if (args[0] == "-nocache")
- IgnoreCache = true;
- else if (args[0] == "-nointro")
- NoIntro = true;
- else if (args[0] == "-quick" || args[0] == "-q")
- DoQuick = true;
- }
-
- ExecutablePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
-
- string AnopeVersion = FindAnopeVersion();
-
- if (!NoIntro && File.Exists(string.Format(@"{0}\.BANNER", ExecutablePath)))
- Console.WriteLine(File.ReadAllText(string.Format(@"{0}\.BANNER", ExecutablePath)).Replace("CURVER", AnopeVersion).Replace("For more options type SOURCE_DIR/Config --help", ""));
-
- Console.WriteLine("Press Enter to begin");
- Console.WriteLine();
- Console.ReadKey();
-
- bool UseCache = false;
-
- if (DoQuick || !IgnoreCache)
- {
- UseCache = LoadCache();
- if (DoQuick && !UseCache)
- {
- Console.WriteLine("Can't find cache file (config.cache), aborting...");
- return 1;
- }
- }
-
- if (!DoQuick)
- {
- List<string> InstallerQuestions = new List<string>()
- {
- "Where do you want Anope to be installed?",
- "Would you like to build using NMake instead of using Visual Studio?\r\nNOTE: If you decide to use NMake, you must be in an environment where\r\nNMake can function, such as the Visual Studio command line. If you say\r\nyes to this while not in an environment that can run NMake, it can\r\ncause the CMake configuration to enter an endless loop. [y/n]",
- "Would you like to build a debug version of Anope? [y/n]",
- "Are there any extra include directories you wish to use?\nYou may only need to do this if CMake is unable to locate missing dependencies without hints.\nSeparate directories with semicolons and use slashes (aka /) instead of backslashes (aka \\).\nIf you need no extra include directories, enter NONE in all caps.",
- "Are there any extra library directories you wish to use?\nYou may only need to do this if CMake is unable to locate missing dependencies without hints.\nSeparate directories with semicolons and use slashes (aka /) instead of backslashes (aka \\).\nIf you need no extra library directories, enter NONE in all caps.",
- "Are there any extra arguments you wish to pass to CMake?\nIf you need no extra arguments to CMake, enter NONE in all caps."
- };
-
- for (int i = 0; i < InstallerQuestions.Count; ++i)
- {
- Console.WriteLine(InstallerQuestions[i]);
- string CacheResponse = null;
- if (UseCache)
- CacheResponse = HandleCache(i);
- string InstallerResponse = Console.ReadLine();
- Console.WriteLine();
-
- if (!string.IsNullOrWhiteSpace(CacheResponse) && string.IsNullOrWhiteSpace(InstallerResponse))
- InstallerResponse = CacheResponse;
-
- // Question 4+ are optional
- if (i < 3 && string.IsNullOrWhiteSpace(InstallerResponse))
- {
- Console.WriteLine("Invalid option");
- --i;
- continue;
- }
-
- switch (i)
- {
- case 0:
- if (!Directory.Exists(InstallerResponse))
- {
- Console.WriteLine("Directory does not exist! Creating directory.");
- Console.WriteLine();
- try
- {
- Directory.CreateDirectory(InstallerResponse);
- InstallDirectory = InstallerResponse;
- }
- catch (Exception e)
- {
- Console.WriteLine("Unable to create directory: " + e.Message);
- --i;
- }
- }
- else if (File.Exists(InstallerResponse + @"\include\services.h"))
- {
- Console.WriteLine("You cannot use the Anope source directory as the target directory!");
- --i;
- }
- else
- InstallDirectory = InstallerResponse;
- break;
- case 1:
- UseNMake = CheckResponse(InstallerResponse);
- if (UseNMake)
- ++i;
- break;
- case 2:
- BuildDebug = CheckResponse(InstallerResponse);
- break;
- case 3:
- if (InstallerResponse == "NONE")
- ExtraIncludeDirs = null;
- else
- ExtraIncludeDirs = InstallerResponse;
- break;
- case 4:
- if (InstallerResponse == "NONE")
- ExtraLibDirs = null;
- else
- ExtraLibDirs = InstallerResponse;
- break;
- case 5:
- if (InstallerResponse == "NONE")
- ExtraArguments = null;
- else
- ExtraArguments = InstallerResponse;
- break;
- default:
- break;
- }
- }
- }
-
- Console.WriteLine("Anope will be compiled with the following options:");
- Console.WriteLine("Install directory: {0}", InstallDirectory);
- Console.WriteLine("Use NMake: {0}", UseNMake ? "Yes" : "No");
- Console.WriteLine("Build debug: {0}", BuildDebug ? "Yes" : "No");
- Console.WriteLine("Anope Version: {0}", AnopeVersion);
- Console.WriteLine("Extra Include Directories: {0}", ExtraIncludeDirs);
- Console.WriteLine("Extra Library Directories: {0}", ExtraLibDirs);
- Console.WriteLine("Extra Arguments: {0}", ExtraArguments);
- Console.WriteLine("Press Enter to continue...");
- Console.ReadKey();
-
- SaveCache();
-
- if (!string.IsNullOrWhiteSpace(ExtraIncludeDirs))
- ExtraIncludeDirs = string.Format("-DEXTRA_INCLUDE:STRING={0} ", ExtraIncludeDirs);
- else
- ExtraIncludeDirs = "";
- if (!string.IsNullOrWhiteSpace(ExtraLibDirs))
- ExtraLibDirs = string.Format("-DEXTRA_LIBS:STRING={0} ", ExtraLibDirs);
- else
- ExtraLibDirs = "";
- if (!string.IsNullOrWhiteSpace(ExtraArguments))
- ExtraArguments += " ";
- else
- ExtraArguments = "";
-
- InstallDirectory = "-DINSTDIR:STRING=\"" + InstallDirectory.Replace('\\', '/') + "\" ";
- string NMake = UseNMake ? "-G\"NMake Makefiles\" " : "";
- string Debug = BuildDebug ? "-DCMAKE_BUILD_TYPE:STRING=DEBUG " : "-DCMAKE_BUILD_TYPE:STRING=RELEASE ";
- string cMake = InstallDirectory + NMake + Debug + ExtraIncludeDirs + ExtraLibDirs + ExtraArguments + "\"" + ExecutablePath.Replace('\\', '/') + "\"";
- RunCMake(cMake);
-
- return 0;
- }
- }
-}
diff --git a/src/win32/anope_windows.h b/src/win32/anope_windows.h
index 14c83b4d4..061934752 100644
--- a/src/win32/anope_windows.h
+++ b/src/win32/anope_windows.h
@@ -1,7 +1,7 @@
/* POSIX emulation layer for Windows.
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2014 Anope Team <info@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -42,6 +42,13 @@
/* VS2008 hates having this define before its own */
#define vsnprintf _vsnprintf
+#define popen _popen
+#define pclose _pclose
+
+#define PATH_MAX MAX_PATH
+
+#define sleep(x) Sleep(x * 1000)
+
#define anope_close windows_close
#define stat _stat
@@ -56,7 +63,6 @@
#include "dir/dir.h"
#include "dl/dl.h"
#include "pipe/pipe.h"
-#include "pthread/pthread.h"
#include "sigaction/sigaction.h"
typedef int ssize_t;
diff --git a/src/win32/dir/dir.cpp b/src/win32/dir/dir.cpp
index d660c9694..16809bd9c 100644
--- a/src/win32/dir/dir.cpp
+++ b/src/win32/dir/dir.cpp
@@ -1,14 +1,13 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
#include "dir.h"
#include <stdio.h>
-
+
DIR *opendir(const char *path)
{
char real_path[MAX_PATH];
diff --git a/src/win32/dir/dir.h b/src/win32/dir/dir.h
index a6c9a055f..4d1433658 100644
--- a/src/win32/dir/dir.h
+++ b/src/win32/dir/dir.h
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -21,7 +20,7 @@ struct DIR
WIN32_FIND_DATA data;
bool read_first;
};
-
+
DIR *opendir(const char *);
dirent *readdir(DIR *);
int closedir(DIR *);
diff --git a/src/win32/dl/dl.cpp b/src/win32/dl/dl.cpp
index bdcbe636c..5b19d7441 100644
--- a/src/win32/dl/dl.cpp
+++ b/src/win32/dl/dl.cpp
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
diff --git a/src/win32/dl/dl.h b/src/win32/dl/dl.h
index 81c115fef..02a2f1d3d 100644
--- a/src/win32/dl/dl.h
+++ b/src/win32/dl/dl.h
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
diff --git a/src/win32/pipe/pipe.cpp b/src/win32/pipe/pipe.cpp
index 70690ab2b..676909b9a 100644
--- a/src/win32/pipe/pipe.cpp
+++ b/src/win32/pipe/pipe.cpp
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -56,6 +55,7 @@ int pipe(int fds[2])
fds[0] = cfd;
fds[1] = afd;
-
+
return 0;
}
+
diff --git a/src/win32/pipe/pipe.h b/src/win32/pipe/pipe.h
index d77d0706b..8e67bafc7 100644
--- a/src/win32/pipe/pipe.h
+++ b/src/win32/pipe/pipe.h
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
diff --git a/src/win32/pthread/pthread.cpp b/src/win32/pthread/pthread.cpp
deleted file mode 100644
index 36b8cd54d..000000000
--- a/src/win32/pthread/pthread.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* POSIX emulation layer for Windows.
- *
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "pthread.h"
-
-struct ThreadInfo
-{
- void *(*entry)(void *);
- void *param;
-};
-
-static DWORD WINAPI entry_point(void *parameter)
-{
- ThreadInfo *ti = static_cast<ThreadInfo *>(parameter);
- ti->entry(ti->param);
- delete ti;
- return 0;
-}
-
-int pthread_attr_init(pthread_attr_t *)
-{
- /* No need for this */
- return 0;
-}
-
-int pthread_attr_setdetachstate(pthread_attr_t *, int)
-{
- /* No need for this */
- return 0;
-}
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *, void *(*entry)(void *), void *param)
-{
- ThreadInfo *ti = new ThreadInfo;
- ti->entry = entry;
- ti->param = param;
-
- *thread = CreateThread(NULL, 0, entry_point, ti, 0, NULL);
- if (!*thread)
- {
- delete ti;
- return -1;
- }
-
- return 0;
-}
-
-int pthread_join(pthread_t thread, void **)
-{
- if (WaitForSingleObject(thread, INFINITE) == WAIT_FAILED)
- return -1;
- CloseHandle(thread);
- return 0;
-}
-
-void pthread_exit(int i)
-{
- ExitThread(i);
-}
-
-int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *)
-{
- InitializeCriticalSection(mutex);
- return 0;
-}
-
-int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
- DeleteCriticalSection(mutex);
- return 0;
-}
-
-int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
- EnterCriticalSection(mutex);
- return 0;
-}
-
-int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- return !TryEnterCriticalSection(mutex);
-}
-
-int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
- LeaveCriticalSection(mutex);
- return 0;
-}
-
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *)
-{
- *cond = CreateEvent(NULL, false, false, NULL);
- if (*cond == NULL)
- return -1;
- return 0;
-}
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
- return !CloseHandle(*cond);
-}
-
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- return !PulseEvent(*cond);
-}
-
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- LeaveCriticalSection(mutex);
- WaitForSingleObject(*cond, INFINITE);
- EnterCriticalSection(mutex);
- return 0;
-}
diff --git a/src/win32/pthread/pthread.h b/src/win32/pthread/pthread.h
deleted file mode 100644
index 18909a17d..000000000
--- a/src/win32/pthread/pthread.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* POSIX emulation layer for Windows.
- *
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include <Windows.h>
-
-typedef HANDLE pthread_t;
-typedef CRITICAL_SECTION pthread_mutex_t;
-typedef HANDLE pthread_cond_t;
-typedef int pthread_attr_t;
-typedef void pthread_mutexattr_t;
-typedef void pthread_condattr_t;
-
-#define PTHREAD_CREATE_JOINABLE 0
-
-extern int pthread_attr_init(pthread_attr_t *);
-extern int pthread_attr_setdetachstate(pthread_attr_t *, int);
-extern int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
-extern int pthread_join(pthread_t, void **);
-extern void pthread_exit(int);
-
-extern int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
-extern int pthread_mutex_destroy(pthread_mutex_t *);
-extern int pthread_mutex_lock(pthread_mutex_t *);
-extern int pthread_mutex_trylock(pthread_mutex_t *);
-extern int pthread_mutex_unlock(pthread_mutex_t *);
-
-extern int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
-extern int pthread_cond_destroy(pthread_cond_t *);
-extern int pthread_cond_signal(pthread_cond_t *);
-extern int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
diff --git a/src/win32/resource.h b/src/win32/resource.h
index 0fb755b56..e4fa54b70 100644
--- a/src/win32/resource.h
+++ b/src/win32/resource.h
@@ -1,11 +1,3 @@
-/*
- *
- * (C) 2005-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Win32GUI.rc
@@ -16,7 +8,7 @@
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
diff --git a/src/win32/sigaction/sigaction.cpp b/src/win32/sigaction/sigaction.cpp
index 17faaf2fb..51615cf39 100644
--- a/src/win32/sigaction/sigaction.cpp
+++ b/src/win32/sigaction/sigaction.cpp
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -9,12 +8,12 @@
* Based on the original code of Services by Andy Church.
*/
-#include <windows.h>
-#include "sigaction.h"
-#include <signal.h>
+ #include <windows.h>
+ #include "sigaction.h"
+ #include <signal.h>
-int sigaction(int sig, struct sigaction *action, struct sigaction *old)
-{
+ int sigaction(int sig, struct sigaction *action, struct sigaction *old)
+ {
if (sig == -1)
return 0;
if (old == NULL)
@@ -28,4 +27,4 @@ int sigaction(int sig, struct sigaction *action, struct sigaction *old)
return -1;
}
return 0;
-}
+ }
diff --git a/src/win32/sigaction/sigaction.h b/src/win32/sigaction/sigaction.h
index c517ba16d..9e74eeffa 100644
--- a/src/win32/sigaction/sigaction.h
+++ b/src/win32/sigaction/sigaction.h
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -9,20 +8,21 @@
* Based on the original code of Services by Andy Church.
*/
-#define sigemptyset(x) memset((x), 0, sizeof(*(x)))
+ #define sigemptyset(x) memset((x), 0, sizeof(*(x)))
-#ifndef SIGHUP
-# define SIGHUP -1
-#endif
-#ifndef SIGPIPE
-# define SIGPIPE -1
-#endif
+ #ifndef SIGHUP
+ # define SIGHUP -1
+ #endif
+ #ifndef SIGPIPE
+ # define SIGPIPE -1
+ #endif
-struct sigaction
-{
+ struct sigaction
+ {
void (*sa_handler)(int);
int sa_flags;
int sa_mask;
-};
+ };
+
+ extern int sigaction(int, struct sigaction *, struct sigaction *);
-extern int sigaction(int, struct sigaction *, struct sigaction *);
diff --git a/src/win32/socket.cpp b/src/win32/socket.cpp
index 489192679..7f6ef4df1 100644
--- a/src/win32/socket.cpp
+++ b/src/win32/socket.cpp
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -86,7 +85,7 @@ int windows_inet_pton(int af, const char *src, void *dst)
}
return 1;
}
-
+
return 0;
}
diff --git a/src/win32/socket.h b/src/win32/socket.h
index a8064589e..d587618a9 100644
--- a/src/win32/socket.h
+++ b/src/win32/socket.h
@@ -1,7 +1,6 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2008-2014 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
diff --git a/src/win32/win32.rc.cmake b/src/win32/win32.rc.cmake
index 1e86c7e0d..4cca9d89d 100644
--- a/src/win32/win32.rc.cmake
+++ b/src/win32/win32.rc.cmake
@@ -54,7 +54,7 @@ BEGIN
VALUE "FileDescription", "Anope IRC Services"
VALUE "FileVersion", "@VERSION_FULL@"
VALUE "InternalName", "Anope"
- VALUE "LegalCopyright", "Copyright (C) 2003-2016 Anope Team"
+ VALUE "LegalCopyright", "Copyright (C) 2003-2014 Anope Team"
VALUE "OriginalFilename", "anope.exe"
VALUE "ProductName", "Anope"
VALUE "ProductVersion", "@VERSION_DOTTED@"
diff --git a/src/win32/windows.cpp b/src/win32/windows.cpp
index ac6801cba..f5bbde2f8 100644
--- a/src/win32/windows.cpp
+++ b/src/win32/windows.cpp
@@ -1,7 +1,7 @@
-/* POSIX emulation layer for Windows.
+ /* POSIX emulation layer for Windows.
*
- * (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
- * (C) 2008-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2014 Anope Team <info@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -73,10 +73,10 @@ int gettimeofday(timeval *tv, void *)
{
SYSTEMTIME st;
GetSystemTime(&st);
-
+
tv->tv_sec = Anope::CurTime;
tv->tv_usec = st.wMilliseconds;
-
+
return 0;
}
@@ -248,7 +248,7 @@ int mkstemp(char *input)
errno = EEXIST;
return -1;
}
-
+
int fd = open(input, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
return fd;
}
diff --git a/src/xline.cpp b/src/xline.cpp
index 21cbc2501..df65ae7dd 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -1,12 +1,20 @@
-/* XLine functions.
+/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
#include "services.h"
@@ -14,66 +22,67 @@
#include "xline.h"
#include "users.h"
#include "sockets.h"
-#include "regexpr.h"
#include "config.h"
#include "commands.h"
#include "servers.h"
/* List of XLine managers we check users against in XLineManager::CheckAll */
-std::list<XLineManager *> XLineManager::XLineManagers;
-Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManager::XLinesByUID("XLine");
+std::vector<XLineManager *> XLineManager::XLineManagers;
-void XLine::Init()
+void XLine::Recache()
{
- if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && !Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty())
+ delete regex;
+ regex = nullptr;
+
+ delete c;
+ c = nullptr;
+
+ Anope::string mask = GetMask();
+ if (mask.length() >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/' && Config->regex_flags)
{
- Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2);
+ Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string>("regexengine"));
- if (provider)
+ try
{
- try
- {
- this->regex = provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- Log(LOG_DEBUG) << ex.GetReason();
- }
+ this->regex = new std::regex(stripped_mask.str(), Config->regex_flags);
+ }
+ catch (const std::regex_error &ex)
+ {
+ Log(LOG_DEBUG) << ex.what();
}
}
- size_t nick_t = this->mask.find('!');
+ size_t nick_t = mask.find('!');
if (nick_t != Anope::string::npos)
- nick = this->mask.substr(0, nick_t);
+ nick = mask.substr(0, nick_t);
- size_t user_t = this->mask.find('!'), host_t = this->mask.find('@');
+ size_t user_t = mask.find('!'), host_t = mask.find('@');
if (host_t != Anope::string::npos)
{
if (user_t != Anope::string::npos && host_t > user_t)
- user = this->mask.substr(user_t + 1, host_t - user_t - 1);
+ user = mask.substr(user_t + 1, host_t - user_t - 1);
else
- user = this->mask.substr(0, host_t);
+ user = mask.substr(0, host_t);
}
- size_t real_t = this->mask.find('#');
+ size_t real_t = mask.find('#');
if (host_t != Anope::string::npos)
{
if (real_t != Anope::string::npos && real_t > host_t)
- host = this->mask.substr(host_t + 1, real_t - host_t - 1);
+ host = mask.substr(host_t + 1, real_t - host_t - 1);
else
- host = this->mask.substr(host_t + 1);
+ host = mask.substr(host_t + 1);
}
else
{
if (real_t != Anope::string::npos)
- host = this->mask.substr(0, real_t);
+ host = mask.substr(0, real_t);
else
- host = this->mask;
+ host = mask;
}
if (real_t != Anope::string::npos)
- real = this->mask.substr(real_t + 1);
+ real = mask.substr(real_t + 1);
if (host.find('/') != Anope::string::npos)
{
@@ -86,31 +95,80 @@ void XLine::Init()
}
}
-XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(Me->GetName()), created(0), expires(0), reason(r), id(uid)
+XLine::~XLine()
+{
+ delete regex;
+ delete c;
+}
+
+void XLine::SetType(const Anope::string &t)
{
- regex = NULL;
- manager = NULL;
- c = NULL;
+ Set(&XLineType::type, t);
+}
- this->Init();
+Anope::string XLine::GetType()
+{
+ return Get(&XLineType::type);
}
-XLine::XLine(const Anope::string &ma, const Anope::string &b, const time_t ex, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(b), created(Anope::CurTime), expires(ex), reason(r), id(uid)
+void XLine::SetMask(const Anope::string &m)
{
- regex = NULL;
- manager = NULL;
- c = NULL;
+ Set(&XLineType::mask, m);
+}
- this->Init();
+Anope::string XLine::GetMask()
+{
+ return Get<Anope::string>(&XLineType::mask);
}
-XLine::~XLine()
+void XLine::SetBy(const Anope::string &b)
{
- if (manager)
- manager->RemoveXLine(this);
+ Set(&XLineType::by, b);
+}
- delete regex;
- delete c;
+Anope::string XLine::GetBy()
+{
+ return Get(&XLineType::by);
+}
+
+void XLine::SetReason(const Anope::string &r)
+{
+ Set(&XLineType::reason, r);
+}
+
+Anope::string XLine::GetReason()
+{
+ return Get(&XLineType::reason);
+}
+
+void XLine::SetID(const Anope::string &id)
+{
+ Set(&XLineType::id, id);
+}
+
+Anope::string XLine::GetID()
+{
+ return Get(&XLineType::id);
+}
+
+void XLine::SetCreated(const time_t &t)
+{
+ Set(&XLineType::created, t);
+}
+
+time_t XLine::GetCreated()
+{
+ return Get(&XLineType::created);
+}
+
+void XLine::SetExpires(const time_t &e)
+{
+ Set(&XLineType::expires, e);
+}
+
+time_t XLine::GetExpires()
+{
+ return Get(&XLineType::created);
}
const Anope::string &XLine::GetNick() const
@@ -133,11 +191,11 @@ const Anope::string &XLine::GetReal() const
return real;
}
-Anope::string XLine::GetReason() const
+Anope::string XLine::GetReasonWithID()
{
- Anope::string r = this->reason;
- if (!this->id.empty())
- r += " (ID: " + this->id + ")";
+ Anope::string r = this->GetReason();
+ if (!this->GetID().empty())
+ r += " (ID: " + this->GetID() + ")";
return r;
}
@@ -146,67 +204,21 @@ bool XLine::HasNickOrReal() const
return !this->GetNick().empty() || !this->GetReal().empty();
}
-bool XLine::IsRegex() const
+bool XLine::IsRegex()
{
- return !this->mask.empty() && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/';
+ Anope::string mask = GetMask();
+ return mask.length() > 2 && mask[0] == '/' && mask[mask.length() - 1] == '/';
}
-void XLine::Serialize(Serialize::Data &data) const
+XLineManager *XLine::GetManager()
{
- data["mask"] << this->mask;
- data["by"] << this->by;
- data["created"] << this->created;
- data["expires"] << this->expires;
- data["reason"] << this->reason;
- data["uid"] << this->id;
- if (this->manager)
- data["manager"] << this->manager->name;
+ return ServiceManager::Get()->FindService<XLineManager *>(GetType());
}
-Serializable* XLine::Unserialize(Serializable *obj, Serialize::Data &data)
+void XLineType::Mask::SetField(XLine *s, const Anope::string &value)
{
- Anope::string smanager;
-
- data["manager"] >> smanager;
-
- ServiceReference<XLineManager> xlm("XLineManager", smanager);
- if (!xlm)
- return NULL;
-
- XLine *xl;
- if (obj)
- {
- xl = anope_dynamic_static_cast<XLine *>(obj);
- data["mask"] >> xl->mask;
- data["by"] >> xl->by;
- data["reason"] >> xl->reason;
- data["uid"] >> xl->id;
-
- if (xlm != xl->manager)
- {
- xl->manager->DelXLine(xl);
- xlm->AddXLine(xl);
- }
- }
- else
- {
- Anope::string smask, sby, sreason, suid;
- time_t expires;
-
- data["mask"] >> smask;
- data["by"] >> sby;
- data["reason"] >> sreason;
- data["uid"] >> suid;
- data["expires"] >> expires;
-
- xl = new XLine(smask, sby, expires, sreason, suid);
- xlm->AddXLine(xl);
- }
-
- data["created"] >> xl->created;
- xl->manager = xlm;
-
- return xl;
+ Serialize::Field<XLine, Anope::string>::SetField(s, value);
+ s->Recache();
}
void XLineManager::RegisterXLineManager(XLineManager *xlm)
@@ -216,52 +228,35 @@ void XLineManager::RegisterXLineManager(XLineManager *xlm)
void XLineManager::UnregisterXLineManager(XLineManager *xlm)
{
- std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
-
+ auto it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
if (it != XLineManagers.end())
XLineManagers.erase(it);
}
void XLineManager::CheckAll(User *u)
{
- for (std::list<XLineManager *>::iterator it = XLineManagers.begin(), it_end = XLineManagers.end(); it != it_end; ++it)
- {
- XLineManager *xlm = *it;
-
+ for (XLineManager *xlm : XLineManagers)
if (xlm->CheckAllXLines(u))
break;
- }
}
Anope::string XLineManager::GenerateUID()
{
Anope::string id;
- int count = 0;
- do
- {
- id.clear();
- if (++count > 10)
- {
- Log(LOG_DEBUG) << "Unable to generate XLine UID";
- break;
- }
-
- for (int i = 0; i < 10; ++i)
- {
- char c;
- do
- c = (rand() % 75) + 48;
- while (!isupper(c) && !isdigit(c));
- id += c;
- }
+ for (int i = 0; i < 10; ++i)
+ {
+ char c;
+ do
+ c = (rand() % 75) + 48;
+ while (!isupper(c) && !isdigit(c));
+ id += c;
}
- while (XLinesByUID->count(id) > 0);
return id;
}
-XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, "XLineManager", xname), type(t), xlines("XLine")
+XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, NAME, xname), type(t)
{
}
@@ -270,147 +265,82 @@ XLineManager::~XLineManager()
this->Clear();
}
-const char &XLineManager::Type()
+char XLineManager::Type()
{
return this->type;
}
-size_t XLineManager::GetCount() const
+std::vector<XLine *> XLineManager::GetXLines() const
{
- return this->xlines->size();
-}
+ std::vector<XLine *> xlines;
-const std::vector<XLine *> &XLineManager::GetList() const
-{
- return this->xlines;
-}
+ for (XLine *x : Serialize::GetObjects<XLine *>())
+ if (x->GetType() == this->GetName())
+ xlines.push_back(x);
-void XLineManager::AddXLine(XLine *x)
-{
- if (!x->id.empty())
- XLinesByUID->insert(std::make_pair(x->id, x));
- this->xlines->push_back(x);
- x->manager = this;
+ return xlines;
}
-void XLineManager::RemoveXLine(XLine *x)
-{
- /* called from the destructor */
-
- std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x);
-
- if (!x->id.empty())
- {
- std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->id), it3 = XLinesByUID->upper_bound(x->id);
- for (; it2 != XLinesByUID->end() && it2 != it3; ++it2)
- if (it2->second == x)
- {
- XLinesByUID->erase(it2);
- break;
- }
- }
-
- if (it != this->xlines->end())
- {
- this->SendDel(x);
- this->xlines->erase(it);
- }
-}
-
-bool XLineManager::DelXLine(XLine *x)
+void XLineManager::AddXLine(XLine *x)
{
- std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x);
-
- if (!x->id.empty())
- {
- std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->id), it3 = XLinesByUID->upper_bound(x->id);
- for (; it2 != XLinesByUID->end() && it2 != it3; ++it2)
- if (it2->second == x)
- {
- XLinesByUID->erase(it2);
- break;
- }
- }
-
- if (it != this->xlines->end())
- {
- this->SendDel(x);
-
- x->manager = NULL; // Don't call remove
- delete x;
- this->xlines->erase(it);
-
- return true;
- }
-
- return false;
+ x->SetType(this->GetName());
}
XLine* XLineManager::GetEntry(unsigned index)
{
- if (index >= this->xlines->size())
- return NULL;
+ std::vector<XLine *> xlines = GetXLines();
+
+ if (index >= xlines.size())
+ return nullptr;
- XLine *x = this->xlines->at(index);
- x->QueueUpdate();
- return x;
+ return xlines.at(index);
}
void XLineManager::Clear()
{
- std::vector<XLine *> xl;
- this->xlines->swap(xl);
-
- for (unsigned i = 0; i < xl.size(); ++i)
- {
- XLine *x = xl[i];
- if (!x->id.empty())
- XLinesByUID->erase(x->id);
- delete x;
- }
+ for (XLine *x : GetXLines())
+ x->Delete();
}
bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason)
{
- for (unsigned i = this->GetCount(); i > 0; --i)
+ for (XLine *x : GetXLines())
{
- XLine *x = this->GetEntry(i - 1);
-
- if (x->mask.equals_ci(mask))
+ if (x->GetMask().equals_ci(mask))
{
- if (!x->expires || x->expires >= expires)
+ if (!x->GetExpires() || x->GetExpires() >= expires)
{
- if (x->reason != reason)
+ if (x->GetReason() != reason)
{
- x->reason = reason;
- source.Reply(_("Reason for %s updated."), x->mask.c_str());
+ x->SetReason(reason);
+ source.Reply(_("Reason for %s updated."), x->GetMask().c_str());
}
else
source.Reply(_("%s already exists."), mask.c_str());
}
else
{
- x->expires = expires;
- if (x->reason != reason)
+ x->SetExpires(expires);
+ if (x->GetReason() != reason)
{
- x->reason = reason;
- source.Reply(_("Expiry and reason updated for %s."), x->mask.c_str());
+ x->SetReason(reason);
+ source.Reply(_("Expiry and reason updated for %s."), x->GetMask().c_str());
}
else
- source.Reply(_("Expiry for %s updated."), x->mask.c_str());
+ source.Reply(_("Expiry for %s updated."), x->GetMask().c_str());
}
return false;
}
- else if (Anope::Match(mask, x->mask) && (!x->expires || x->expires >= expires))
+ else if (Anope::Match(mask, x->GetMask()) && (!x->GetExpires() || x->GetExpires() >= expires))
{
- source.Reply(_("%s is already covered by %s."), mask.c_str(), x->mask.c_str());
+ source.Reply(_("%s is already covered by %s."), mask.c_str(), x->GetMask().c_str());
return false;
}
- else if (Anope::Match(x->mask, mask) && (!expires || x->expires <= expires))
+ else if (Anope::Match(x->GetMask(), mask) && (!expires || x->GetExpires() <= expires))
{
- source.Reply(_("Removing %s because %s covers it."), x->mask.c_str(), mask.c_str());
- this->DelXLine(x);
+ source.Reply(_("Removing %s because %s covers it."), x->GetMask().c_str(), mask.c_str());
+ x->Delete();
}
}
@@ -419,38 +349,21 @@ bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time
XLine* XLineManager::HasEntry(const Anope::string &mask)
{
- std::multimap<Anope::string, XLine *, ci::less>::iterator it = XLinesByUID->find(mask);
- if (it != XLinesByUID->end())
- for (std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->upper_bound(mask); it != it2; ++it)
- if (it->second->manager == NULL || it->second->manager == this)
- {
- it->second->QueueUpdate();
- return it->second;
- }
- for (unsigned i = 0, end = this->xlines->size(); i < end; ++i)
- {
- XLine *x = this->xlines->at(i);
-
- if (x->mask.equals_ci(mask))
- {
- x->QueueUpdate();
+ for (XLine *x : GetXLines())
+ if (x->GetMask().equals_ci(mask))
return x;
- }
- }
- return NULL;
+ return nullptr;
}
XLine *XLineManager::CheckAllXLines(User *u)
{
- for (unsigned i = this->xlines->size(); i > 0; --i)
+ for (XLine *x : Serialize::GetObjects<XLine *>())
{
- XLine *x = this->xlines->at(i - 1);
-
- if (x->expires && x->expires < Anope::CurTime)
+ if (x->GetExpires() && x->GetExpires() < Anope::CurTime)
{
this->OnExpire(x);
- this->DelXLine(x);
+ x->Delete();
continue;
}
@@ -461,10 +374,10 @@ XLine *XLineManager::CheckAllXLines(User *u)
}
}
- return NULL;
+ return nullptr;
}
-void XLineManager::OnExpire(const XLine *x)
+void XLineManager::OnExpire(XLine *x)
{
}