1
0
mirror of https://github.com/anope/anope.git synced 2026-06-19 23:24:47 +02:00

Compare commits

..

225 Commits

Author SHA1 Message Date
Adam 3a502f2189 Anope 1.9.5 Release 2011-09-09 23:28:58 -04:00
Adam b6dad375a3 Update version.log 2011-09-09 23:28:37 -04:00
Adam 3cbad7f0df Regenerate language files 2011-09-09 23:27:15 -04:00
VisioN b80a0a8d74 Updated Greek language file 2011-09-09 22:27:51 -04:00
Adam f844b0a161 Changed User::IsRecognized check to default to secure 2011-09-09 19:18:43 -04:00
Adam 6bd31b0333 Bug #1330 & many other small fixes 2011-09-08 19:00:30 -04:00
Adam 7de1a7a6d1 Don't try and part service bots twice when channels drop 2011-09-05 18:40:34 -04:00
Adam 3815e7d61e Translate whole messages before splitting them up to send to users 2011-09-03 14:39:12 -04:00
Adam 30e6fc07d6 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-09-03 14:13:14 -04:00
Adam fe1c5d41f9 Bug #1328 - Fixed fantasy to re-split message parameters correctly 2011-09-03 14:10:48 -04:00
lethality fa5ba63542 Fixed a typo in the OperServ Global command 2011-09-03 13:44:20 +01:00
Adam 073db54354 Added permission check in cs_sync 2011-09-03 01:29:57 -04:00
DukePyrolator ef10b5a834 Fixed operserv global 2011-09-03 06:58:49 +02:00
Adam 1c5ff92c93 Changed a few fatal exceptions to shutdown a bit more gracefully 2011-08-29 17:08:26 -04:00
Adam b24ea29bf5 Fixed the /ms del message sent to users when they use /ms read 2011-08-29 16:13:37 -04:00
Adam 5cf3ddb7b1 Made config rehashing not wipe opers configured with opersev/oper 2011-08-29 16:03:33 -04:00
Adam 1e1a41f0e7 Added missing ` in docs/LANGUAGE 2011-08-27 20:58:09 -04:00
Adam 28e8190e6b Fixed some cmake warnings 2011-08-27 20:47:30 -04:00
Adam 670c928a9f Tweaked the access operators to allow superadmins to be > channel founders 2011-08-27 17:13:28 -04:00
Adam d07a69278d Fixed /cs clone to set botmodes on the botserv bot when cloning channels 2011-08-27 16:52:07 -04:00
Adam bb52530eb2 Fixed mlock with param modes if you change (but not unset) the mode 2011-08-27 16:45:14 -04:00
Adam 309dfa36e7 Fixed a few mysql problems, including bug #1326 2011-08-27 16:14:04 -04:00
Adam 5c57f5aa0b Fixed /ns logout on other users 2011-08-27 15:34:09 -04:00
Adam a36e575500 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-08-25 19:01:40 -04:00
Adam 8702031bcd Set the creator of default mlocks to the channel founder when a channel is registered 2011-08-25 19:01:01 -04:00
Adam 1571508aac Only match users against the more "serious" extbans (ones which prevent users from joining) 2011-08-25 10:16:56 +02:00
DukePyrolator 6dacec22a4 guested nicks are now logged out from the recovered account on /nickserv recover 2011-08-24 21:11:23 +02:00
Adam fdbbea2609 Fixed cs_set_misc 2011-08-24 14:27:01 -04:00
Adam dffed5a259 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-08-24 13:57:56 -04:00
Adam 5d681a74ad Clear NS_HELD from nicks when recover expiry is up 2011-08-24 13:56:48 -04:00
DukePyrolator d80e00f5d7 Fixed automatic fingerprint identify on nickchange between registered nicks 2011-08-24 13:57:40 +02:00
Adam 21a8bff011 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-08-23 19:04:27 -04:00
Adam fb14f7706c Set os_session as having first priority for events 2011-08-23 19:03:04 -04:00
DukePyrolator 2284c31f90 Replaced some chanserv/forbid with operserv/forbid in example.conf and added a check for ForceForbidReason in os_forbid 2011-08-23 11:42:40 +02:00
Adam b5b2c42242 Removed this ondeleteobject event, was for m_async_commands which died 2011-08-22 17:14:18 -04:00
Adam a2f92b642c Fixed the db_mysql metadata load events to use the right keys 2011-08-22 13:14:08 -04:00
Adam c996356fab Bugs #1321 & 1322 2011-08-21 16:35:22 -04:00
Adam d71ae412bb Fixed /cs access add log message to not show override for channel founders 2011-08-21 14:54:06 -04:00
Adam 68a125bf6e Fixed ns_set_misc and cs_set_misc to allow unsetting values 2011-08-21 14:33:11 -04:00
Adam 37c7ca8b87 Fixed AddAkiller 2011-08-21 14:09:55 -04:00
Adam 4663970722 Removed m_async_commands, it can still cause crashes from invalid pointers on the stack & is a giant mess anyway 2011-08-20 00:57:35 -04:00
Adam a68d17c17e Moved the ERROR log message out of debug 2011-08-20 00:51:39 -04:00
Adam fa3b74a5b4 Fixed zlines to only add the xline host, fixed db_mysql's write function, and prevent adding multiple of the same nick to access lists 2011-08-20 00:50:26 -04:00
Adam fd999b996f Fixed some problems with deleting access 2011-08-19 16:14:26 -04:00
Adam b4f57247b8 Fixed AccessGroup::operator> fail 2011-08-19 04:20:11 -04:00
DukePyrolator abdc69aa94 added some log message for automatic fingerprint identify and removed a unused function from ns_cert 2011-08-19 09:07:19 +02:00
Adam 1b02216f2d Fixed crash in /cs mode 2011-08-18 23:08:27 -04:00
Adam db340f96d6 Fixed some permission checking fail in modules that got messed up from the big commands sed 2011-08-18 22:04:59 -04:00
Adam 0cdca534a8 Moved CA_TOPIC to qop aswell. Newer channels (default) to TOPIC at 5 but older channels will remain at founder only, causing access list to think newer aop are level 10000 due to having this permission on older channels. 2011-08-18 17:30:49 -04:00
Adam 71b9bbd1ac Bug #1315 - moved CA_ASSIGN permission from sop to qop 2011-08-18 16:48:51 -04:00
DukePyrolator 2f3969b4be Bug #1317 - fixed sha1 fingerprint hashes in the inspircd protocol modules 2011-08-18 07:59:58 +02:00
Adam ff7479f437 Fixed attaching to events in db_mysql & possibly having ChannelInfo::WhoSends return NULL if there really are *no* bots 2011-08-18 00:47:34 -04:00
Adam 487d828fa0 Actually made the nickserv block optional 2011-08-17 22:05:47 -04:00
Adam f41081ba51 Include when an access entry was created in access view 2011-08-17 21:41:30 -04:00
Adam ede910d655 Made /os oper info also show all inherited commands/privs 2011-08-17 15:56:40 -04:00
Adam 0f4c9a43b3 List supported languages in /ns help saset language 2011-08-16 16:38:42 -04:00
Adam 9aa414b1f6 Fixed matching acount access entries against nicknames 2011-08-16 15:28:21 -04:00
Adam 2d9ddb065f Bug #1316 - added permissions for hs_request commands 2011-08-16 13:43:01 -04:00
Adam 1f542e1e75 Moved cs_seens data purger log message to debug 2011-08-16 00:16:00 -04:00
Adam 68e0d99f62 Fixed select()ing 0 sockets on Windows 2011-08-16 00:09:09 -04:00
Adam f43287f43d Fixed grammar problem in cs_clone 2011-08-14 22:10:17 -04:00
Adam 2e7bd6498f Fixed /cs clone access 2011-08-14 21:46:14 -04:00
Adam 786397f77d Massive cleanup of cs_seen, added help, syntax messages, command descriptions, removed lots of dead code, fixed memory leaks, etc 2011-08-14 21:33:07 -04:00
Adam 960c339a4c Brought back the old 1.7 behavior of a level -1 matching all users and 0 matching all identified users 2011-08-14 18:50:22 -04:00
Adam fddb2304c6 Bug #1312, fixed loading autoowner from db_plain 2011-08-14 17:01:28 -04:00
Adam 1b8dc4d096 Fixed updating exceptions 2011-08-14 16:34:20 -04:00
Adam fcc03f4ed8 Do not put users hosts in session akills 2011-08-14 15:59:14 -04:00
Adam 78b8b30766 Fixed resolving hosts when connecting to our uplink 2011-08-14 15:27:20 -04:00
Adam 91d8cc4c5b Revert "Fixed resolving hosts on connect"
This reverts commit 11619be8b9.
2011-08-14 15:25:02 -04:00
DukePyrolator 11619be8b9 Fixed resolving hosts on connect 2011-08-14 21:21:50 +02:00
Adam e767ded69f Fixed default settings for log blocks 2011-08-14 01:01:38 -04:00
Adam 83a579fb9a Fixed number list position when requesting custom lists from akill 2011-08-13 23:05:30 -04:00
DukePyrolator 244f87917c Fixed permission check in botserv set 2011-08-13 20:00:45 +02:00
Adam 6f0da68915 Fixed anope_os_core insert statement 2011-08-13 09:43:38 -04:00
Adam af438527e9 Fixed /cs saset noexpire syntax 2011-08-13 09:27:42 -04:00
Adam ad4c4e462b Send replies back to uses after m_ldap_authentication processes 2011-08-12 13:08:53 -04:00
Adam ed33a4f75b Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-08-12 12:48:29 -04:00
Adam f3d7d4ee37 Track when our clients are introduced or not 2011-08-12 12:46:11 -04:00
DukePyrolator bd4916ee84 Fixed loading/saving XLines in db_plain 2011-08-12 14:54:31 +02:00
Adam feee50e695 Allow bot usermodes to be configurable 2011-08-12 03:13:56 -04:00
Adam 54710a782b Removed the unused ChannelModeBan code 2011-08-12 01:51:14 -04:00
Adam d44a1d0867 Fixed Windows runtime problems 2011-08-11 23:10:08 -04:00
DukePyrolator c2780e1de4 Added a separate field for last seen realhost to ns_info, shown to services admins only 2011-08-11 22:21:40 +02:00
DukePyrolator 4e1f54ff9c added cs_seen 2011-08-11 07:03:20 +02:00
Adam 3755bf5bcd Ignore SIGPIPE 2011-08-10 15:50:45 -04:00
Adam 25d422d32b Fixed flags +* and -* 2011-08-10 15:47:02 -04:00
Adam 697bc8d8e8 Added a services.host define to easily change every clients hostname 2011-08-10 05:05:09 -04:00
Adam 4bdc9824a0 Added two missing files 2011-08-10 01:34:14 -04:00
Adam ded98ed3de Fixed windows build 2011-08-10 01:32:07 -04:00
Adam 13bcc4ef14 Replace the old sigaction for a signal when our Signal destructs 2011-08-10 00:28:31 -04:00
Adam ce92c9b21b Remove +P from unregistered channels if persist is set 2011-08-09 22:18:31 -04:00
Adam b332fbd7a7 Fixed parsing TMODE on ratbox 2011-08-09 18:34:17 -04:00
Adam eaf4e69cf1 Updated Changes 2011-08-09 17:07:20 -04:00
DukePyrolator 2f67c704fe fixed the operserv forbid del command 2011-08-09 16:38:10 +02:00
Jens Voß 8348392af2 fixed wrong syntax-message for botserv set msg 2011-08-09 13:36:33 +02:00
Adam 8116ad9b28 Added forgotten founder checks to cs_access, fixed fantasy replies to come from the right service, and fixed the accessgroup operators to acount for founder/superadmin 2011-08-09 04:38:35 -04:00
Adam cb7435982c Fixed a typo in init.cpp 2011-08-09 01:56:08 -04:00
Adam 776583a665 Simiplied a bit of the access system 2011-08-09 01:55:34 -04:00
Adam 91c3363c15 Hopefully sort this AccessGroup::HasPriv once and for all 2011-08-09 00:06:44 -04:00
Adam b7542fd6f2 Added a few sanity checks which never really should happen to db-convert 2011-08-08 23:41:03 -04:00
Adam 0c860a77c0 Fixed CMakeLists.txt detecting epoll 2011-08-08 23:32:52 -04:00
Adam 2d591f7f59 When we split from the uplink send a quit for *all* of our clients not just bots 2011-08-08 20:34:27 -04:00
lethality 9cb96f3bfb Merge branch '1.9' of ssh://anope.git.sf.net/gitroot/anope/anope into 1.9 2011-08-08 06:24:29 +01:00
lethality 286a9edb1e Standardized some of the SyntaxError/Help replies and corrected some syntax in BotServ set 2011-08-08 06:19:35 +01:00
Adam c4da496834 Copy modules to the runtime directory in one big read/write if we can instead of this 1 byte at a time thing, significantly improves startup loading time. 2011-08-08 00:32:09 -04:00
Adam ade92395a0 Fixed the pipengines 2011-08-07 22:34:16 -04:00
Adam c6741d3765 Always reset the levels of newly created channels, fixed DetermineLevel matching ACCESS_INVALID levels, and added in a disabled config option for levels 2011-08-07 19:04:27 -04:00
Adam 25e3408ff6 Fixed generating sid on startup 2011-08-07 17:43:23 -04:00
Adam 35588cc521 Made botserv bots with no commands just ignore messages to them, and made bots only tell users to use HELP if they have a HELP command 2011-08-07 16:04:40 -04:00
Adam 32bb63f047 Updated tables.sql 2011-08-07 15:56:35 -04:00
Adam 27912e1e8f Fixed two of the xop log messages 2011-08-06 19:43:06 -04:00
Adam b678aa64d8 Give channel founders +qo by default 2011-08-06 19:41:37 -04:00
Adam c3e9fc4a8d Show channel founders their channels in /ns alist 2011-08-06 18:33:44 -04:00
Adam 66ab59d163 Fixed loading older access entries 2011-08-06 18:21:59 -04:00
Adam deb79e830d sed'd a few typos 2011-08-06 18:05:16 -04:00
Adam a6dd65f916 Fixed suepradmin 2011-08-06 17:33:59 -04:00
Adam 0448e386de Document what /os oline does 2011-08-06 16:49:55 -04:00
Adam 749de0054f Update last used times on channels when someone with access uses them 2011-08-06 04:32:50 -04:00
Adam 7849667a19 Added a define{} block which can be used to easially rename things 2011-08-06 04:16:10 -04:00
lethality e03efdee97 Fixed ns_ajoin to check if adding a duplicate channel 2011-08-06 00:31:24 +01:00
lethality d6a8d27265 Fixed an error and typo in CS SET OPNOTICE 2011-08-05 16:07:41 +01:00
Adam 5e18a7292b Mark the new commands/ modules as CORE and fixed a typo in the example.conf 2011-08-05 06:18:38 -04:00
Adam e66063e630 Rewrote the example configurations and split them
up into seperate files for each pseudo client.

Also reorganized how the modules are stored, and
made most of the old "extra" modules "core"
2011-08-05 05:35:31 -04:00
Adam 9ec18a3b02 Added a command:permission setting 2011-08-04 21:59:01 -04:00
Adam 773a1f3075 Updated a bit of the TODO 2011-08-04 16:41:36 -04:00
Adam b3f4ba0082 Start the ts6 sid generator off at 00A if none is given 2011-08-03 06:09:27 -04:00
Adam 34da226bd9 Generate random SIDs for us if one is not specified 2011-08-03 05:54:03 -04:00
Adam 16280f4f7f Added operserv/kill and removed version.h from .gitignore 2011-08-03 05:42:41 -04:00
Adam 42f954ff7d Fixed reintroducing our clients if we disconnect and reconnect to the uplink 2011-08-02 22:39:14 -04:00
Adam 09f5591aba Fixed /cs clone copying channel access, fixed restricted, and fixed some compiler warnings 2011-08-02 05:07:59 -04:00
Adam f690cd802e Made /ns info default to your account or your nick if no arguments are given 2011-08-02 02:02:13 -04:00
Adam d43e1fb800 Added opertype:modes 2011-08-02 01:50:09 -04:00
Adam 41b40f6504 Split /os mode into /os mode and /os umode to make giving permission to just one possible 2011-08-01 23:42:20 -04:00
Adam f7adc0b35b Rewrote the access systems and added a flags access system 2011-08-01 22:37:27 -04:00
lethality 710c02f3bd Fixed bug #1301 - Changed operserv/staff to reflect its renaming to operserv/oper 2011-07-31 19:11:26 +01:00
lethality 7f69d2b95f Fixed bug #1300 2011-07-31 14:41:59 +01:00
Adam a18e3f3380 Bugs 1297-1299 and made /os stats work like the help describes it does 2011-07-31 07:00:27 -04:00
Adam 63a4201d15 Fixed these ModuleManager::Attach calls once and for all.. 2011-07-31 06:24:24 -04:00
Adam b751800ff4 Fixed os_defcon 2011-07-31 06:24:11 -04:00
Adam f32149117a Fixed error message from being unable to connect 2011-07-31 04:00:35 -04:00
Adam 1cb11bba5d Fixed a few small problems, including m_ssl's connect feature sometimes failing for no good reason 2011-07-31 03:22:23 -04:00
lethality f29c88bcd5 Fixed bug #1294, Crash on NS SET HIDE 2011-07-29 22:50:45 +01:00
lethality f5e78d7c88 Fixed a typo in the nickserv/auspex oper privilege 2011-07-28 07:06:08 +01:00
lethality 25c4985518 Fixed OS LOGONNEWS 2011-07-28 06:36:29 +01:00
Adam cd4f6da735 Bug #1289 - Fixed hooking to delcore event in cs_main 2011-07-27 19:24:58 -04:00
Adam 6e032ded6e Bug #1288 - Fixed crash on /cs help access 2011-07-27 19:17:21 -04:00
Adam e2b47e001f Bug #1291 - fixed parsing JOIN on ratbox 2011-07-27 19:06:42 -04:00
lethality b32c961c2e Show the description in cs help set instead of the syntax 2011-07-27 16:54:50 +01:00
Adam 088337ea07 Fixed /os ignore, /os exception del, and a crash in /cs entrymsg 2011-07-26 23:18:54 -04:00
Adam e8c00b9e8b A few small fixes 2011-07-26 05:44:14 -04:00
lethality 023d4b44ec Fixed a typo that broke CS SET RESTRICTD and re-added abbreviation for CS SET DESC 2011-07-23 13:22:56 +01:00
Charles Kingsley 87d2f4b8d7 Fix couple of typos in modules 2011-07-23 13:07:19 +01:00
lethality 39ca53cfcf Fixed hs_request and corrected a typo(?) in hs activate 2011-07-17 21:58:27 +01:00
lethality 46f2f3bd8f Fixed some of the extra modules 2011-07-17 13:08:15 +01:00
Adam cb56d50837 Fixed up cs_set_misc and ns_set_misc 2011-07-17 06:08:35 -04:00
Adam b19dddb0f6 Fixed a few of the /cs set syntax messages to reflect the new syntax 2011-07-16 07:03:04 -04:00
Adam acceabe3a8 Bug #1287 - Only check if users should be deopped on syncing channels
when the user is on a server that is also syncing.

This prevents us from deopping all users who join a new channel
when recovering from a netsplit that don't explicitly have access
to that channel.
2011-07-16 06:52:13 -04:00
Adam c3993b3123 Fixed appending !*@* to some access list entries that are valid hosts 2011-07-14 22:37:46 -04:00
Adam f277be0f26 Fixed OSOpersOnly & CSOpersOnly 2011-07-14 21:40:21 -04:00
Adam 1a2486d2ec These .pot files don't need to be under version control 2011-07-14 20:52:24 -04:00
Adam a735095965 Added cs_sync 2011-07-14 20:00:39 -04:00
Adam ef75e171bc Added bs_autoassign 2011-07-14 19:11:13 -04:00
Adam 5bf7dee559 Made channel descriptions optional 2011-07-14 18:29:03 -04:00
Adam f858164dee Rewrote how commands are handled within Anope.
This allows naming commands and having spaces within command names.
2011-07-14 02:31:12 -04:00
Adam 924f6849fe Bug #1283 - Upped the buffer used for messge replies, as some can be really big 2011-07-10 19:32:10 -04:00
Adam b5ec57a3f9 Bug #1285 - Fixed setting -P on channels with only a service bot in it 2011-07-10 19:07:45 -04:00
Adam 6d978486cd Bug #1286 - Dont allow actions to mess up the caps kicker 2011-07-10 18:27:48 -04:00
Adam d2832b1045 Use getrlimit instead of ulimit, fixes freebsd build 2011-07-07 02:23:11 -04:00
Adam 1a4fc39d7b Do not send news when a server is syncing 2011-07-06 22:06:07 -04:00
Adam 97388abb99 Fixed /hs set and /hs setall not allowing only a host 2011-07-06 22:05:01 -04:00
Adam 57ec310512 Only call send once per write event in dns manager 2011-07-06 05:20:25 -04:00
Adam ffd5c045e4 Fixed chanserv/access/modify permission on non-xop channels 2011-07-06 00:33:25 -04:00
Adam cc3c2b6999 Send account data once an account is confirmed 2011-07-05 01:39:11 -04:00
Adam c549aa4e76 Bug #1279 - Fixed strftime 2011-07-04 22:39:13 -04:00
Adam 714831b249 Bug #1282 2011-07-04 22:34:21 -04:00
Adam d6879c4a25 Bug #1280 - Fixed reading some na and bi flags in db_plain 2011-07-04 14:25:13 -04:00
Adam 2caf5868d0 Clean up some of the dns code, udp is connectionless anyway so this isnt required 2011-07-03 00:19:54 -04:00
Adam c585964e60 Fixed the mode manager from complaining about prefixless modes on insp20 2011-06-27 19:14:30 -04:00
Adam 936a50df23 Fixed build on older cmake versions 2011-06-27 15:35:09 -04:00
Adam 3e9888092a Fixed mail delay time 2011-06-24 03:40:18 -04:00
Adam 821826a566 The other part of #1277 2011-06-24 02:58:40 -04:00
Adam 7ec803f610 Bug #1277 - Dont send account data for unconfirmed nicks 2011-06-23 15:31:57 -04:00
Adam b1a075b462 Fixed bug #1276 and some other valgrind warnings 2011-06-23 15:10:50 -04:00
Adam 3be75cbcb3 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-06-20 23:28:25 -04:00
Adam 2667f9046e Cleaned up some of the logger code which fixes not logging debug logs to files etc when debug is enabled, and some other small things 2011-06-20 23:25:46 -04:00
Naram Qashat 2601871391 Fix long-standing issue with the get token functions if the delimiter wasn't found in the string but you wanted the first "token". 2011-06-20 23:09:03 -04:00
Adam a3d0ab3d09 Use case insensitive matching when looking up servers by name 2011-06-20 23:00:49 -04:00
Adam a1b36ec0a5 Search all domains for language strings, fixes the mess that we used to use to translate strings in 3rd party modules 2011-06-17 19:57:43 -04:00
Adam 48e995ddf2 Bug #1275 - Don't log absolutely everything sent to operserv, most of its commands already have their own logs 2011-06-17 13:34:47 -04:00
Adam df971befb2 Fixed a few small things 2011-06-14 18:23:53 -04:00
DukePyrolator 1cd65878db changed some _() to gtl() and updated do_strftime() and duration() 2011-06-13 18:20:22 +02:00
DukePyrolator 6148ffa669 added a Anope::string::capacity() function 2011-06-12 06:28:22 +02:00
DukePyrolator 717b4c3406 small improvement for Timer::SetSecs() 2011-06-09 06:16:31 +02:00
DukePyrolator 74361bec05 added a Timer::SetSecs() function 2011-06-07 06:16:57 +02:00
Adam a087e7f664 Fixed clearing bandata 2011-06-05 18:18:50 -04:00
Adam 3ad93a31c9 Burst our channels with the uplink when we connect & fixed bug #1274 2011-06-02 14:59:34 -04:00
Adam 184b346166 Place version.h in build/ not include/ 2011-06-02 12:45:08 -04:00
Adam b2c807dc8c Fixed /ns alist 2011-05-30 13:14:33 -04:00
Adam 60548aa00b Fixed ns_update and db_mysql_live sql queries 2011-05-29 19:05:28 -04:00
Adam a45d1555d3 Added an IsServicesOper event 2011-05-23 14:47:14 -04:00
Adam 121ae0b189 Added m_statusupdate 2011-05-23 13:32:01 -04:00
Adam 8bf8832b70 Rewrote the signal handling to use sigaction 2011-05-23 04:41:51 -04:00
DukePyrolator 4dd7e261f5 fixed a possible crash on database saving 2011-05-22 09:05:21 +02:00
Adam f4329df11c Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-05-21 15:33:10 -04:00
Adam 98729a6c78 Bug #1271 2011-05-21 15:32:47 -04:00
DukePyrolator 742ba970b0 fixed bug #1272 2011-05-21 15:15:46 +02:00
Adam 115f94bfc2 Made Anope able to process normally when disconnected from the uplink and not sleep(), enable usage of non-blocking connect() and default all sockets to non blocking mode. Some cleanup to m_ssl and some cleanup to main.cpp. 2011-05-21 04:57:27 -04:00
Adam 7e5727288d Fixed compile from the earlier merge 2011-05-19 20:36:39 -04:00
Adam 13915d8b57 Modularized os_news 2011-05-16 04:10:18 -04:00
Adam 9962fae1a1 Calculate nc::channelcount at runtime 2011-05-16 04:10:18 -04:00
Adam 9fcbe293e2 Added os_oper 2011-05-16 04:10:18 -04:00
Adam fd4b52ec38 Added os_forbid 2011-05-16 04:10:18 -04:00
Adam b59602abf8 Check for a valid server in /operserv noop 2011-05-16 04:10:18 -04:00
Adam fd21c36725 Fixed some logic fail in ts6_uid_retrieve 2011-05-16 04:10:18 -04:00
Adam b999c6ca53 Expand more on m_alias and changed some std::string usage in sockets.cpp to use Anope::string 2011-05-16 04:10:15 -04:00
Adam 583954d3a1 Use module type to determine what type each module is instead of its location in the configuration file. 2011-05-16 04:09:32 -04:00
Adam 8fb1604f64 Fixed reading empty config values in the multiconfig code, caused by removal of DT_CHARPTR 2011-05-16 04:09:07 -04:00
Adam 284af258bf Added more useful functions to our LDAP API, allow adding newly registered accounts to LDAP, removed some unnecessary OnPre events and fixed unloading all modules 2011-05-16 04:09:07 -04:00
Adam e7887c1f01 Unmodularized the socket engine because its causing problems and really is unnecessary 2011-05-16 04:08:47 -04:00
Adam 076ebafa1b Moved some global functions to be member functions and misc cleanup 2011-05-16 04:07:56 -04:00
Adam 6922bd239c Fixed up the MySQL Query code and finished some command code I forgot earlier 2011-05-16 04:07:30 -04:00
Adam 13aa58ce5d Removed DT_CHARPTR from the config reader, its unneeded 2011-05-16 04:06:22 -04:00
Adam c8c23158a4 Moved the core pseudo clients out into their own modules 2011-05-16 04:06:17 -04:00
Adam 1782ce260c Use std::map instead of unordered_map 2011-05-16 04:01:50 -04:00
Adam b28d3746f5 Branch for 1.9.5 2011-05-16 04:01:46 -04:00
391 changed files with 138625 additions and 136665 deletions
-1
View File
@@ -1,4 +1,3 @@
config.cache
include/version.h
include/sysconf.h
build/
+3 -4
View File
@@ -222,7 +222,7 @@ option(USE_RUN_CC_PL "Use run-cc.pl for building" OFF)
# 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)
include_directories(${Anope_BINARY_DIR}/include ${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/language ${Anope_SOURCE_DIR}/modules/pseudoclients)
# If using Windows, always add the _WIN32 define
if(WIN32)
@@ -337,11 +337,10 @@ check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
check_function_exists(setgrent HAVE_SETGRENT)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(stricmp HAVE_STRICMP)
check_function_exists(strlcat HAVE_STRLCAT)
check_function_exists(strlcpy HAVE_STRLCPY)
check_function_exists(umask HAVE_UMASK)
check_function_exists(backtrace HAVE_BACKTRACE)
check_function_exists(eventfd HAVE_EVENTFD)
check_function_exists(epoll_wait HAVE_EPOLL)
check_function_exists(poll HAVE_POLL)
# Check for the existance of the following types
check_type_size(uint8_t UINT8_T)
+8 -2
View File
@@ -178,11 +178,17 @@ if [ ! "$NO_INTRO" ] ; then
if [ -d .git ] ; then
VERSION=`git describe --tags`
VERSION_BUILD=`echo "$VERSION" | cut -d'-' -f2`
if [ "$SOURCE_DIR" = "." ] ; then
test -d build || mkdir -p build/include
BUILD_DIR="build"
else
BUILD_DIR="."
fi
VERSION_EXTRA=`echo "$VERSION" | cut -d'-' -f3`
# Only do this if we are not on a tag, src/version.sh will be all we need then.
if [ "$VERSION_BUILD" != "$VERSION_EXTRA" ] ; then
echo "#define VERSION_BUILD $VERSION_BUILD" > include/version.h
echo "#define VERSION_EXTRA \"-$VERSION_EXTRA\"" >> include/version.h
echo "#define VERSION_BUILD $VERSION_BUILD" > $BUILD_DIR/include/version.h
echo "#define VERSION_EXTRA \"-$VERSION_EXTRA\"" >> $BUILD_DIR/include/version.h
fi
fi
cat $SOURCE_DIR/.BANNER | sed "s/CURVER/$VERSION/" | sed "s@SOURCE_DIR@$SOURCE_DIR@" | $PAGER
+1 -1
View File
@@ -1,6 +1,6 @@
# Only install example.chk and example.conf from this directory
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
set(DATA example.chk example.conf mysql/tables.sql)
set(DATA example.chk tables.sql 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)
install(FILES ${DATA}
DESTINATION data
)
+240
View File
@@ -0,0 +1,240 @@
/*
* Example configuration file for BotServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the BotServ client
*/
nick = "BotServ"
/*
* The username of the BotServ client.
*/
user = "services"
/*
* The hostname of the BotServ client.
*/
host = "services.host"
/*
* The realname of the BotServ client.
*/
gecos = "Bot Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core BotServ module.
*
* Provides essential functionality for BotServ.
*/
module { name = "bs_main" }
/*
* Configuration for BotServ provided by bs_main.
*/
botserv
{
/*
* The name of the client that should be BotServ.
*/
name = "BotServ"
/*
* The default bot options for newly registered channels. Note that changing these options
* will have no effect on channels which are already registered. The list must be separated
* by spaces.
*
* The options are:
* - dontkickops: Channel operators will be protected against BotServ kicks
* - dontkickvoices: Voiced users will be protected against BotServ kicks
* - greet: The channel's BotServ bot will greet incoming users that have set a greet
* in their NickServ settings
* - fantasy: Enables the use of BotServ fantasy commands in the channel
*
* This directive is optional, if left blank, there will be no defaults.
*/
defaults="greet fantasy"
/*
* The minimum number of users there must be in a channel before the bot joins it. The best
* value for this setting is 1 or 2. This can be 0, the service bots will not part unless
* specifically unassigned, and will keep the channel open.
*/
minusers = 1
/*
* The maximum number of entries a single bad words list can have. Setting it too high can
* reduce performance slightly.
*/
badwordsmax = 32
/*
* The amount of time that data for a user is valid in BotServ. If the data exceeds this time,
* it is reset or deleted depending on the case. Do not set it too high, otherwise your
* resources will be slightly affected.
*/
keepdata = 10m
/*
* The bots are currently not affected by any modes or bans when they try to join a channel.
* But some people may want to make it act like a real bot, that is, for example, remove all
* the bans affecting the bot before joining the channel, remove a ban that affects the bot
* set by a user when it is in the channel, and so on. Since it consumes a bit more CPU
* time, you should not enable this on larger networks.
*
* This directive is optional.
*/
#smartjoin = yes
/*
* If set, the bots will use a kick reason that does not state the word when it is kicking.
* This is especially useful if you have young people on your network.
*
* This directive is optional.
*/
gentlebadwordreason = yes
/*
* If set, BotServ will use case sensitive checking for badwords.
*
* This directive is optional.
*/
#casesensitive = yes
/*
* Defines the prefix for fantasy commands in channels. This character will have to be prepended
* to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
* "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
*/
#fantasycharacter = "!"
}
/*
* Core BotServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "BotServ"; name = "HELP"; command = "generic/help"; }
/*
* bs_assign
*
* Provides the commands botserv/assign and botserv/unassign.
*
* Used for assigning and unassigning bots to channels.
*/
module { name = "bs_assign" }
command { service = "BotServ"; name = "ASSIGN"; command = "botserv/assign"; }
command { service = "BotServ"; name = "UNASSIGN"; command = "botserv/unassign"; }
/*
* bs_autoassign
*
* Allows service bots to be automatically assigned to channels upon registration.
*/
#module { name = "bs_autoassign" }
bs_autoassign
{
/*
* Automatically assign ChanServ to channels upon registration.
*/
bot = "ChanServ"
}
/*
* bs_badwords
*
* Provides the command botserv/badwords.
*
* Used for controlling the channel badword list.
*/
module { name = "bs_badwords" }
command { service = "BotServ"; name = "BADWORDS"; command = "botserv/badwords"; }
/*
* bs_bot
*
* Provides the command botserv/bot.
*
* Used for administrating BotServ bots.
*/
module { name = "bs_bot" }
command { service = "BotServ"; name = "BOT"; command = "botserv/bot"; }
/*
* bs_botlist
*
* Provides the command botserv/botlist.
*
* Used for listing all available bots.
*/
module { name = "bs_botlist" }
command { service = "BotServ"; name = "BOTLIST"; command = "botserv/botlist"; }
/*
* bs_control
*
* Provides the commands botserv/act and botserv/say.
*
* Used for making the bot message a channel.
*/
module { name = "bs_control" }
command { service = "BotServ"; name = "ACT"; command = "botserv/act"; }
command { service = "BotServ"; name = "SAY"; command = "botserv/say"; }
/*
* bs_info
*
* Provides the command botserv/info.
*
* Used for getting information on bots or channels.
*/
module { name = "bs_info" }
command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
/*
* bs_kick
*
* Provides the command botserv/kick.
*
* Used for configuring what bots should kick for.
*/
module { name = "bs_kick" }
command { service = "BotServ"; name = "KICK"; command = "botserv/kick"; }
/*
* bs_set
*
* Provides the command botserv/set.
*
* Used for setting options such as kickers and fantasy replies.
*/
module { name = "bs_set" }
command { service = "BotServ"; name = "SET"; command = "botserv/set"; }
+752
View File
@@ -0,0 +1,752 @@
/*
* Example configuration file for ChanServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the ChanServ client
*/
nick = "ChanServ"
/*
* The username of the ChanServ client.
*/
user = "services"
/*
* The hostname of the ChanServ client.
*/
host = "services.host"
/*
* The realname of the ChanServ client.
*/
gecos = "Channel Registration Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core ChanServ module.
*
* Provides essential functionality for ChanServ.
*/
module { name = "cs_main" }
/*
* Configuration for ChanServ provided by cs_main.
*/
chanserv
{
/*
* The name of the client that should be ChanServ.
*/
name = "ChanServ"
/*
* The default options for newly registered channels. Note that changing these options
* will have no effect on channels which are already registered. The list must be separated
* by spaces.
*
* The options are:
* - keeptopic: Retain topic when the channel is not in use
* - opnotice: Send a notice when OP/DEOP commands are used
* - peace: Disallow users from kicking or removing modes from others who are of the same
* access level or superior
* - private: Hide the channel from ChanServ's LIST command
* - restricted: Kick/ban users who are restricted from the channel
* - secure: Enable channel security, requiring the user to be identified with NickServ in
* order to be considered for being on the access list of the channel
* - secureops: Only allow operator status to be given if the user is on the access list
* - securefounder: Only allow the real founder of the channel to drop the channel, change it's
* password, or change the founder or successor
* - signkick: Use of ChanServ's KICK command will cause the user's nick to be signed to the kick.
* - signkicklevel: Same as above, but the kick will not be signed if the user is at the same access
* level or superior to the target
* - topiclock: Disallow the topic to be changed except with ChanServ's TOPIC command
* - persist: Keep the channel open at all times
* - none: No defaults
*
* This directive is optional, if left blank, the options will default to keeptopic, secure, securefounder,
* and signkick. If you really want no defaults, use "none" by itself as the option.
*/
defaults="keeptopic peace secure securefounder signkick"
/*
* The maximum number of channels which may be registered to a single nickname.
*
* This directive is optional, but recommended.
* If not set, there will be no restriction on the numbers of channels a single nickname can have registered.
*/
maxregistered = 20
/*
* The length of time before a channel registration expires.
*
* This directive is optional, but recommended.
* If not set, the default is 14 days.
*/
expire = 14d
/*
* The length of time before a suspended channel becomes unsuspended.
*
* This directive is optional.
* If not set, the default is to never.
*/
#suspendexpire = 90d
/*
* The lenth of time before a forbidden channel drops.
*
* This directive is optional.
* If not set, the default is to never.
*/
#forbidexpire = 90d
/*
* The default ban type for newly registered channels (and when importing old databases).
*
* defbantype can be:
*
* 0: ban in the form of *!user@host
* 1: ban in the form of *!*user@host
* 2: ban in the form of *!*@host
* 3: ban in the form of *!*user@*.domain
*/
defbantype = 2
/*
* The maximum number of entries on a channel's access list.
*/
accessmax = 1024
/*
* The maximum number of entries on a channel's autokick list.
*/
autokickmax = 32
/*
* The default reason for an autokick if none is given.
*/
autokickreason = "User has been banned from the channel"
/*
* The length of time ChanServ stays in a channel after kicking a user from a channel they are not
* permitted to be in. This only occurs when the user is the only one in the channel.
*/
inhabit = 15s
/*
* The maximum number of channels to be returned for a ChanServ LIST command.
*/
listmax = 50
/*
* Allow only IRC Operators to use ChanServ.
*
* This directive is optional.
*/
#opersonly = yes
/*
* ChanServ levels configuration, for use with cs_access.
*
* These levels are used by the chanserv/access access system.
* The levels configured below will be used as a default by newly registered channels.
*
* The level "founder" is a special level that means anyone with the level_founder permission
* can use (which of course defaults to "founder"). Anyone with the founder level permission in
* a channel can do anything in the channel.
*
* The level "disabled" is a special level that means the level is disabled, even from people
* with founder level access.
*/
level_change = 10
level_list = 1
level_akick = 10
level_assign = "founder"
level_autohalfop = 4
level_autoop = 5
level_autoowner = 9999
level_autoprotect = 10
level_autovoice = 3
level_badwords = 10
level_ban = 4
level_fantasia = 3
level_founder = "founder"
level_getkey = 5
level_greet = 5
level_halfop = 5
level_halfopme = 4
level_info = 9999
level_invite = 5
level_kick = 4
level_memo = 10
level_mode = 5
level_nokick = 1
level_opdeop = 5
level_opdeopme = 5
level_owner = "founder"
level_ownerme = 9999
level_protect = 9999
level_protectme = 10
level_say = 5
level_signkick = 9999
level_set = 9999
level_topic = 5
level_unban = 4
level_voice = 4
level_voiceme = 3
/*
* ChanServ flags configuration, for use with cs_flags.
*
* These flags are used by the chanserv/flags access system.
*/
flag_change = "f"
flag_list = "l"
flag_akick = "K"
flag_assign = "s"
flag_autohalfop = "H"
flag_autoop = "O"
flag_autoowner = "Q"
flag_autoprotect = "A"
flag_autovoice = "V"
flag_badwords = "k"
flag_ban = "b"
flag_fantasia = "c"
flag_founder = "F"
flag_getkey = "G"
flag_greet = "g"
flag_halfop = "h"
flag_halfopme = "h"
flag_info = "I"
flag_invite = "i"
flag_kick = "k"
flag_memo = "m"
flag_mode = "s"
flag_nokick = "N"
flag_opdeop = "o"
flag_opdeopme = "o"
flag_owner = "q"
flag_ownerme = "q"
flag_protect = "a"
flag_protectme = "a"
flag_say = "B"
flag_set = "s"
flag_signkick = "K"
flag_topic = "t"
flag_unban = "u"
flag_voice = "v"
flag_voiceme = "v"
}
/*
* Core ChanServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "ChanServ"; name = "HELP"; command = "generic/help"; }
/*
* cs_access
*
* Provides commands chanserv/access and chanserv/levels.
* Provides the access system "levels".
*
* Used for giving users access in channels.
*/
module { name = "cs_access" }
command { service = "ChanServ"; name = "ACCESS"; command = "chanserv/access"; }
command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; }
/*
* cs_akick
*
* Provides the command chanserv/akick.
*
* Used for preventing users from joining channels.
*/
module { name = "cs_akick" }
command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; }
/*
* cs_appendtopic
*
* Provides the chanserv/appendtopic command.
*
* Used to append text to existing channel topics.
*/
module { name = "cs_appendtopic" }
command { service = "ChanServ"; name = "APPENDTOPIC"; command = "chanserv/appendtopic"; }
/*
* cs_ban
*
* Provides the command chanserv/ban.
*
* Used for banning users from channels.
*/
module { name = "cs_ban" }
command { service = "ChanServ"; name = "BAN"; command = "chanserv/ban"; }
command { service = "ChanServ"; name = "KB"; command = "chanserv/ban"; }
/*
* cs_clearusers
*
* Provides the command chanserv/clearusers.
*
* Used for kicking all users from channels.
*/
module { name = "cs_clearusers" }
command { service = "ChanServ"; name = "CLEARUSERS"; command = "chanserv/clearusers"; }
/*
* cs_clone
*
* Provides the command chanserv/clone.
*
* Used for copying channel settings from one channel to another.
*/
module { name = "cs_clone" }
command { service = "ChanServ"; name = "CLONE"; command = "chanserv/clone"; }
/*
* cs_drop
*
* Provides the command chanserv/drop.
*
* Used for unregistering channels.
*/
module { name = "cs_drop" }
command { service = "ChanServ"; name = "DROP"; command = "chanserv/drop"; }
/*
* cs_enforce
*
* Provides the command chanserv/enforce.
*
* Used to enforce various channel settings such as secureops and restricted.
*/
module { name = "cs_enforce" }
command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce"; }
/*
* cs_entrymsg
*
* Provides the command chanserv/entrymsg.
*
* Used to configure entry messages sent to users when they join a channel.
*/
module { name = "cs_entrymsg" }
command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; }
cs_entrymsg
{
/* The maximum number of entrymsgs allowed per channel. If not set, defaults to 5. */
maxentries = 5
}
/*
* cs_flags
*
* Provides the command chanserv/flags.
* Provides the access system "flags".
*
* Used for giving users access in channels.
*/
module { name = "cs_flags" }
command { service = "ChanServ"; name = "FLAGS"; command = "chanserv/flags"; }
/*
* cs_getkey
*
* Provides the command chanserv/getkey.
*
* Used for getting the key for channels.
*/
module { name = "cs_getkey" }
command { service = "ChanServ"; name = "GETKEY"; command = "chanserv/getkey"; }
/*
* cs_info
*
* Provides the command chanserv/info.
*
* Used for getting information about channels.
*/
module { name = "cs_info" }
command { service = "ChanServ"; name = "INFO"; command = "chanserv/info"; }
/*
* cs_invite
*
* Provides the command chanserv/invite.
*
* Used for inviting yourself in to channels.
*/
module { name = "cs_invite" }
command { service = "ChanServ"; name = "INVITE"; command = "chanserv/invite"; }
/*
* cs_kick
*
* Provides the command chanserv/kick.
*
* Used for kicking users from channels.
*/
module { name = "cs_kick" }
command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
command { service = "ChanServ"; name = "K"; command = "chanserv/kick"; }
/*
* cs_list
*
* Provides the command chanserv/list.
*
* Used for retrieving and searching the registered channel list.
*/
module { name = "cs_list" }
command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; permission = "chanserv/list"; }
/*
* cs_mode
*
* Provides the command chanserv/mode.
*
* Used for changing mode locks and changing modes.
*/
module { name = "cs_mode" }
command { service = "ChanServ"; name = "MODE"; command = "chanserv/mode"; }
/*
* cs_mode
*
* Provides the commands chanserv/op, chanserv/deop, chanserv/halfop, chanserv/dehalfop
* chanserv/voice, chanserv/devoice, chanserv/protect, chanserv/deprotect,
* chanserv/owner, and chanserv/deowner.
*
* Used for setting and removing modes on users.
*/
module { name = "cs_modes" }
command { service = "ChanServ"; name = "OP"; command = "chanserv/op"; }
command { service = "ChanServ"; name = "DEOP"; command = "chanserv/deop"; }
command { service = "ChanServ"; name = "HALFOP"; command = "chanserv/halfop"; }
command { service = "ChanServ"; name = "DEHALFOP"; command = "chanserv/dehalfop"; }
command { service = "ChanServ"; name = "VOICE"; command = "chanserv/voice"; }
command { service = "ChanServ"; name = "DEVOICE"; command = "chanserv/devoice"; }
command { service = "ChanServ"; name = "PROTECT"; command = "chanserv/protect"; }
command { service = "ChanServ"; name = "DEPROTECT"; command = "chanserv/deprotect"; }
command { service = "ChanServ"; name = "OWNER"; command = "chanserv/owner"; }
command { service = "ChanServ"; name = "DEOWNER"; command = "chanserv/deowner"; }
/*
* cs_register
*
* Provides the commands chanserv/register.
*
* Used for registering channels.
*/
module { name = "cs_register" }
command { service = "ChanServ"; name = "REGISTER"; command = "chanserv/register"; }
/*
* cs_seen
*
* Provides the commands chanserv/seen and operserv/seen.
*
* Records the last time a user was seen and what they were doing and allows users to request this data.
* Also allows administrators to view stats about seen data and purge the database.
*/
module { name = "cs_seen" }
command { service = "ChanServ"; name = "SEEN"; command = "chanserv/seen"; }
#command { service = "OperServ"; name = "SEEN"; command = "operserv/seen"; }
/*
* cs_set
*
* Provides the command chanserv/set.
*
* Is a dummy command to provide a help wrapper for the various SET commands.
*/
module { name = "cs_set" }
command { service = "ChanServ"; name = "SET"; command = "chanserv/set"; }
/*
* cs_saset
*
* Provides the command chanserv/saset.
*
* Is a dummy command to provide a help wrapper for the various SASET commands.
*/
module { name = "cs_saset" }
command { service = "ChanServ"; name = "SASET"; command = "chanserv/saset"; permission = "chanserv/saset"; }
/*
* cs_set_bantype
*
* Provides the commands chanserv/set/bantype and chanserv/saset/bantype.
*
* Used for controlling what format bans are placed on channels.
*/
module { name = "cs_set_bantype" }
command { service = "ChanServ"; name = "SET BANTYPE"; command = "chanserv/set/bantype"; }
command { service = "ChanServ"; name = "SASET BANTYPE"; command = "chanserv/saset/bantype"; permission = "chanserv/saset/bantype"; }
/*
* cs_set_description
*
* Provides the commands chanserv/set/description and chanserv/saset/description.
*
* Used for changing channels descriptions.
*/
module { name = "cs_set_description" }
command { service = "ChanServ"; name = "SET DESCRIPTION"; command = "chanserv/set/description"; }
command { service = "ChanServ"; name = "SET DESC"; command = "chanserv/set/description"; }
command { service = "ChanServ"; name = "SASET DESCRIPTION"; command = "chanserv/saset/description"; permission = "chanserv/saset/description"; }
command { service = "ChanServ"; name = "SASET DESC"; command = "chanserv/saset/description"; permission = "chanserv/saset/description"; }
/*
* cs_set_founder
*
* Provides the commands chanserv/set/founder and chanserv/saset/founder.
*
* Used for changing channel founders.
*/
module { name = "cs_set_founder" }
command { service = "ChanServ"; name = "SET FOUNDER"; command = "chanserv/set/founder"; }
command { service = "ChanServ"; name = "SASET FOUNDER"; command = "chanserv/saset/founder"; permission = "chanserv/saset/founder"; }
/*
* cs_set_keeptopic
*
* Provides the commands chanserv/set/keeptopic and chanserv/saset/keeptopic.
*
* Used for enabling keeptopic on channels, which causes ChanServ to restore the channel topic
* when a channel is created.
*/
module { name = "cs_set_keeptopic" }
command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
command { service = "ChanServ"; name = "SASET KEEPTOPIC"; command = "chanserv/saset/keeptopic"; permission = "chanserv/saset/keeptopic"; }
/*
* cs_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.
*/
module { name = "cs_set_misc" }
command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; }
command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; }
/*
* cs_set_opnotice
*
* Provides the commands chanserv/set/opnotice and chanserv/saset/opnotice.
*
* Used for setting whether channel ops should be notified of mode changes made through ChanServ.
*/
module { name = "cs_set_opnotice" }
command { service = "ChanServ"; name = "SET OPNOTICE"; command = "chanserv/set/opnotice"; }
command { service = "ChanServ"; name = "SASET OPNOTICE"; command = "chanserv/saset/opnotice"; permission = "chanserv/saset/opnotice"; }
/*
* cs_set_peace
*
* Provides the commands chanserv/set/peace and chanserv/saset/peace.
*
* Used for setting the peace option, which prevents users from kicking other users with
* higher level access than them.
*/
module { name = "cs_set_peace" }
command { service = "ChanServ"; name = "SET PEACE"; command = "chanserv/set/peace"; }
command { service = "ChanServ"; name = "SASET PEACE"; command = "chanserv/saset/peace"; permission = "chanserv/saset/peace"; }
/*
* cs_set_persist
*
* Provides the commands chanserv/set/persist and chanserv/saset/persist.
*
* Used for setting whether ChanServ should stay in channels after the last user leaves.
*/
module { name = "cs_set_persist" }
command { service = "ChanServ"; name = "SET PERSIST"; command = "chanserv/set/persist"; }
command { service = "ChanServ"; name = "SASET PERSIST"; command = "chanserv/saset/persist"; permission = "chanserv/saset/persist"; }
/*
* cs_set_private
*
* Provides the commands chanserv/set/private and chanserv/saset/private.
*
* Used for setting whether channels should show up in chanserv/list.
*/
module { name = "cs_set_private" }
command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/private"; }
command { service = "ChanServ"; name = "SASET PRIVATE"; command = "chanserv/saset/private"; permission = "chanserv/saset/private"; }
/*
* cs_set_restricted
*
* Provides the commands chanserv/set/restricted and chanserv/saset/restricted.
*
* Used for setting whether users not on a channel's access list can join.
*/
module { name = "cs_set_restricted" }
command { service = "ChanServ"; name = "SET RESTRICTED"; command = "chanserv/set/restricted"; }
command { service = "ChanServ"; name = "SASET RESTRICTED"; command = "chanserv/saset/restricted"; permission = "chanserv/saset/restricted"; }
/*
* cs_set_secure
*
* Provides the commands chanserv/set/secure and chanserv/saset/secure.
*
* Used for setting whether users who are recognized for accounts should have their access in channels.
*/
module { name = "cs_set_secure" }
command { service = "ChanServ"; name = "SET SECURE"; command = "chanserv/set/secure"; }
command { service = "ChanServ"; name = "SASET SECURE"; command = "chanserv/saset/secure"; permission = "chanserv/saset/secure"; }
/*
* cs_set_securefounder
*
* Provides the commands chanserv/set/securefounder and chanserv/saset/securefounder.
*
* Used for setting whether users with founder level access in channels have true founder or not.
*/
module { name = "cs_set_securefounder" }
command { service = "ChanServ"; name = "SET SECUREFOUNDER"; command = "chanserv/set/securefounder"; }
command { service = "ChanServ"; name = "SASET SECUREFOUNDER"; command = "chanserv/saset/securefounder"; permission = "chanserv/saset/securefounder"; }
/*
* cs_set_secureops
*
* Provides the commands chanserv/set/secureops and chanserv/saset/secureops.
*
* Used for restricting who can have channel op privilege in a channel to those whom have access in the channel.
*/
module { name = "cs_set_secureops" }
command { service = "ChanServ"; name = "SET SECUREOPS"; command = "chanserv/set/secureops"; }
command { service = "ChanServ"; name = "SASET SECUREOPS"; command = "chanserv/saset/secureops"; permission = "chanserv/saset/secureops"; }
/*
* cs_set_signkick
*
* Provides the commands chanserv/set/signkick and chanserv/saset/signkick.
*
* Used for setting signkick, which appends the kicker's name to kicks sent through ChanServ.
*/
module { name = "cs_set_signkick" }
command { service = "ChanServ"; name = "SET SIGNKICK"; command = "chanserv/set/signkick"; }
command { service = "ChanServ"; name = "SASET SIGNKICK"; command = "chanserv/saset/signkick"; permission = "chanserv/saset/signkick"; }
/*
* cs_set_successor
*
* Provides the commands chanserv/set/successor and chanserv/saset/successor.
*
* Used for setting channel successors, which become channel founders if the founders account expires.
*/
module { name = "cs_set_successor" }
command { service = "ChanServ"; name = "SET SUCCESSOR"; command = "chanserv/set/successor"; }
command { service = "ChanServ"; name = "SASET SUCCESSOR"; command = "chanserv/saset/successor"; permission = "chanserv/saset/successor"; }
/*
* cs_set_topiclock
*
* Provides the commands chanserv/set/topiclock and chanserv/saset/topiclock.
*
* Used for setting topiclock, which prevents channel topics from being modified.
*/
module { name = "cs_set_topiclock" }
command { service = "ChanServ"; name = "SET TOPICLOCK"; command = "chanserv/set/topiclock"; }
command { service = "ChanServ"; name = "SASET TOPICLOCK"; command = "chanserv/saset/topiclock"; permission = "chanserv/saset/topiclock"; }
/*
* cs_set_noexpire
*
* Provides the command chanserv/saset/noexpire.
*
* Used for setting noexpire, which prevents channels from expiring.
*/
module { name = "cs_saset_noexpire" }
command { service = "ChanServ"; name = "SASET NOEXPIRE"; command = "chanserv/saset/noexpire"; permission = "chanserv/saset/noexpire"; }
/*
* cs_suspend
*
* Provides the commands chanserv/suspend and chanserv/unsuspend.
*
* Used for suspending and unsuspending channels. Suspended channels can not be used but their settings are stored.
*/
module { name = "cs_suspend" }
command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend"; permission = "chanserv/suspend"; }
command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; permission = "chanserv/suspend"; }
/*
* cs_sync
*
* Provides the command chanserv/sync.
*
* Used to sync users channel status modes with what access they have.
*/
module { name = "cs_sync" }
command { service = "ChanServ"; name = "SYNC"; command = "chanserv/sync"; }
/*
* cs_topic
*
* Provides the command chanserv/topic.
*
* Used for changing the channel topic. Usedful in conjunction with chanserv/set/topiclock.
*/
module { name = "cs_topic" }
command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; }
/*
* cs_unban
*
* Provides the command chanserv/unban.
*
* Used for unbanning users from channels.
*/
module { name = "cs_unban" }
command { service = "ChanServ"; name = "UNBAN"; command = "chanserv/unban"; }
/*
* cs_xop
*
* Provides the commands chanserv/qop, chanserv/sop, chanserv/aop, chanserv/hop, and chanserv/vop.
* Provides the access system "XOP".
*
* Used for giving users access in channels.
*/
module { name = "cs_xop" }
command { service = "ChanServ"; name = "QOP"; command = "chanserv/qop"; }
command { service = "ChanServ"; name = "SOP"; command = "chanserv/sop"; }
command { service = "ChanServ"; name = "AOP"; command = "chanserv/aop"; }
command { service = "ChanServ"; name = "HOP"; command = "chanserv/hop"; }
command { service = "ChanServ"; name = "VOP"; command = "chanserv/vop"; }
+253 -1417
View File
File diff suppressed because it is too large Load Diff
+115
View File
@@ -0,0 +1,115 @@
/*
* Example configuration file for Global.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the Global client
*/
nick = "Global"
/*
* The username of the Global client.
*/
user = "services"
/*
* The hostname of the Global client.
*/
host = "services.host"
/*
* The realname of the Global client.
*/
gecos = "Global Noticer"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core Global module.
*
* Provides essential functionality for Global.
*/
module { name = "gl_main" }
/*
* Configuration for Global provided by gl_main.
*/
global
{
/*
* The name of the client that should be Global.
*/
name = "Global"
/*
* If set, Services will send global messages on starting up and shutting
* down/restarting.
*
* This directive is optional.
*/
#globaloncycle = yes
/*
* This is the global message that will be sent when Services are being
* shutdown/restarted. This directive is only required if you enable
* globaloncycle above.
*/
globaloncycledown = "Services are restarting, they will be back shortly - please be good while we're gone"
/*
* This is the global message that will be sent when Services (re)join the
* network. This directive is only required if you enable globaloncycle above.
*/
globaloncycleup = "Services are now back online - have a nice day"
/*
* If set, Services will hide the IRC operator's nick in a global
* message/notice.
*
* This directive is optional.
*/
#anonymousglobal = yes
}
/*
* Core Global commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "Global"; name = "HELP"; command = "generic/help"; }
/*
* gl_global
*
* Provides the command global/global.
*
* Used for sending a message to every online user.
*/
module { name = "gl_global" }
command { service = "OperServ"; name = "GLOBAL"; command = "global/global"; permission = "operserv/global"; }
command { service = "Global"; name = "GLOBAL"; command = "global/global"; permission = "global/global"; }
+163
View File
@@ -0,0 +1,163 @@
/*
* Example configuration file for HostServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the HostServ client
*/
nick = "HostServ"
/*
* The username of the HostServ client.
*/
user = "services"
/*
* The hostname of the HostServ client.
*/
host = "services.host"
/*
* The realname of the HostServ client.
*/
gecos = "vHost Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core HostServ module.
*
* Provides essential functionality for HostServ.
*/
module { name = "hs_main" }
/*
* Configuration for HostServ provided by hs_main.
*/
hostserv
{
/*
* The name of the client that should be HostServ.
*/
name = "HostServ"
}
/*
* Core HostServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "HostServ"; name = "HELP"; command = "generic/help"; }
/*
* hs_del
*
* Provides the commands hostserv/del and hostserv/delall.
*
* Used for removing users vHosts.
*/
module { name = "hs_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
*
* Provides the command hostserv/group.
*
* Used for grouping one vHost to many nicks.
*/
module { name = "hs_group" }
command { service = "HostServ"; name = "GROUP"; command = "hostserv/group"; }
/*
* hs_list
*
* Provides the command hostserv/list.
*
* Used for listing actively set vHosts.
*/
module { name = "hs_list" }
command { service = "HostServ"; name = "LIST"; command = "hostserv/list"; permission = "hostserv/list"; }
/*
* hs_off
*
* Provides the command hostserv/off.
*
* Used for turning off your vHost.
*/
module { name = "hs_off" }
command { service = "HostServ"; name = "OFF"; command = "hostserv/off"; }
/*
* hs_on
*
* Provides the command hostserv/on.
*
* Used for turning on your vHost.
*/
module { name = "hs_on" }
command { service = "HostServ"; name = "ON"; command = "hostserv/on"; }
/*
* hs_request
*
* Provides the commands hostserv/request, hostserv/active, hostserv/reject, and hostserv/waiting.
*
* Used to manage vhosts requested by users.
*/
module { name = "hs_request" }
command { service = "HostServ"; name = "REQUEST"; command = "hostserv/request"; }
command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/activate"; permission = "hostserv/set"; }
command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; permission = "hostserv/set"; }
command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/set"; }
hs_request
{
/*
* If set, Services will send a memo to the user requesting a vHost when it's been
* approved or rejected.
*/
#memouser = yes
/*
* If set, Services will send a memo to all Services staff when a new vHost is requested.
*/
#memooper = yes
}
/*
* hs_set
*
* Provides the commands hostserv/set and hostserv/setall.
*
* Used for setting users vhosts.
*/
module { name = "hs_set" }
command { service = "HostServ"; name = "SET"; command = "hostserv/set"; permission = "hostserv/set"; }
command { service = "HostServ"; name = "SETALL"; command = "hostserv/setall"; permission = "hostserv/set"; }
+228
View File
@@ -0,0 +1,228 @@
/*
* Example configuration file for MemoServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the MemoServ client
*/
nick = "MemoServ"
/*
* The username of the MemoServ client.
*/
user = "services"
/*
* The hostname of the MemoServ client.
*/
host = "services.host"
/*
* The realname of the MemoServ client.
*/
gecos = "Memo Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core MemoServ module.
*
* Provides essential functionality for MemoServ.
*/
module { name = "ms_main" }
/*
* Configuration for MemoServ provided by ms_main.
*/
memoserv
{
/*
* The name of the client that should be MemoServ. Clients are configured
* with the service blocks.
*/
name = "MemoServ"
/*
* The maximum number of memos a user is allowed to keep by default. Normal users may set the
* limit anywhere between 0 and this value. Services Admins can change it to any value or
* disable it.
*
* This directive is optional, but recommended. If not set, the limit is disabled
* by default, and normal users can set any limit they want.
*/
maxmemos = 20
/*
* The delay between consecutive uses of the MemoServ SEND command. This can help prevent spam
* as well as denial-of-service attacks from sending large numbers of memos and filling up disk
* space (and memory). The default 3-second wait means a maximum average of 150 bytes of memo
* per second per user under the current IRC protocol.
*
* This directive is optional, but recommended.
*/
senddelay = 3s
/*
* Allow the use of memo receipts for the following groups:
*
* 1 - Opers Only
* 2 - Everybody
*
* This directive is optional.
*/
#memoreceipt = 1
}
/*
* Core MemoServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "MemoServ"; name = "HELP"; command = "generic/help"; }
/*
* ms_cancel
*
* Provides the command memoserv/cancel.
*
* Used to cancel memos already sent but not yet read.
*/
module { name = "ms_cancel" }
command { service = "MemoServ"; name = "CANCEL"; command = "memoserv/cancel"; }
/*
* ms_check
*
* Provides the command memoserv/check.
*
* Used to check if a sent memo has been read.
*/
module { name = "ms_check" }
command { service = "MemoServ"; name = "CHECK"; command = "memoserv/check"; }
/*
* ms_del
*
* Provides the command memoserv/del.
*
* Used to delete your memos.
*/
module { name = "ms_del" }
command { service = "MemoServ"; name = "DEL"; command = "memoserv/del"; }
/*
* ms_ignore
*
* Provides the command memoserv/ignore.
*
* Used to ignore memos from specific users.
*/
module { name = "ms_ignore" }
command { service = "MemoServ"; name = "IGNORE"; command = "memoserv/ignore"; }
/*
* ms_info
*
* Provides the command memoserv/info.
*
* Used to show memo related information about an account or a channel.
*/
module { name = "ms_info" }
command { service = "MemoServ"; name = "INFO"; command = "memoserv/info"; }
/*
* ms_list
*
* Provides the command memoserv/list.
*
* Used to list your current memos.
*/
module { name = "ms_list" }
command { service = "MemoServ"; name = "LIST"; command = "memoserv/list"; }
/*
* ms_read
*
* Provides the command memoserv/read.
*
* Used to read your memos.
*/
module { name = "ms_read" }
command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
/*
* ms_rsend
*
* Provides the command memoserv/rsend.
*
* Used to send a memo requiring a receipt be sent back once it is read.
*
* Requires configuring memoserv:memoreceipt.
*/
#module { name = "ms_rsend" }
#command { service = "MemoServ"; name = "RSEND"; command = "memoserv/rsend"; }
/*
* ms_send
*
* Provides the command memoserv/send
*
* Used to send memos.
*/
module { name = "ms_send" }
command { service = "MemoServ"; name = "SEND"; command = "memoserv/send"; }
/*
* ms_sendlal
*
* Provides the command memoserv/sendall
*
* Used to send a mass memo to every registered user.
*/
module { name = "ms_sendall" }
command { service = "MemoServ"; name = "SENDALL"; command = "memoserv/sendall"; permission = "memoserv/sendall"; }
/*
* ms_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" }
command { service = "MemoServ"; name = "SET"; command = "memoserv/set"; }
/*
* ms_staff
*
* Provides the command memoserv/staff.
*
* Used to send a memo to all registered staff members.
*/
module { name = "ms_staff" }
command { service = "MemoServ"; name = "STAFF"; command = "memoserv/staff"; permission = "memoserv/staff"; }
+276
View File
@@ -0,0 +1,276 @@
/*
* [OPTIONAL] Non-Core Modules
*
* The following blocks are used to load all non-core modules, including 3rd-party modules.
* Modules can be prevented from loading by commenting out the line, other modules can be added by
* adding a module block. These modules will be loaded prior to Services connecting to your network.
*/
/*
* help
*
* Provides commands generic/help
*
* Is a generic help command that can be used with any client.
*/
module { name = "help" }
/*
* m_dnsbl
*
* Allows configurable DNS blacklists to check connecting users against. If a user
* is found on the blacklist they will be immediately banned. This is a crucial module
* to prevent bot attacks.
*/
module { name = "m_dnsbl" }
m_dnsbl
{
/*
* If set, Services will check clients against the DNSBLs when services connect to its uplink.
* This is not recommended, and on large networks will open a very large amount of DNS queries.
* Whilst services are not drastically affected by this, your nameserver/DNSBL might care.
*/
check_on_connect = no
/*
* If set, Services will check clients when coming back from a netsplit. This can cause a large number
* of DNS queries open at once. Whilst services are not drastically affected by this, your nameserver/DNSBL
* might care.
*/
check_on_netburst = no
/*
* If set, OperServ will add clients found in the DNSBL to the akill list. Without it, OperServ simply sends
* a timed G/K-line to the IRCd and forgets about it. Can be useful if your akill list is being fill up by bots.
*/
add_to_akill = yes
}
blacklist
{
/* Name of the blacklist */
name = "rbl.efnetrbl.org"
/* How long to set the ban for */
time = 4h
/* Reason for akill.
* %n is the nick of the user
* %u is the ident/username of the user
* %g is the realname of the user
* %h is the hostname of the user
* %i is the IP of the user
* %r is the reason (configured below). Will be nothing if not configured.
* %N is the network name set in networkinfo:networkname
*/
reason = "You are listed in the efnet RBL, visit http://rbl.efnetrbl.org/?i=%i for info"
/* Replies to ban and their reason. If this is totally ommited all replies get banned */
1 = "Open Proxy"
/* Don't ban for result 2 or 3 */
#2 = "spamtrap666"
#3 = "spamtrap50"
4 = "TOR"
5 = "Drones / Flooding"
}
blacklist
{
name = "dnsbl.dronebl.org"
time = 4h
reason = "You have a host listed in the DroneBL. For more information, visit http://dronebl.org/lookup_branded.do?ip=%i&network=%N"
}
/*
* m_helpchan
*
* Gives users who are op in the specified help channel usermode +h (helpop).
*/
#module { name = "m_helpchan" }
m_helpchan
{
helpchannel = "#help"
}
/*
* m_ldap
*
* This module allows other modules to use LDAP. By itself, this module does nothing useful.
*/
#module { name = "m_ldap" }
ldap
{
server = "ldap://127.0.0.1"
port = 389
admin_binddn = "cn=Manager,dc=anope,dc=org"
admin_password = "secret"
}
/*
* m_ldap_authentication
*
* This module allows many commands such as IDENTIFY, RELEASE, RECOVER, GHOST, etc. use
* LDAP to authenticate users. Requires m_ldap.
*/
#module { name = "m_ldap_authentication" }
m_ldap_authentication
{
/*
* The distinguished name we should bind to when a user tries to identify.
*/
binddn = "ou=users,dc=anope,dc=org"
/*
* The object class used by LDAP to store user account information.
* Used for adding new users to LDAP if disable_ns_register is false
*/
object_class = "anopeUser"
/*
* The attribute value used for account names.
*/
username_attribute = "uid"
/*
* The attribute value used for email addresses.
* This directive is optional.
*/
email_attribute = "email"
/*
* The attribute value used for passwords.
* Used when registering new accounts in LDAP.
*/
password_attribute = "userPassword"
/*
* Enable to have this module disable /nickserv register.
*/
disable_ns_register = false
/*
* The reason to give the users who try to /ns register if
* disable_ns_register is enabled.
*/
#disable_reason = "To register on this network visit http://some.misconfigured.site/register"
}
/*
* m_ldap_oper
*
* This module dynamically ties users to Anope opertypes when they identify
* via LDAP group membership. Requires m_ldap.
*
* Note that this doesn't give the user privileges on the IRCd, only in Services.
*/
#module { name = "m_ldap_oper" }
m_ldap_oper
{
/*
* An optional binddn to use when searching for groups.
* %a is replaced with the account name of the user.
*/
#binddn = "cn=Manager,dc=anope,dc=org"
/*
* An optional password to bind with.
*/
#password = "secret"
/*
* The base DN where the groups are.
*/
basedn = "ou=groups,dc=anope,dc=org"
/*
* The filter to use when searching for users.
* %a is replaced with the account name of the user.
*/
filter = "(member=uid=%a,ou=users,dc=anope,dc=org)"
/*
* The attribute of the group that is the name of the opertype.
* The cn attribute should match a known opertype in the config.
*/
opertype_attribute = "cn"
}
/*
* m_mysql
*
* This module allows other modules (db_mysql/db_mysql_live) to use MySQL.
* Be sure you have imported the table schema with mydbgen before
* trying to use MySQL
*/
#module { name = "m_mysql" }
mysql
{
database = "anope"
server = "127.0.0.1"
username = "anope"
password = "mypassword"
port = 3306
}
/*
* m_ssl
*
* This module uses SSL to connect to the uplink server(s)
*/
module { name = "m_ssl" }
/*
* m_statusupdate
*
* This module automatically updates users status on channels when the
* channel's access list is modified.
*/
module { name = "m_statusupdate" }
/*
* m_xmlrpc
*
* Allows remote applications (websites) to execute queries in real time to retrieve data from Anope.
* By itself this module does nothing, but allows other modules (m_xmlrpc_main) to receive and send XMLRPC queries.
*/
#module { name = "m_xmlrpc" }
m_xmlrpc
{
/* IP to listen on */
bindip = "127.0.0.1"
/* Port to listen on */
port = 26673
/* Enable for IPv6 */
ipv6 = no
/* If enabled, requires m_ssl to be loaded */
ssl = no
/* IPs allowed to connect (separate with spaces), this should be secured. We also recommend you firewall this
* with an outside program to increase security.
*/
allowed = "127.0.0.0/24"
}
/*
* m_xmlrpc_main
*
* Adds the main XMLRPC core functions.
* Requires m_xmlrpc.
*/
#module { name = "m_xmlrpc_main" }
/*
* ns_maxemail
*
* Limits how many times the same email address may be used in Anope
* to register accounts.
*/
module { name = "ns_maxemail" }
ns_maxemail
{
/*
* The limit to how many registered nicks can use the same e-mail address. If set to 0 or left
* commented, there will be no limit enforced when registering new accounts or using
* /msg NickServ SET EMAIL.
*/
#maxemails = 1
}
+619
View File
@@ -0,0 +1,619 @@
/*
* Example configuration file for NickServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the NickServ client
*/
nick = "NickServ"
/*
* The username of the NickServ client.
*/
user = "services"
/*
* The hostname of the NickServ client.
*/
host = "services.host"
/*
* The realname of the NickServ client.
*/
gecos = "Nickname Registration Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core NickServ module.
*
* Provides essential functionality for NickServ.
*/
module { name = "ns_main" }
/*
* Configuration for NickServ provided by ns_main.
*/
nickserv
{
/*
* The name of the client that should be NickServ.
*/
name = "NickServ"
/*
* Force users to give an e-mail address when they register a nick.
*
* This directive is recommended to be enabled, and required if e-mail registration is enabled.
*/
forceemail = yes
/*
* Require users who change their email address to confirm they
* own it.
*/
confirmemailchanges = no
/*
* Require an e-mail to be sent to the user before they can register their nick.
*/
#emailregistration = yes
/*
* The default options for newly registered nicks. Note that changing these options
* will have no effect on nicks which are already registered. The list must be separated
* by spaces.
*
* The options are:
* - kill: Kill nick if not identified within 60 seconds
* - killquick: Kill nick if not identified within 20 seconds, this one overrides the above
* option and the above must be specified with this one
* - secure: Enable nickname security, requiring the nick's password before any operations
* can be done on it
* - private: Hide the nick from NickServ's LIST command
* - hideemail: Hide's the nick's e-mail address from NickServ's INFO command
* - hideusermask: Hide's the nick's last or current user@host from NickServ's INFO command
* - hidequit: Hide's the nick's last quit message
* - memosignon: Notify user if they have a new memo when they sign into the nick
* - memoreceive: Notify user if they have a new memo as soon as it's received
* - autoop: User will be automatically opped in channels they enter and have access to
* - msg: Services messages will be sent as PRIVMSGs instead of NOTICEs, requires UsePrivmsg
* to be enabled as well
*
* This directive is optional, if left blank, the options will default to secure, memosignon, and
* memoreceive. If you really want no defaults, use "none" by itself as the option.
*/
defaults="secure private hideemail hideusermask memosignon memoreceive autoop"
/*
* A list of languages to load on startup that will be available in /nickserv set language.
* Useful if you translate Anope to your language. (Explained further in docs/LANGUAGE).
* Note that english should not be listed here because it is the base language.
*/
languages = "ca_ES de_DE el_GR es_ES fr_FR hu_HU it_IT nl_NL pl_PL pt_PT ru_RU tr_TR"
/*
* Default language that non- and newly-registered nicks will receive messages in.
* Leave empty to default to English.
*/
#defaultlanguage = "es_ES"
/*
* The minimum length of time between consecutive uses of NickServ's REGISTER command. This
* directive is optional, but recommended. If not set, this restriction will be disabled.
*/
regdelay = 30s
/*
* The minimum length of time between consecutive uses of NickServ's RESEND command.
*
* This directive is optional, but recommended. If not set, this restriction will be disabled.
*/
resenddelay = 90s
/*
* The length of time before a nick registration expires.
*
* This directive is optional, but recommended. If not set, the default is 21 days.
*/
expire = 21d
/*
* The length of time before a suspended nick becomes unsuspended.
*
* This directive is optional. If not set, the default is to never.
*/
#suspendexpire = 90d
/*
* The length of time a user using an unconfirmed account has
* before the account will be released for general use again.
*
* This directive is only required if the e-mail registration option is enabled.
*/
#unconfirmedexpire = 1d
/*
* The maximum number of nicks allowed in a group.
*
* This directive is optional, but recommended. If not set or set to 0, no limits will be applied.
*/
maxaliases = 16
/*
* The maximum number of entries allowed on a nickname's access list.
*/
accessmax = 32
/*
* The username (and possibly hostname) used for the fake user created when NickServ collides
* a user. Should be in the user@host format.
*/
enforceruser = "enforcer"
enforcerhost = "localhost.net"
/*
* The delay before a NickServ collided nick is released.
*/
releasetimeout = 1m
/*
* Allow the use of the IMMED option in the NickServ SET KILL command.
*
* This directive is optional.
*/
#allowkillimmed = yes
/*
* If set, the NickServ GROUP command won't allow any group change. This is recommended for
* better performance and to protect against nick stealing, however users will have less
* flexibility.
*
* This directive is optional, but recommended.
*/
#nogroupchange = yes
/*
* The maximum number of nicks to be returned for a NickServ LIST command.
*/
listmax = 50
/*
* When a user's nick is forcibly changed to enforce a "nick kill", their new nick will start
* with this value. The rest will be made up of 6 or 7 digits.
*/
guestnickprefix = "Guest"
/*
* Prevents the use of the DROP, FORBID, GETPASS, and SET PASSWORD commands by Services Admins
* on other Services Admins or the Services Root(s).
*
* This directive is optional, but recommended.
*/
secureadmins = yes
/*
* If set, any user wanting to use the privileges of Services Root, Services Admin, or Services
* Operator must have been logged as an IRC Operator with the /oper command.
*
* This directive is optional, but recommended.
*/
strictprivileges = yes
/*
* If set, Services will set the channel modes a user has access to upon identifying, assuming
* they are not already set.
*
* This directive is optional.
*/
modeonid = yes
/*
* If set, Services will add the usermask of registering users to the access list of their
* newly created account. If not set, users will always have to identify to NickServ before
* being recognized, unless they manually add an address to the access list of their account.
* This directive is optional.
*/
addaccessonreg = yes
/*
* The maximum number of channels a user can have on NickServ's AJOIN command.
*/
ajoinmax = 10
}
/*
* Core NickServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
/*
* ns_access
*
* Provides the command nickserv/access.
*
* Used for configuring what hosts have access to your account.
*/
module { name = "ns_access" }
command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
/*
* ns_ajoin
*
* Provides the command nickserv/ajoin.
*
* Used for configuring channels to join once you identify.
*/
module { name = "ns_ajoin" }
command { service = "NickServ"; name = "AJOIN"; command = "nickserv/ajoin"; }
/*
* ns_alist
*
* Provides the command nickserv/alist.
*
* Used for viewing what channels you have access to.
*/
module { name = "ns_alist" }
command { service = "NickServ"; name = "ALIST"; command = "nickserv/alist"; }
/*
* ns_cert
*
* Provides the command nickserv/cert.
*
* Used for configuring your SSL certificate list, which can be used to automatically identify you.
*/
module { name = "ns_cert" }
command { service = "NickServ"; name = "CERT"; command = "nickserv/cert"; }
/*
* ns_drop
*
* Provides the command nickserv/drop.
*
* Used for unregistering names.
*/
module { name = "ns_drop" }
command { service = "NickServ"; name = "DROP"; command = "nickserv/drop"; }
/*
* ns_getemail
*
* Provides the command nickserv/getemail.
*
* Used for getting registered accounts by searching for emails.
*/
module { name = "ns_getemail" }
command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"; permission = "nickserv/getemail"; }
/*
* 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_ghost
*
* Provides the command nickserv/ghost.
*
* Used for disconnecting "ghost" sessions.
*/
module { name = "ns_ghost" }
command { service = "NickServ"; name = "GHOST"; command = "nickserv/ghost"; }
/*
* ns_group
*
* Provides the commands nickserv/group, nickserv/glist, and nickserv/ungroup.
*
* Used for controlling nick groups.
*/
module { name = "ns_group" }
command { service = "NickServ"; name = "GLIST"; command = "nickserv/glist"; }
command { service = "NickServ"; name = "GROUP"; command = "nickserv/group"; }
command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup"; }
/*
* ns_identify
*
* Provides the command nickserv/identify.
*
* Used for identifying to accounts.
*/
module { name = "ns_identify" }
command { service = "NickServ"; name = "ID"; command = "nickserv/identify"; }
command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"; }
/*
* ns_info
*
* Provides the command nickserv/info.
*
* Used for gathering information about an account.
*/
module { name = "ns_info" }
command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
/*
* ns_list
*
* Provides the command nickserv/list.
*
* Used for retrieving and searching the registered account list.
*/
module { name = "ns_list" }
command { service = "NickServ"; name = "LIST"; command = "nickserv/list"; }
/*
* ns_logout
*
* Provides the command nickserv/logout.
*
* Used for logging out of your account.
*/
module { name = "ns_logout" }
command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
/*
* ns_recover
*
* Provides the command nickserv/recover.
*
* Used for forcing someone on your nick to a guest nick.
*/
module { name = "ns_recover" }
command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover"; }
/*
* ns_register
*
* Provides the commands nickserv/confirm, nickserv/register, and nickserv/resend.
*
* Used for registering accounts.
*/
module { name = "ns_register" }
command { service = "NickServ"; name = "CONFIRM"; command = "nickserv/confirm"; }
command { service = "NickServ"; name = "REGISTER"; command = "nickserv/register"; }
command { service = "NickServ"; name = "RESEND"; command = "nickserv/resend"; }
/*
* ns_release
*
* Provides the command nickserv/release.
*
* Used for releasing names held by nickserv/recover.
*/
module { name = "ns_release" }
command { service = "NickServ"; name = "RELEASE"; command = "nickserv/release"; }
/*
* ns_resetpass
*
* Provides the command nickserv/resetpass.
*
* Used for resetting passwords by emailing users a temporary one.
*/
module { name = "ns_resetpass" }
command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpass"; }
/*
* ns_saset
*
* Provides commands nickserv/saset, nickserv/saset/display, and nickserv/saset/password.
*
* Used as a help wrapper for SASET commands, and used to force change users display name or password.
*/
module { name = "ns_saset" }
command { service = "NickServ"; name = "SASET"; command = "nickserv/saset"; }
command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/saset/display"; }
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; }
/*
* ns_set
*
* Provides the commands nickserv/set, nickserv/set/display, and nickserv/set/password.
*
* Used as a help wrapper for SET commands, and used for users to change their display name or password.
*/
module { name = "ns_set" }
command { service = "NickServ"; name = "SET"; command = "nickserv/set"; }
command { service = "NickServ"; name = "SET DISPLAY"; command = "nickserv/set/display"; }
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
/*
* ns_set_autoop
*
* Provides the commands nickserv/set/autoop and nickserv/saset/autoop.
*
* Used for setting autoop, which determines whether or not modes are automatically set on you when joining a channel.
*/
module { name = "ns_set_autoop" }
command { service = "NickServ"; name = "SET AUTOOP"; command = "nickserv/set/autoop"; }
command { service = "NickServ"; name = "SASET AUTOOP"; command = "nickserv/saset/autoop"; permission = "nickserv/saset/autoop"; }
/*
* ns_set_email
*
* Provides the commands nickserv/set/email and nickserv/saset/email.
*
* Used for setting users email addresses.
*/
module { name = "ns_set_email" }
command { service = "NickServ"; name = "SET EMAIL"; command = "nickserv/set/email"; }
command { service = "NickServ"; name = "SASET EMAIL"; command = "nickserv/saset/email"; permission = "nickserv/saset/email"; }
/*
* ns_set_greet
*
* Provides the commands nickserv/set/greet and nickserv/saset/greet.
*
* Used for changing users greet message, which is displayed when they enter channels.
*/
module { name = "ns_set_greet" }
command { service = "NickServ"; name = "SET GREET"; command = "nickserv/set/greet"; }
command { service = "NickServ"; name = "SASET GREET"; command = "nickserv/saset/greet"; permission = "nickserv/saset/greet"; }
/*
* ns_set_hide
*
* Provides the commands nickserv/set/hide and nickserv/saset/hide.
*
* Used for configuring which options are publically shown in nickserv/info for your account.
*/
module { name = "ns_set_hide" }
command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/hide"; permission = "nickserv/saset/hide"; }
/*
* ns_set_kill
*
* Provides the commands nickserv/set/kill and nickserv/saset/kill.
*
* Used for configuring if and for how long other users are allowed to use your nick.
*/
module { name = "ns_set_kill" }
command { service = "NickServ"; name = "SET KILL"; command = "nickserv/set/kill"; }
command { service = "NickServ"; name = "SASET KILL"; command = "nickserv/saset/kill"; permission = "nickserv/saset/kill"; }
/*
* ns_set_language
*
* Provides the commands nickserv/set/language and nickserv/saset/language.
*
* Used for configuring what language services use when messaging you.
*/
module { name = "ns_set_language" }
command { service = "NickServ"; name = "SET LANGUAGE"; command = "nickserv/set/language"; }
command { service = "NickServ"; name = "SASET LANGUAGE"; command = "nickserv/saset/language"; permission = "nickserv/saset/language"; }
/*
* ns_set_message
*
* Provides the commands nickserv/set/message and nickserv/saset/message.
*
* Used to configure how services send messages to you.
*/
module { name = "ns_set_message" }
command { service = "NickServ"; name = "SET MESSAGE"; command = "nickserv/set/message"; }
command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; permission = "nickserv/saset/message"; }
/*
* ns_set_private
*
* Provides the commands nickserv/set/private and nickserv/saset/private.
*
* Used for configuring whether or not your account shows up in nickserv/list.
*/
module { name = "ns_set_private" }
command { service = "NickServ"; name = "SET PRIVATE"; command = "nickserv/set/private"; }
command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/saset/private"; permission = "nickserv/saset/private"; }
/*
* ns_set_secure
*
* Provides the commands nickserv/set/secure and nickserv/saset/secure.
*
* Used for configuring whether you can gain access to your nick by simply being recognized by nickserv/access.
*/
module { name = "ns_set_secure" }
command { service = "NickServ"; name = "SET SECURE"; command = "nickserv/set/secure"; }
command { service = "NickServ"; name = "SASET SECURE"; command = "nickserv/saset/secure"; permission = "nickserv/saset/secure"; }
/*
* ns_saset_noexpire
*
* Provides the command nickserv/saset/noexpire.
*
* Used for configuring noexpire, which prevents nicks from expiring.
*/
module { name = "ns_saset_noexpire" }
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire" }
/*
* ns_sendpass
*
* Provides the command nickserv/sendpass.
*
* Used to send users their password via email.
*
* Requires that no encryption is being used.
*/
module { name = "ns_sendpass" }
command { service = "NickServ"; name = "SENDPASS"; command = "nickserv/sendpass"; permission = "nickserv/sendpass"; }
/*
* ns_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.
*/
module { name = "ns_set_misc" }
command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc"; }
command { service = "NickServ"; name = "SET ICQ"; command = "nickserv/set/misc"; }
/*
* ns_status
*
* Provides the nickserv/status command.
*
* Used to determine if a user is recognized or identified by services.
*/
module { name = "ns_status" }
command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
/*
* ns_suspend
*
* Provides the commands nickserv/suspend and nickserv/unsuspend.
*
* Used to suspend and unsuspend nicknames. Suspended nicknames can not be used but their settings are stored.
*/
module { name = "ns_suspend" }
command { service = "NickServ"; name = "SUSPEND"; command = "nickserv/suspend"; permission = "nickserv/suspend"; }
command { service = "NickServ"; name = "UNSUSPEND"; command = "nickserv/unsuspend"; permission = "nickserv/suspend"; }
/*
* ns_update
*
* Provides the command nickserv/update.
*
* Used to update your status on all channels, turn on your vHost, etc.
*/
module { name = "ns_update" }
command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
+593
View File
@@ -0,0 +1,593 @@
/*
* Example configuration file for OperServ.
*/
/*
* First, create the service.
*/
service
{
/*
* The name of the OperServ client
*/
nick = "OperServ"
/*
* The username of the OperServ client.
*/
user = "services"
/*
* The hostname of the OperServ client.
*/
host = "services.host"
/*
* The realname of the OperServ client.
*/
gecos = "Operator Service"
/*
* The modes this client should use.
* Do not modify this unless you know what you are doing.
*
* These modes are very IRCd specific. If left commented, sane defaults
* are used based on what protocol module you have loaded.
*
* Note that setting this option incorrectly could potentially BREAK some if
* not all usefulness of the client. We will not support you if this client is
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
}
/*
* Core OperServ module.
*
* Provides essential functionality for OperServ.
*/
module { name = "os_main" }
/*
* Configuration for OperServ provided by os_main.
*/
operserv
{
/*
* The name of the client that should be OperServ.
*/
name = "OperServ"
/*
* If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant
* them extra privileges such as being a founder on ALL channels.
*
* This directive is optional.
*/
#superadmin = yes
/*
* These define the default expiration times for, respectively, AKILLs, CHANKILLs, SNLINEs,
* SQLINEs, and SZLINEs.
*/
autokillexpiry = 30d
chankillexpiry = 30d
snlineexpiry = 30d
sqlineexpiry = 30d
szlineexpiry = 30d
/*
* If set, this option will make Services send an AKILL command immediately after it has been
* added with AKILL ADD. This eliminates the need for killing the user after the AKILL has
* been added.
*
* This directive is optional, but recommended.
*/
akillonadd = yes
/*
* If set, this option will make Services send an (SVS)KILL command immediately after SNLINE ADD.
* This eliminates the need for killing the user after the SNLINE has been added.
*
*This directive is optional.
*/
#killonsnline = yes
/*
* If set, this option will make Services send an (SVS)KILL command immediately after SQLINE ADD.
* This eliminates the need for killing the user after the SQLINE has been added.
*
* This directive is optional.
*/
#killonsqline = yes
/*
* Defines what actions should trigger notifications. The list must be separated by spaces.
*
* The notifications are:
* - oper: A user has become an IRC operator
* - bados: A non-IRCop attempts to use OperServ
* - akillexpire: An AKILL has expired
* - snlineexpire: An SNLINE has expired
* - sqlineexpire: An SQLINE has expired
* - szlineexpire: An SZLINE has expired
* - exceptionexpire: A session exception has expired
*
* This directive is optional, if left blank, there will be no notifications.
*/
notifications = "oper"
/*
* Enables session limiting. Session limiting prevents users from connecting more than a certain
* number of times from the same host at the same time - thus preventing most types of cloning.
* Once a host reaches it's session limit, all clients attempting to connect from that host will
* be killed. Exceptions to the default session limit can be defined via the exception list. It
* should be noted that session limiting, along with a large exception list, can degrade Services'
* performance.
*
* See the source and comments in sessions.c and the online help for more information about
* session limiting.
*
* This directive is optional.
*/
limitsessions = yes
/*
* Default session limit per host. Once a host reaches it's session limit, all clients attempting
* to connect from that host will be killed. A value of zero means an unlimited session limit.
*
* This directive is optional.
* If not given and session limiting is enabled, it will default to no limit.
*/
defaultsessionlimit = 3
/*
* The maximum session limit that may be set for a host in an exception.
*
* This directive is only required if session limiting is enabled.
*/
maxsessionlimit = 100
/*
* Sets the default expiry time for session exceptions.
*
* This directive is only required if session limiting is enabled.
*/
exceptionexpiry = 1d
/*
* The message that will be NOTICE'd to a user just before they are removed from the network because
* their host's session limit has been exceeded. It may be used to give a slightly more descriptive
* reason for the impending kill as opposed to simply "Session limit exceeded".
*
* This directive is optional, if not set, nothing will be sent.
*/
sessionlimitexceeded = "The session limit for your host %s has been exceeded."
/*
* Same as above, but should be used to provide a website address where users can find out more
* about session limits and how to go about applying for an exception.
*
* Note: This directive has been intentionally commented out in an effort to remind you to change
* the URL it contains. It is recommended that you supply an address/URL where people can get help
* regarding session limits.
*
* This directive is optional, if not set, nothing will be sent.
*/
#sessionlimitdetailsloc = "Please visit http://your.website.url/ for more information about session limits."
/*
* If set and is not 0, this directive tells Services to add an AKILL the number of subsequent kills
* for the same host exceeds this value, preventing the network from experiencing KILL floods.
*
* This directive is optional.
*/
maxsessionkill = 15
/*
* Sets the expiry time for AKILLs set for hosts exceeding the maxsessionkill directive limit.
*
* This directive is optional, if not set, defaults to 30 minutes.
*/
sessionautokillexpiry = 30m
/*
* Adds the nickname of the IRC Operator issuing an AKILL to the kill reason.
*
* This directive is optional.
*/
addakiller = yes
/*
* If set, only IRC Operators will be permitted to use OperServ, regardless of module-based command
* access restrictions.
*
* This directive is optional, but recommended.
*/
opersonly = yes
}
/*
* Core OperServ commands.
*
* In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
* are loaded you can then configure the commands to be added to any client you like with any name you like.
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/* Give it a help command */
command { service = "OperServ"; name = "HELP"; command = "generic/help"; }
/*
* os_akill
*
* Provides the command operserv/akill.
*
* Used to ban users from the network.
*/
module { name = "os_akill" }
command { service = "OperServ"; name = "AKILL"; command = "operserv/akill"; permission = "operserv/akill"; }
/*
* os_chankill
*
* Provides the command operserv/chankill.
*
* Used to akill uses from an entire channel.
*/
module { name = "os_chankill" }
command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"; permission = "operserv/chankill"; }
/*
* os_defcon
*
* Provides the command operserv/defcon.
*
* Allows you to set services in defcon mode, which can be used to restrict services access
* during bot attacks.
*/
#module { name = "os_defcon" }
#command { service = "OperServ"; name = "DEFCON"; command = "operserv/defcon"; }
defcon
{
/*
* Default DefCon level (1-5) to use when starting Services up. Level 5 constitutes normal operation
* while level 1 constitutes the most restrictive operation. If this setting is left out or set to
* 0, DefCon will be disabled and the rest of this block will be ignored.
*/
#defaultlevel = 5
/*
* The following 4 directives define what operations will take place when DefCon is set to levels
* 1 through 4. Each level is a list that must be separated by spaces.
*
* The following operations can be defined at each level:
* - nonewchannels: Disables registering new channels
* - nonewnicks: Disables registering new nicks
* - nomlockchanges: Disables changing MLOCK on registered channels
* - forcechanmodes: Forces all channels to have the modes given in the later chanmodes directive
* - reducedsessions: Reduces the session limit to the value given in the later sessionlimit directive
* - nonewclients: KILL any new clients trying to connect
* - operonly: Services will ignore all non-IRCops
* - silentoperonly: Services will silently ignore all non-IRCops
* - akillnewclients: AKILL any new clients trying to connect
* - nonewmemos: No new memos will be sent to block MemoServ attacks
*/
level4 = "nonewchannels nonewnicks nomlockchanges reducedsessions"
level3 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions"
level2 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions silentoperonly"
level1 = "nonewchannels nonewnicks nomlockchanges forcechanmodes reducedsessions silentoperonly akillnewclients"
/*
* New session limit to use when a DefCon level is using "reduced" session limiting.
*/
#sessionlimit = 2
/*
* Length of time to add an AKILL for when DefCon is preventing new clients from connecting to the
* network.
*/
#akillexpire = 5m
/*
* The channel modes to set on all channels when the DefCon channel mode system is in use.
*
* Note 1: Choose these modes carefully, because when DefCon switches to a level which does NOT have
* the mode setting selected, Services will set the reverse on all channels, e.g. if this setting
* is +RN when DefCon is used, all channels will be set to +RN, when DefCon is removed, all
* channels will be set to -RN. You don't want to set this to +k for example, because when DefCon
* is removed all channels with -k.
*
* Note 2: MLOCKed modes will not be lost.
*/
#chanmodes = "+R"
/*
* This value can be used to automatically return the network to DefCon level 5 after the specified
* time period, just in case any IRC Operator forgets to remove a DefCon setting.
*
* This directive is optional.
*/
#timeout = 15m
/*
* If set, Services will send a global message on DefCon level changes.
*
* This directive is optional.
*/
#globalondefcon = yes
/*
* If set, Services will send the global message defined in the message directive on DefCon level
* changes.
*
* This directive is optional.
*/
#globalondefconmore = yes
/*
* Defines the message that will be sent on DefCon level changes when globalondefconmore is set.
*
* This directive is required only when globalondefconmore is set.
*/
#message = "Put your message to send your users here. Dont forget to uncomment globalondefconmore"
/*
* Defines the message that will be sent when DefCon is returned to level 5. This directive is optional,
* and will also override globalondefcon and globalondefconmore when set.
*/
#offmessage = "Services are now back to normal, sorry for any inconvenience"
/*
* Defines the reason to use when clients are KILLed or AKILLed from the network while the proper
* DefCon operation is in effect.
*/
#akillreason = "This network is currently not accepting connections, please try again later"
}
/*
* os_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" }
command { service = "OperServ"; name = "CHANLIST"; command = "operserv/chanlist"; }
command { service = "OperServ"; name = "USERLIST"; command = "operserv/userlist"; }
/*
* os_config
*
* Provides the command operserv/config.
*
* Used to view and set configuration options while services are running.
*/
module { name = "os_config" }
command { service = "OperServ"; name = "CONFIG"; command = "operserv/config"; permission = "operserv/config"; }
/*
* os_forbid
*
* Provides the command operserv/forbid.
*
* Used to forbid specific nicks, channels, emails, etc. from being used.
*/
module { name = "os_forbid" }
command { service = "OperServ"; name = "FORBID"; command = "operserv/forbid"; permission = "operserv/forbid"; }
/*
* os_ignore
*
* Provides the command operserv/ignore.
*
* Used to make Services ignore users.
*/
module { name = "os_ignore" }
command { service = "OperServ"; name = "IGNORE"; command = "operserv/ignore"; permission = "operserv/ignore"; }
/*
* os_jupe
*
* Provides the command operserv/jupe.
*
* Used to disconnect servers from the network and prevent them from relinking.
*/
module { name = "os_jupe" }
command { service = "OperServ"; name = "JUPE"; command = "operserv/jupe"; permission = "operserv/jupe"; }
/*
* os_kick
*
* Provides the command operserv/kick.
*
* Used to kick users from channels.
*/
module { name = "os_kick" }
command { service = "OperServ"; name = "KICK"; command = "operserv/kick"; permission = "operserv/kick"; }
/*
* os_kill
*
* Provides the command operserv/kill.
*
* Used to forcibly disconnect users from the network.
*/
module { name = "os_kill" }
command { service = "OperServ"; name = "KILL"; command = "operserv/kill"; permission = "operserv/kill"; }
/*
* os_login
*
* Provides the command operserv/login.
*
* Used to login to OperServ, only required if your oper block requires this.
*/
module { name = "os_login" }
command { service = "OperServ"; name = "LOGIN"; command = "operserv/login"; }
/*
* os_mode
*
* Provides the commands operserv/mode and operserv/umode.
*
* Used to change user and channel modes.
*/
module { name = "os_mode" }
command { service = "OperServ"; name = "MODE"; command = "operserv/mode"; permission = "operserv/mode"; }
command { service = "OperServ"; name = "UMODE"; command = "operserv/umode"; permission = "operserv/umode"; }
/*
* os_modinfo
*
* Provides the commands operserv/modinfo and operserv/modlist.
*
* Used to show information about loaded modules.
*/
module { name = "os_modinfo" }
command { service = "OperServ"; name = "MODINFO"; command = "operserv/modinfo"; }
command { service = "OperServ"; name = "MODLIST"; command = "operserv/modlist"; permission = "operserv/modlist"; }
/*
* os_module
*
* Provides the commands operserv/modload, operserv/modreload, and operserv/modunload.
*
* Used to load, reload, and unload modules.
*/
module { name = "os_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
*
* Provides the commands operserv/logonnews, operserv/opernews, and operserv/randomnews.
*
* Used to configure news notices shown to users when they connect, and opers when they oper.
*/
module { name = "os_news" }
command { service = "OperServ"; name = "LOGONNEWS"; command = "operserv/logonnews"; permission = "operserv/news"; }
command { service = "OperServ"; name = "OPERNEWS"; command = "operserv/opernews"; permission = "operserv/news"; }
command { service = "OperServ"; name = "RANDOMNEWS"; command = "operserv/randomnews"; permission = "operserv/news"; }
/*
* os_noop
*
* Provides the command operserv/noop.
*
* Used to NOOP a server, which prevents users from opering on that server.
*/
module { name = "os_noop" }
command { service = "OperServ"; name = "NOOP"; command = "operserv/noop"; permission = "operserv/noop"; }
/*
* os_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" }
command { service = "OperServ"; name = "OLINE"; command = "operserv/oline"; permission = "operserv/oline"; }
/*
* os_oper
*
* Provides the command opersev/oper.
*
* Used to configure opers and show information about opertypes.
*/
module { name = "os_oper" }
command { service = "OperServ"; name = "OPER"; command = "operserv/oper"; permission = "operserv/oper"; }
/*
* os_reload
*
* Provides the command operserv/relad.
*
* Used to reload the services.conf configuration file.
*/
module { name = "os_reload" }
command { service = "OperServ"; name = "RELOAD"; command = "operserv/reload"; permission = "operserv/reload"; }
/*
* os_session
*
* Provides the commands operserv/exception and operserv/session.
*
* Used to manage the session limit exception list, and view currently active sessions.
*/
module { name = "os_session" }
command { service = "OperServ"; name = "EXCEPTION"; command = "operserv/exception"; permission = "operserv/exception"; }
command { service = "OperServ"; name = "SESSION"; command = "operserv/session"; permission = "operserv/session"; }
/*
* os_set
*
* Provides the command operserv/set.
*
* Used to set various settinsg such as superadmin, debug mode, etc.
*/
module { name = "os_set" }
command { service = "OperServ"; name = "SET"; command = "operserv/set"; permission = "operserv/set"; }
/*
* os_shutdown
*
* Provides the commands operserv/quit, operserv/restart, and operserv/shutdown.
*
* Used to quit, restart, or shutdown services.
*/
module { name = "os_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
*
* Provides the operserv/stats command.
*
* Used to show statistics about services.
*/
module { name = "os_stats" }
command { service = "OperServ"; name = "STATS"; command = "operserv/stats"; permission = "operserv/stats"; }
/*
* os_svsnick
*
* Provides the operserv/svsnick command.
*
* Used to force change user's nicks.
*/
module { name = "os_svsnick" }
command { service = "OperServ"; name = "SVSNICK"; command = "operserv/svsnick"; permission = "operserv/svsnick"; }
/*
* os_sxline
*
* Provides the operserv/snline, operserv/sqline, and operserv/szline commands.
*
* Used to ban different things such as realnames, nicknames, and IPs.
*/
module { name = "os_sxline" }
command { service = "OperServ"; name = "SNLINE"; command = "operserv/snline"; permission = "operserv/snline"; }
command { service = "OperServ"; name = "SQLINE"; command = "operserv/sqline"; permission = "operserv/sqline"; }
command { service = "OperServ"; name = "SZLINE"; command = "operserv/szline"; permission = "operserv/szline"; }
/*
* os_update
*
* Provides the opersev/update command.
*
* Use to immediately update the databases.
*/
module { name = "os_update" }
command { service = "OperServ"; name = "UPDATE"; command = "operserv/update"; permission = "operserv/update"; }
+10 -29
View File
@@ -3,9 +3,9 @@
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Apr 28, 2011 at 07:08 PM
-- Generation Time: Aug 07, 2011 at 03:53 PM
-- Server version: 5.1.50
-- PHP Version: 5.3.3-pl1-gentoo
-- PHP Version: 5.3.6-pl0-gentoo
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
@@ -63,12 +63,14 @@ CREATE TABLE IF NOT EXISTS `anope_bs_info_metadata` (
--
CREATE TABLE IF NOT EXISTS `anope_cs_access` (
`level` int(11) NOT NULL DEFAULT '0',
`display` varchar(255) NOT NULL DEFAULT '',
`provider` varchar(255) NOT NULL DEFAULT '',
`data` varchar(255) NOT NULL DEFAULT '',
`mask` varchar(255) NOT NULL DEFAULT '',
`channel` varchar(255) NOT NULL DEFAULT '',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`creator` varchar(255) NOT NULL DEFAULT '',
UNIQUE KEY `channel` (`channel`,`display`)
`created` int(11) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`mask`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
@@ -105,8 +107,6 @@ CREATE TABLE IF NOT EXISTS `anope_cs_info` (
`last_topic_setter` text NOT NULL,
`last_topic_time` int(10) unsigned NOT NULL DEFAULT '0',
`flags` text NOT NULL,
`forbidby` text NOT NULL,
`forbidreason` text NOT NULL,
`bantype` smallint(6) NOT NULL DEFAULT '0',
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
`botnick` varchar(255) NOT NULL DEFAULT '',
@@ -250,6 +250,7 @@ CREATE TABLE IF NOT EXISTS `anope_ns_alias` (
`last_quit` text NOT NULL,
`last_realname` text NOT NULL,
`last_usermask` text NOT NULL,
`last_realhost` text NOT NULL,
`time_registered` int(10) unsigned NOT NULL DEFAULT '0',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`flags` text NOT NULL,
@@ -284,7 +285,6 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core` (
`greet` text NOT NULL,
`flags` text NOT NULL,
`language` varchar(5) NOT NULL DEFAULT '',
`channelcount` smallint(5) unsigned NOT NULL DEFAULT '0',
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`display`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -303,32 +303,13 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` (
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_akills`
--
CREATE TABLE IF NOT EXISTS `anope_os_akills` (
`user` varchar(255) NOT NULL,
`host` varchar(255) NOT NULL,
`xby` text NOT NULL,
`reason` text NOT NULL,
`seton` int(10) unsigned NOT NULL DEFAULT '0',
`expire` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_core`
--
CREATE TABLE IF NOT EXISTS `anope_os_core` (
`maxusercnt` int(11) NOT NULL DEFAULT '0',
`maxusertime` int(10) unsigned NOT NULL DEFAULT '0',
`akills_count` int(11) NOT NULL DEFAULT '0',
`snlines_count` int(11) NOT NULL DEFAULT '0',
`sqlines_count` int(11) NOT NULL DEFAULT '0',
`szlines_count` int(11) NOT NULL DEFAULT '0'
`maxusertime` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
@@ -353,7 +334,7 @@ CREATE TABLE IF NOT EXISTS `anope_os_exceptions` (
--
CREATE TABLE IF NOT EXISTS `anope_os_xlines` (
`type` varchar(20) NOT NULL,
`type` varchar(1) NOT NULL,
`mask` varchar(255) NOT NULL,
`xby` text NOT NULL,
`reason` text NOT NULL,
+479 -1
View File
@@ -1,3 +1,481 @@
Revision 3cbad7f - Fri, 9 Sep 2011 23:27:15 -0400 - Regenerate language files
Revision b80a0a8 - Fri, 9 Sep 2011 22:27:51 -0400 - Updated Greek language file
Revision f844b0a - Fri, 9 Sep 2011 19:18:43 -0400 - Changed User::IsRecognized check to default to secure
Revision 6bd31b0 - Thu, 8 Sep 2011 19:00:30 -0400 - Bug #1330 & many other small fixes
Revision 7de1a7a - Mon, 5 Sep 2011 18:40:34 -0400 - Don't try and part service bots twice when channels drop
Revision 3815e7d - Sat, 3 Sep 2011 14:39:12 -0400 - Translate whole messages before splitting them up to send to users
Revision 30e6fc0 - Sat, 3 Sep 2011 14:13:14 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision fe1c5d4 - Sat, 3 Sep 2011 14:10:48 -0400 - Bug #1328 - Fixed fantasy to re-split message parameters correctly
Revision fa5ba63 - Sat, 3 Sep 2011 13:44:20 +0100 - Fixed a typo in the OperServ Global command
Revision 073db54 - Sat, 3 Sep 2011 01:29:57 -0400 - Added permission check in cs_sync
Revision ef10b5a - Sat, 3 Sep 2011 06:58:49 +0200 - Fixed operserv global
Revision 1c5ff92 - Mon, 29 Aug 2011 17:08:26 -0400 - Changed a few fatal exceptions to shutdown a bit more gracefully
Revision b24ea29 - Mon, 29 Aug 2011 16:13:37 -0400 - Fixed the /ms del message sent to users when they use /ms read
Revision 5cf3ddb - Mon, 29 Aug 2011 16:03:33 -0400 - Made config rehashing not wipe opers configured with opersev/oper
Revision 1e1a41f - Sat, 27 Aug 2011 20:58:09 -0400 - Added missing ` in docs/LANGUAGE
Revision 28e8190 - Sat, 27 Aug 2011 20:47:30 -0400 - Fixed some cmake warnings
Revision 670c928 - Sat, 27 Aug 2011 17:13:28 -0400 - Tweaked the access operators to allow superadmins to be > channel founders
Revision d07a692 - Sat, 27 Aug 2011 16:52:07 -0400 - Fixed /cs clone to set botmodes on the botserv bot when cloning channels
Revision bb52530 - Sat, 27 Aug 2011 16:45:14 -0400 - Fixed mlock with param modes if you change (but not unset) the mode
Revision 309dfa3 - Sat, 27 Aug 2011 16:14:04 -0400 - Fixed a few mysql problems, including bug #1326
Revision 5c57f5a - Sat, 27 Aug 2011 15:34:09 -0400 - Fixed /ns logout on other users
Revision a36e575 - Thu, 25 Aug 2011 19:01:40 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 8702031 - Thu, 25 Aug 2011 19:01:01 -0400 - Set the creator of default mlocks to the channel founder when a channel is registered
Revision 1571508 - Thu, 25 Aug 2011 10:16:56 +0200 - Only match users against the more "serious" extbans (ones which prevent users from joining)
Revision 6dacec2 - Wed, 24 Aug 2011 21:11:23 +0200 - guested nicks are now logged out from the recovered account on /nickserv recover
Revision fdbbea2 - Wed, 24 Aug 2011 14:27:01 -0400 - Fixed cs_set_misc
Revision dffed5a - Wed, 24 Aug 2011 13:57:56 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 5d681a7 - Wed, 24 Aug 2011 13:56:48 -0400 - Clear NS_HELD from nicks when recover expiry is up
Revision d80e00f - Wed, 24 Aug 2011 13:57:40 +0200 - Fixed automatic fingerprint identify on nickchange between registered nicks
Revision 21a8bff - Tue, 23 Aug 2011 19:04:27 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision fb14f77 - Tue, 23 Aug 2011 19:03:04 -0400 - Set os_session as having first priority for events
Revision 2284c31 - Tue, 23 Aug 2011 11:42:40 +0200 - Replaced some chanserv/forbid with operserv/forbid in example.conf and added a check for ForceForbidReason in os_forbid
Revision b5b2c42 - Mon, 22 Aug 2011 17:14:18 -0400 - Removed this ondeleteobject event, was for m_async_commands which died
Revision a2f92b6 - Mon, 22 Aug 2011 13:14:08 -0400 - Fixed the db_mysql metadata load events to use the right keys
Revision c996356 - Sun, 21 Aug 2011 16:35:22 -0400 - Bugs #1321 & 1322
Revision d71ae41 - Sun, 21 Aug 2011 14:54:06 -0400 - Fixed /cs access add log message to not show override for channel founders
Revision 68a125b - Sun, 21 Aug 2011 14:33:11 -0400 - Fixed ns_set_misc and cs_set_misc to allow unsetting values
Revision 37c7ca8 - Sun, 21 Aug 2011 14:09:55 -0400 - Fixed AddAkiller
Revision 4663970 - Sat, 20 Aug 2011 00:57:35 -0400 - Removed m_async_commands, it can still cause crashes from invalid pointers on the stack & is a giant mess anyway
Revision a68d17c - Sat, 20 Aug 2011 00:51:39 -0400 - Moved the ERROR log message out of debug
Revision fa3b74a - Sat, 20 Aug 2011 00:50:26 -0400 - Fixed zlines to only add the xline host, fixed db_mysql's write function, and prevent adding multiple of the same nick to access lists
Revision fd999b9 - Fri, 19 Aug 2011 16:14:26 -0400 - Fixed some problems with deleting access
Revision b4f5724 - Fri, 19 Aug 2011 04:20:11 -0400 - Fixed AccessGroup::operator> fail
Revision abdc69a - Fri, 19 Aug 2011 09:07:19 +0200 - added some log message for automatic fingerprint identify and removed a unused function from ns_cert
Revision 1b02216 - Thu, 18 Aug 2011 23:08:27 -0400 - Fixed crash in /cs mode
Revision db340f9 - Thu, 18 Aug 2011 22:04:59 -0400 - Fixed some permission checking fail in modules that got messed up from the big commands sed
Revision 0cdca53 - Thu, 18 Aug 2011 17:30:49 -0400 - Moved CA_TOPIC to qop aswell. Newer channels (default) to TOPIC at 5 but older channels will remain at founder only, causing access list to think newer aop are level 10000 due to having this permission on older channels.
Revision 71b9bbd - Thu, 18 Aug 2011 16:48:51 -0400 - Bug #1315 - moved CA_ASSIGN permission from sop to qop
Revision 2f3969b - Thu, 18 Aug 2011 07:59:58 +0200 - Bug #1317 - fixed sha1 fingerprint hashes in the inspircd protocol modules
Revision ff7479f - Thu, 18 Aug 2011 00:47:34 -0400 - Fixed attaching to events in db_mysql & possibly having ChannelInfo::WhoSends return NULL if there really are *no* bots
Revision 487d828 - Wed, 17 Aug 2011 22:05:47 -0400 - Actually made the nickserv block optional
Revision f41081b - Wed, 17 Aug 2011 21:41:30 -0400 - Include when an access entry was created in access view
Revision ede910d - Wed, 17 Aug 2011 15:56:40 -0400 - Made /os oper info also show all inherited commands/privs
Revision 0f4c9a4 - Tue, 16 Aug 2011 16:38:42 -0400 - List supported languages in /ns help saset language
Revision 9aa414b - Tue, 16 Aug 2011 15:28:21 -0400 - Fixed matching acount access entries against nicknames
Revision 2d9ddb0 - Tue, 16 Aug 2011 13:43:01 -0400 - Bug #1316 - added permissions for hs_request commands
Revision 1f542e1 - Tue, 16 Aug 2011 00:16:00 -0400 - Moved cs_seens data purger log message to debug
Revision 68e0d99 - Tue, 16 Aug 2011 00:09:09 -0400 - Fixed select()ing 0 sockets on Windows
Revision f43287f - Sun, 14 Aug 2011 22:10:17 -0400 - Fixed grammar problem in cs_clone
Revision 2e7bd64 - Sun, 14 Aug 2011 21:46:14 -0400 - Fixed /cs clone access
Revision 786397f - Sun, 14 Aug 2011 21:33:07 -0400 - Massive cleanup of cs_seen, added help, syntax messages, command descriptions, removed lots of dead code, fixed memory leaks, etc
Revision 960c339 - Sun, 14 Aug 2011 18:50:22 -0400 - Brought back the old 1.7 behavior of a level -1 matching all users and 0 matching all identified users
Revision fddb230 - Sun, 14 Aug 2011 17:01:28 -0400 - Bug #1312, fixed loading autoowner from db_plain
Revision 1b8dc4d - Sun, 14 Aug 2011 16:34:20 -0400 - Fixed updating exceptions
Revision fcc03f4 - Sun, 14 Aug 2011 15:59:14 -0400 - Do not put users hosts in session akills
Revision 78b8b30 - Sun, 14 Aug 2011 15:27:20 -0400 - Fixed resolving hosts when connecting to our uplink
Revision 91d8cc4 - Sun, 14 Aug 2011 15:25:02 -0400 - Revert "Fixed resolving hosts on connect"
Revision 11619be - Sun, 14 Aug 2011 21:21:50 +0200 - Fixed resolving hosts on connect
Revision e767ded - Sun, 14 Aug 2011 01:01:38 -0400 - Fixed default settings for log blocks
Revision 83a579f - Sat, 13 Aug 2011 23:05:30 -0400 - Fixed number list position when requesting custom lists from akill
Revision 244f879 - Sat, 13 Aug 2011 20:00:45 +0200 - Fixed permission check in botserv set
Revision 6f0da68 - Sat, 13 Aug 2011 09:43:38 -0400 - Fixed anope_os_core insert statement
Revision af43852 - Sat, 13 Aug 2011 09:27:42 -0400 - Fixed /cs saset noexpire syntax
Revision ad4c4e4 - Fri, 12 Aug 2011 13:08:53 -0400 - Send replies back to uses after m_ldap_authentication processes
Revision ed33a4f - Fri, 12 Aug 2011 12:48:29 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision f3d7d4e - Fri, 12 Aug 2011 12:46:11 -0400 - Track when our clients are introduced or not
Revision bd4916e - Fri, 12 Aug 2011 14:54:31 +0200 - Fixed loading/saving XLines in db_plain
Revision feee50e - Fri, 12 Aug 2011 03:13:56 -0400 - Allow bot usermodes to be configurable
Revision 54710a7 - Fri, 12 Aug 2011 01:51:14 -0400 - Removed the unused ChannelModeBan code
Revision d44a1d0 - Thu, 11 Aug 2011 23:10:08 -0400 - Fixed Windows runtime problems
Revision c2780e1 - Thu, 11 Aug 2011 22:21:40 +0200 - Added a separate field for last seen realhost to ns_info, shown to services admins only
Revision 4e1f54f - Thu, 11 Aug 2011 07:03:20 +0200 - added cs_seen
Revision 3755bf5 - Wed, 10 Aug 2011 15:50:45 -0400 - Ignore SIGPIPE
Revision 25d422d - Wed, 10 Aug 2011 15:47:02 -0400 - Fixed flags +* and -*
Revision 697bc8d - Wed, 10 Aug 2011 05:05:09 -0400 - Added a services.host define to easily change every clients hostname
Revision 4bdc982 - Wed, 10 Aug 2011 01:34:14 -0400 - Added two missing files
Revision ded98ed - Wed, 10 Aug 2011 01:32:07 -0400 - Fixed windows build
Revision 13bcc4e - Wed, 10 Aug 2011 00:28:31 -0400 - Replace the old sigaction for a signal when our Signal destructs
Revision ce92c9b - Tue, 9 Aug 2011 22:18:31 -0400 - Remove +P from unregistered channels if persist is set
Revision b332fbd - Tue, 9 Aug 2011 18:34:17 -0400 - Fixed parsing TMODE on ratbox
Revision eaf4e69 - Tue, 9 Aug 2011 17:07:20 -0400 - Updated Changes
Revision 2f67c70 - Tue, 9 Aug 2011 16:38:10 +0200 - fixed the operserv forbid del command
Revision 8348392 - Tue, 9 Aug 2011 13:36:33 +0200 - fixed wrong syntax-message for botserv set msg
Revision 8116ad9 - Tue, 9 Aug 2011 04:38:35 -0400 - Added forgotten founder checks to cs_access, fixed fantasy replies to come from the right service, and fixed the accessgroup operators to acount for founder/superadmin
Revision cb74359 - Tue, 9 Aug 2011 01:56:08 -0400 - Fixed a typo in init.cpp
Revision 776583a - Tue, 9 Aug 2011 01:55:34 -0400 - Simiplied a bit of the access system
Revision 91c3363 - Tue, 9 Aug 2011 00:06:44 -0400 - Hopefully sort this AccessGroup::HasPriv once and for all
Revision b7542fd - Mon, 8 Aug 2011 23:41:03 -0400 - Added a few sanity checks which never really should happen to db-convert
Revision 0c860a7 - Mon, 8 Aug 2011 23:32:52 -0400 - Fixed CMakeLists.txt detecting epoll
Revision 2d591f7 - Mon, 8 Aug 2011 20:34:27 -0400 - When we split from the uplink send a quit for *all* of our clients not just bots
Revision 9cb96f3 - Mon, 8 Aug 2011 06:24:29 +0100 - Merge branch '1.9' of ssh://anope.git.sf.net/gitroot/anope/anope into 1.9
Revision 286a9ed - Mon, 8 Aug 2011 06:19:35 +0100 - Standardized some of the SyntaxError/Help replies and corrected some syntax in BotServ set
Revision c4da496 - Mon, 8 Aug 2011 00:32:09 -0400 - Copy modules to the runtime directory in one big read/write if we can instead of this 1 byte at a time thing, significantly improves startup loading time.
Revision ade9239 - Sun, 7 Aug 2011 22:34:16 -0400 - Fixed the pipengines
Revision c6741d3 - Sun, 7 Aug 2011 19:04:27 -0400 - Always reset the levels of newly created channels, fixed DetermineLevel matching ACCESS_INVALID levels, and added in a disabled config option for levels
Revision 25e3408 - Sun, 7 Aug 2011 17:43:23 -0400 - Fixed generating sid on startup
Revision 35588cc - Sun, 7 Aug 2011 16:04:40 -0400 - Made botserv bots with no commands just ignore messages to them, and made bots only tell users to use HELP if they have a HELP command
Revision 32bb63f - Sun, 7 Aug 2011 15:56:35 -0400 - Updated tables.sql
Revision 27912e1 - Sat, 6 Aug 2011 19:43:06 -0400 - Fixed two of the xop log messages
Revision b678aa6 - Sat, 6 Aug 2011 19:41:37 -0400 - Give channel founders +qo by default
Revision c3e9fc4 - Sat, 6 Aug 2011 18:33:44 -0400 - Show channel founders their channels in /ns alist
Revision 66ab59d - Sat, 6 Aug 2011 18:21:59 -0400 - Fixed loading older access entries
Revision deb79e8 - Sat, 6 Aug 2011 18:05:16 -0400 - sed'd a few typos
Revision a6dd65f - Sat, 6 Aug 2011 17:33:59 -0400 - Fixed suepradmin
Revision 0448e38 - Sat, 6 Aug 2011 16:49:55 -0400 - Document what /os oline does
Revision 749de00 - Sat, 6 Aug 2011 04:32:50 -0400 - Update last used times on channels when someone with access uses them
Revision 7849667 - Sat, 6 Aug 2011 04:16:10 -0400 - Added a define{} block which can be used to easially rename things
Revision e03efde - Sat, 6 Aug 2011 00:31:24 +0100 - Fixed ns_ajoin to check if adding a duplicate channel
Revision d6a8d27 - Fri, 5 Aug 2011 16:07:41 +0100 - Fixed an error and typo in CS SET OPNOTICE
Revision 5e18a72 - Fri, 5 Aug 2011 06:18:38 -0400 - Mark the new commands/ modules as CORE and fixed a typo in the example.conf
Revision e66063e - Fri, 5 Aug 2011 05:35:31 -0400 - Rewrote the example configurations and split them up into seperate files for each pseudo client.
Revision 9ec18a3 - Thu, 4 Aug 2011 21:59:01 -0400 - Added a command:permission setting
Revision 773a1f3 - Thu, 4 Aug 2011 16:41:36 -0400 - Updated a bit of the TODO
Revision b3f4ba0 - Wed, 3 Aug 2011 06:09:27 -0400 - Start the ts6 sid generator off at 00A if none is given
Revision 34da226 - Wed, 3 Aug 2011 05:54:03 -0400 - Generate random SIDs for us if one is not specified
Revision 16280f4 - Wed, 3 Aug 2011 05:42:41 -0400 - Added operserv/kill and removed version.h from .gitignore
Revision 42f954f - Tue, 2 Aug 2011 22:39:14 -0400 - Fixed reintroducing our clients if we disconnect and reconnect to the uplink
Revision 09f5591 - Tue, 2 Aug 2011 05:07:59 -0400 - Fixed /cs clone copying channel access, fixed restricted, and fixed some compiler warnings
Revision f690cd8 - Tue, 2 Aug 2011 02:02:13 -0400 - Made /ns info default to your account or your nick if no arguments are given
Revision d43e1fb - Tue, 2 Aug 2011 01:50:09 -0400 - Added opertype:modes
Revision 41b40f6 - Mon, 1 Aug 2011 23:42:20 -0400 - Split /os mode into /os mode and /os umode to make giving permission to just one possible
Revision f7adc0b - Mon, 1 Aug 2011 22:37:27 -0400 - Rewrote the access systems and added a flags access system
Revision 710c02f - Sun, 31 Jul 2011 19:11:26 +0100 - Fixed bug #1301 - Changed operserv/staff to reflect its renaming to operserv/oper
Revision 7f69d2b - Sun, 31 Jul 2011 14:41:59 +0100 - Fixed bug #1300
Revision a18e3f3 - Sun, 31 Jul 2011 07:00:27 -0400 - Bugs 1297-1299 and made /os stats work like the help describes it does
Revision 63a4201 - Sun, 31 Jul 2011 06:24:24 -0400 - Fixed these ModuleManager::Attach calls once and for all..
Revision b751800 - Sun, 31 Jul 2011 06:24:11 -0400 - Fixed os_defcon
Revision f321491 - Sun, 31 Jul 2011 04:00:35 -0400 - Fixed error message from being unable to connect
Revision 1cb11bb - Sun, 31 Jul 2011 03:22:23 -0400 - Fixed a few small problems, including m_ssl's connect feature sometimes failing for no good reason
Revision f29c88b - Fri, 29 Jul 2011 22:50:45 +0100 - Fixed bug #1294, Crash on NS SET HIDE
Revision f5e78d7 - Thu, 28 Jul 2011 07:06:08 +0100 - Fixed a typo in the nickserv/auspex oper privilege
Revision 25c4985 - Thu, 28 Jul 2011 06:36:29 +0100 - Fixed OS LOGONNEWS
Revision cd4f6da - Wed, 27 Jul 2011 19:24:58 -0400 - Bug #1289 - Fixed hooking to delcore event in cs_main
Revision 6e032de - Wed, 27 Jul 2011 19:17:21 -0400 - Bug #1288 - Fixed crash on /cs help access
Revision e2b47e0 - Wed, 27 Jul 2011 19:06:42 -0400 - Bug #1291 - fixed parsing JOIN on ratbox
Revision b32c961 - Wed, 27 Jul 2011 16:54:50 +0100 - Show the description in cs help set instead of the syntax
Revision 088337e - Tue, 26 Jul 2011 23:18:54 -0400 - Fixed /os ignore, /os exception del, and a crash in /cs entrymsg
Revision e8c00b9 - Tue, 26 Jul 2011 05:44:14 -0400 - A few small fixes
Revision 023d4b4 - Sat, 23 Jul 2011 13:22:56 +0100 - Fixed a typo that broke CS SET RESTRICTD and re-added abbreviation for CS SET DESC
Revision 87d2f4b - Sat, 23 Jul 2011 13:07:19 +0100 - Fix couple of typos in modules
Revision 39ca53c - Sun, 17 Jul 2011 21:58:27 +0100 - Fixed hs_request and corrected a typo(?) in hs activate
Revision 46f2f3b - Sun, 17 Jul 2011 13:08:15 +0100 - Fixed some of the extra modules
Revision cb56d50 - Sun, 17 Jul 2011 06:08:35 -0400 - Fixed up cs_set_misc and ns_set_misc
Revision b19dddb - Sat, 16 Jul 2011 07:03:04 -0400 - Fixed a few of the /cs set syntax messages to reflect the new syntax
Revision acceabe - Sat, 16 Jul 2011 06:52:13 -0400 - Bug #1287 - Only check if users should be deopped on syncing channels when the user is on a server that is also syncing.
Revision c3993b3 - Thu, 14 Jul 2011 22:37:46 -0400 - Fixed appending !*@* to some access list entries that are valid hosts
Revision f277be0 - Thu, 14 Jul 2011 21:40:21 -0400 - Fixed OSOpersOnly & CSOpersOnly
Revision 1a2486d - Thu, 14 Jul 2011 20:52:24 -0400 - These .pot files don't need to be under version control
Revision a735095 - Thu, 14 Jul 2011 20:00:39 -0400 - Added cs_sync
Revision ef75e17 - Thu, 14 Jul 2011 19:11:13 -0400 - Added bs_autoassign
Revision 5bf7dee - Thu, 14 Jul 2011 18:29:03 -0400 - Made channel descriptions optional
Revision f858164 - Thu, 14 Jul 2011 02:31:12 -0400 - Rewrote how commands are handled within Anope. This allows naming commands and having spaces within command names.
Revision 924f684 - Sun, 10 Jul 2011 19:32:10 -0400 - Bug #1283 - Upped the buffer used for messge replies, as some can be really big
Revision b5ec57a - Sun, 10 Jul 2011 19:07:45 -0400 - Bug #1285 - Fixed setting -P on channels with only a service bot in it
Revision 6d97848 - Sun, 10 Jul 2011 18:27:48 -0400 - Bug #1286 - Dont allow actions to mess up the caps kicker
Revision d2832b1 - Thu, 7 Jul 2011 02:23:11 -0400 - Use getrlimit instead of ulimit, fixes freebsd build
Revision 1a4fc39 - Wed, 6 Jul 2011 22:06:07 -0400 - Do not send news when a server is syncing
Revision 97388ab - Wed, 6 Jul 2011 22:05:01 -0400 - Fixed /hs set and /hs setall not allowing only a host
Revision 57ec310 - Wed, 6 Jul 2011 05:20:25 -0400 - Only call send once per write event in dns manager
Revision ffd5c04 - Wed, 6 Jul 2011 00:33:25 -0400 - Fixed chanserv/access/modify permission on non-xop channels
Revision cc3c2b6 - Tue, 5 Jul 2011 01:39:11 -0400 - Send account data once an account is confirmed
Revision c549aa4 - Mon, 4 Jul 2011 22:39:13 -0400 - Bug #1279 - Fixed strftime
Revision 714831b - Mon, 4 Jul 2011 22:34:21 -0400 - Bug #1282
Revision d6879c4 - Mon, 4 Jul 2011 14:25:13 -0400 - Bug #1280 - Fixed reading some na and bi flags in db_plain
Revision 2caf586 - Sun, 3 Jul 2011 00:19:54 -0400 - Clean up some of the dns code, udp is connectionless anyway so this isnt required
Revision c585964 - Mon, 27 Jun 2011 19:14:30 -0400 - Fixed the mode manager from complaining about prefixless modes on insp20
Revision 936a50d - Mon, 27 Jun 2011 15:35:09 -0400 - Fixed build on older cmake versions
Revision 3e98880 - Fri, 24 Jun 2011 03:40:18 -0400 - Fixed mail delay time
Revision 821826a - Fri, 24 Jun 2011 02:58:40 -0400 - The other part of #1277
Revision 7ec803f - Thu, 23 Jun 2011 15:31:57 -0400 - Bug #1277 - Dont send account data for unconfirmed nicks
Revision b1a075b - Thu, 23 Jun 2011 15:10:50 -0400 - Fixed bug #1276 and some other valgrind warnings
Revision 3be75cb - Mon, 20 Jun 2011 23:28:25 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 2667f90 - Mon, 20 Jun 2011 23:25:46 -0400 - Cleaned up some of the logger code which fixes not logging debug logs to files etc when debug is enabled, and some other small things
Revision 2601871 - Mon, 20 Jun 2011 23:09:03 -0400 - Fix long-standing issue with the get token functions if the delimiter wasn't found in the string but you wanted the first "token".
Revision a3d0ab3 - Mon, 20 Jun 2011 23:00:49 -0400 - Use case insensitive matching when looking up servers by name
Revision a1b36ec - Fri, 17 Jun 2011 19:57:43 -0400 - Search all domains for language strings, fixes the mess that we used to use to translate strings in 3rd party modules
Revision 48e995d - Fri, 17 Jun 2011 13:34:47 -0400 - Bug #1275 - Don't log absolutely everything sent to operserv, most of its commands already have their own logs
Revision df971be - Tue, 14 Jun 2011 18:23:53 -0400 - Fixed a few small things
Revision 1cd6587 - Mon, 13 Jun 2011 18:20:22 +0200 - changed some _() to gtl() and updated do_strftime() and duration()
Revision 6148ffa - Sun, 12 Jun 2011 06:28:22 +0200 - added a Anope::string::capacity() function
Revision 717b4c3 - Thu, 9 Jun 2011 06:16:31 +0200 - small improvement for Timer::SetSecs()
Revision 74361be - Tue, 7 Jun 2011 06:16:57 +0200 - added a Timer::SetSecs() function
Revision a087e7f - Sun, 5 Jun 2011 18:18:50 -0400 - Fixed clearing bandata
Revision 3ad93a3 - Thu, 2 Jun 2011 14:59:34 -0400 - Burst our channels with the uplink when we connect & fixed bug #1274
Revision 184b346 - Thu, 2 Jun 2011 12:45:08 -0400 - Place version.h in build/ not include/
Revision b2c807d - Mon, 30 May 2011 13:14:33 -0400 - Fixed /ns alist
Revision 60548aa - Sun, 29 May 2011 19:05:28 -0400 - Fixed ns_update and db_mysql_live sql queries
Revision a45d155 - Mon, 23 May 2011 14:47:14 -0400 - Added an IsServicesOper event
Revision 121ae0b - Mon, 23 May 2011 13:32:01 -0400 - Added m_statusupdate
Revision 8bf8832 - Mon, 23 May 2011 04:41:51 -0400 - Rewrote the signal handling to use sigaction
Revision 4dd7e26 - Sun, 22 May 2011 09:05:21 +0200 - fixed a possible crash on database saving
Revision f4329df - Sat, 21 May 2011 15:33:10 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 98729a6 - Sat, 21 May 2011 15:32:47 -0400 - Bug #1271
Revision 742ba97 - Sat, 21 May 2011 15:15:46 +0200 - fixed bug #1272
Revision 115f94b - Sat, 21 May 2011 04:57:27 -0400 - Made Anope able to process normally when disconnected from the uplink and not sleep(), enable usage of non-blocking connect() and default all sockets to non blocking mode. Some cleanup to m_ssl and some cleanup to main.cpp.
Revision 7e57272 - Thu, 19 May 2011 20:36:39 -0400 - Fixed compile from the earlier merge
Revision 13915d8 - Mon, 16 May 2011 04:10:18 -0400 - Modularized os_news
Revision 9962fae - Mon, 16 May 2011 04:10:18 -0400 - Calculate nc::channelcount at runtime
Revision 9fcbe29 - Mon, 16 May 2011 04:10:18 -0400 - Added os_oper
Revision fd4b52e - Mon, 16 May 2011 04:10:18 -0400 - Added os_forbid
Revision b59602a - Mon, 16 May 2011 04:10:18 -0400 - Check for a valid server in /operserv noop
Revision fd21c36 - Mon, 16 May 2011 04:10:18 -0400 - Fixed some logic fail in ts6_uid_retrieve
Revision b999c6c - Mon, 16 May 2011 04:10:15 -0400 - Expand more on m_alias and changed some std::string usage in sockets.cpp to use Anope::string
Revision 583954d - Mon, 16 May 2011 04:09:32 -0400 - Use module type to determine what type each module is instead of its location in the configuration file.
Revision 8fb1604 - Mon, 16 May 2011 04:09:07 -0400 - Fixed reading empty config values in the multiconfig code, caused by removal of DT_CHARPTR
Revision 284af25 - Mon, 16 May 2011 04:09:07 -0400 - Added more useful functions to our LDAP API, allow adding newly registered accounts to LDAP, removed some unnecessary OnPre events and fixed unloading all modules
Revision e7887c1 - Mon, 16 May 2011 04:08:47 -0400 - Unmodularized the socket engine because its causing problems and really is unnecessary
Revision 076ebaf - Mon, 16 May 2011 04:07:56 -0400 - Moved some global functions to be member functions and misc cleanup
Revision 6922bd2 - Mon, 16 May 2011 04:07:30 -0400 - Fixed up the MySQL Query code and finished some command code I forgot earlier
Revision 13aa58c - Mon, 16 May 2011 04:06:22 -0400 - Removed DT_CHARPTR from the config reader, its unneeded
Revision c8c2315 - Mon, 16 May 2011 04:06:17 -0400 - Moved the core pseudo clients out into their own modules
Revision 1782ce2 - Mon, 16 May 2011 04:01:50 -0400 - Use std::map instead of unordered_map
Revision b28d374 - Mon, 16 May 2011 04:01:46 -0400 - Branch for 1.9.5
Revision 469a04e - Mon, 16 May 2011 02:58:06 -0400 - Anope 1.9.4 Release
Revision 605b5d5 - Mon, 16 May 2011 02:57:28 -0400 - Removed ngircd as we've decided not to support it at this time
Revision f7aa46f - Mon, 16 May 2011 02:47:23 -0400 - Note m_async_commands is experimental
Revision b445029 - Sun, 15 May 2011 21:02:06 -0400 - Fixed Windows build
Revision 57327a5 - Sun, 15 May 2011 19:54:35 -0400 - Fixed akill log message when there is no expiry time
Revision 4a3c642 - Sun, 1 May 2011 18:41:54 -0400 - Fixed sometimes not removing nick masks from the access list when the group is dropped
Revision 036b3c9 - Fri, 29 Apr 2011 18:03:04 -0400 - Temporary fix for /os restart with m_async_commands loaded, is fixed properly in 1.9.5
Revision 7da3334 - Thu, 28 Apr 2011 19:13:44 -0400 - Added a unique key for the anope_cs_mlock table
Revision cbdb9f5 - Wed, 27 Apr 2011 11:15:02 -0400 - Fixed bug #1265
Revision 5d3d6bc - Wed, 27 Apr 2011 09:26:51 -0400 - Fixed a crash if an expiring channel had the founder also on the access list
Revision 0cdc628 - Mon, 25 Apr 2011 15:58:46 -0400 - Fixed crash when certain nicks expire
Revision 4a733c9 - Mon, 25 Apr 2011 04:17:21 -0400 - Don't attempt to connect to the uplink if given invalid hostnames
Revision 03d2378 - Mon, 25 Apr 2011 07:08:57 +0200 - resolve hosts when connecting with ssl
Revision 5e027c1 - Sat, 23 Apr 2011 02:36:42 -0400 - Two small SQL fixes
Revision 3aeaef5 - Wed, 20 Apr 2011 15:39:44 -0400 - A few more small fixes
Revision 4d26070 - Wed, 20 Apr 2011 09:35:09 -0400 - This actually isn't necessary
Revision f601b04 - Tue, 19 Apr 2011 23:42:16 -0400 - Fixed logging messages with an empty category to everything
Revision ca16948 - Mon, 18 Apr 2011 21:07:54 -0400 - Allow unidentified users to still get access by non nickcore access entries
Revision 713c2eb - Mon, 18 Apr 2011 17:09:30 -0400 - Fixed /ns help register reply
Revision 660e0c7 - Sun, 17 Apr 2011 19:00:01 -0400 - Fixed /ns help access
Revision 0862de6 - Sat, 16 Apr 2011 16:06:52 -0400 - Fixed the mlock depreciated message
Revision 2cd511d - Sat, 16 Apr 2011 04:35:14 -0400 - Fixed botserv kicker logic
Revision efe5fed - Fri, 15 Apr 2011 19:51:34 -0400 - Fixed caps kicker
Revision c8c6845 - Sun, 10 Apr 2011 22:05:48 -0400 - Fixed /ns list unconfirmed
Revision bd62c48 - Sat, 9 Apr 2011 20:52:25 -0400 - Fixed disabling channel levels
Revision 9535541 - Wed, 6 Apr 2011 10:13:03 -0400 - Fixed setting +r on nick ownership, lost somewhere in revision fbae33
Revision 711a570 - Wed, 6 Apr 2011 09:41:39 -0400 - Run OnCheckAuthentication with the account name if there is one
Revision cb9ccc4 - Tue, 5 Apr 2011 19:11:23 -0400 - Fixed bug #1261
Revision c681bdd - Sun, 3 Apr 2011 18:23:17 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 74844c0 - Sun, 3 Apr 2011 18:19:29 -0400 - Use dynamic_reference to check for users being killed from commands
Revision 9052070 - Sun, 3 Apr 2011 18:07:58 -0400 - Made LDAP support recover, release, resetpass, etc.
Revision 73a944f - Sun, 3 Apr 2011 08:54:40 +0200 - fixed some duplicate messages and updated the german langfile (10% done)
Revision d1328d8 - Fri, 1 Apr 2011 01:57:12 -0400 - Fixed a typo making ns_register crash
Revision faa8556 - Thu, 31 Mar 2011 14:41:30 -0400 - Removed some unneeded/unused code from m_ldap
Revision 8dec0c1 - Wed, 30 Mar 2011 23:59:57 -0400 - Fixed bug #1258, more Windows stuff, and more language strings
Revision 8098ed8 - Wed, 30 Mar 2011 00:55:45 -0400 - Fixed windows build more, including ldap
Revision 77c98f0 - Tue, 29 Mar 2011 14:02:35 -0400 - Regenerated language files.
Revision 8dbdfa9 - Tue, 29 Mar 2011 13:43:40 -0400 - Fixed windows build
Revision 685e99b - Tue, 29 Mar 2011 13:43:22 -0400 - Fixed some left over useprivmsg problems and fixed some compiler warnings.
Revision b14b7bd - Sat, 26 Mar 2011 08:44:21 +0100 - burned all %R and %S in the .po files
Revision 365769d - Sat, 26 Mar 2011 08:20:05 +0100 - replaced all %R with %s in the language strings
Revision 01b901e - Fri, 25 Mar 2011 20:56:42 +0100 - ignore additional parameters for /chanserv info
Revision 26de1d9 - Fri, 25 Mar 2011 17:42:13 +0100 - 1. when dropping nicks, dont add the dropped nick as successor for a channel 2. set -r on dropped channels
Revision 451fb82 - Tue, 22 Mar 2011 23:58:53 -0400 - Bug #1203
Revision c02d51f - Tue, 22 Mar 2011 18:16:05 -0400 - Bug #1256
Revision b95027b - Wed, 16 Mar 2011 01:16:15 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 5b476a2 - Wed, 16 Mar 2011 06:14:28 +0100 - added a description for the HELP command
Revision bceeda8 - Wed, 16 Mar 2011 05:36:12 +0100 - fixed displaying the RESEND command in /nickserv help output
Revision ee9636b - Tue, 15 Mar 2011 19:23:08 -0400 - Fixed some logic fail in User::IsRecognized
Revision ddfb16d - Mon, 14 Mar 2011 20:16:38 -0400 - Fixed compile
Revision 2555d0d - Mon, 14 Mar 2011 21:39:53 +0000 - Removed include/patricia.h due to oversight in attribution. This breaks compile, please do not use until this is fixed later.
Revision ed73d76 - Mon, 14 Mar 2011 13:52:26 -0400 - Rewrote some of the opertype system, added os_login
Revision 4fe49af - Sun, 13 Mar 2011 22:59:50 -0400 - Fixed a crash in m_ldap is unloaded
Revision beabbb3 - Sun, 13 Mar 2011 19:15:53 -0400 - When a server quits use its quit reason for all of its links
Revision b4888c2 - Sun, 13 Mar 2011 17:20:44 -0400 - Fixed a typo in os_stats
Revision b75fa1c - Sun, 13 Mar 2011 14:03:02 -0400 - Fixed a crash in /cs help register
Revision 3fbf39b - Sun, 13 Mar 2011 03:42:30 -0400 - Added some useful Anope::Version functions to prevent some files from unnecessarily rebuilding on every make
Revision 15a8332 - Sun, 13 Mar 2011 03:38:42 -0400 - Set the locale to the default system locale on startup
Revision 5a0d04b - Sun, 13 Mar 2011 07:09:17 +0100 - fixed a typo in os_news, thanks to Dan for reporting it
Revision fbae334 - Sat, 12 Mar 2011 09:27:16 +0100 - added ns_cert
Revision 95469fd - Sat, 12 Mar 2011 02:40:08 -0500 - Added some access checks to cs_mode and fixed some language strings
Revision 9f46972 - Fri, 11 Mar 2011 17:26:27 -0500 - _()ify Command::SetDesc
Revision 46a3afa - Fri, 11 Mar 2011 17:09:49 -0500 - Fixed validating users on all server syncs
Revision 1b2f3bf - Fri, 11 Mar 2011 15:10:30 -0500 - Fixed some problems with m_alias and fantasy
Revision bb3b421 - Fri, 11 Mar 2011 04:27:32 -0500 - Global should send logon news
Revision 1ee3d3d - Fri, 11 Mar 2011 00:47:28 -0500 - Added os_config and support for including additional configuration files.
Revision 97c2e09 - Thu, 10 Mar 2011 19:20:58 -0500 - Bug #1251 - Fixed logging inspircd logging us logging inspircd. Also moved the Server::Find messages to debug level 2
Revision 09a5791 - Wed, 9 Mar 2011 12:29:59 -0500 - ngIRCd protocol: announce Anope with its version
Revision 8db5ecd - Wed, 9 Mar 2011 12:28:24 -0500 - Fixed sending CHANINFO on ngIRCd with two parameters if the channel has no modes locked.
Revision e9aa04a - Wed, 9 Mar 2011 01:25:49 -0500 - Store mlock in the databases and removed some unused functions from misc.cpp
Revision 8eb23e7 - Mon, 7 Mar 2011 19:54:51 -0500 - Added support for extbans
Revision 093b3d2 - Sun, 6 Mar 2011 19:36:52 -0500 - Change the mode name code to use Flags names in preparation for extban support
Revision 48e6221 - Sat, 5 Mar 2011 22:00:27 -0500 - Expire unconfirmed nicks, forgot to add this earlier..
Revision ef0c095 - Sat, 5 Mar 2011 18:18:51 -0500 - Made m_ldap_oper understand deopering
Revision a0355df - Sat, 5 Mar 2011 17:43:51 -0500 - Fixed /bs badword del to show what word was deleted
Revision 6fe2d8a - Sat, 5 Mar 2011 17:23:22 -0500 - Removed nickrequests, instead have unconfirmed registrations. Also made ns_resetpass allow remote-id to get past things such as kill immed.
Revision 90e5d0f - Fri, 4 Mar 2011 20:47:58 -0500 - Added LDAP support
Revision d79e22b - Fri, 4 Mar 2011 12:50:50 -0500 - Updated TODO
Revision a9fb6ba - Fri, 4 Mar 2011 02:41:29 -0500 - Just use blocking sql queries if m_asynch_commands isn't loaded - it's not that bad.
Revision dd968c0 - Fri, 4 Mar 2011 02:19:20 -0500 - Fixed some logic fail when detecting who should be akicked
Revision feb81c5 - Fri, 4 Mar 2011 02:17:51 -0500 - Clarify the module dependency messages generated by cmake are non fatal
Revision aecf675 - Sun, 27 Feb 2011 23:32:07 -0500 - Fixed os_sqline del
Revision bcaf406 - Sun, 27 Feb 2011 16:47:23 -0500 - Made akills work on IRCds that do not support bans (ngircd)
Revision f234a2b - Sat, 26 Feb 2011 17:54:03 -0500 - Replaced the few language strings we use with #defines to prevent accidentally translating them if we shouldnt
Revision 28d17a4 - Fri, 25 Feb 2011 21:41:27 -0500 - Fixed session exception limit of 0 to mean unlimited
Revision 7cfca37 - Fri, 25 Feb 2011 21:41:18 -0500 - Fixed build on freebsd with precompiled headers
Revision c38b639 - Fri, 25 Feb 2011 21:41:08 -0500 - More fixes. Also made db_mysql_live not keep bots updated because thats pointless and made m_asynch_commands respect user language settings.
Revision ee38756 - Fri, 25 Feb 2011 21:40:43 -0500 - Fixed a lot of small problems
Revision eea7d2e - Tue, 22 Feb 2011 20:44:47 -0500 - Fixed the first half of #1235
Revision b15410f - Tue, 22 Feb 2011 20:30:45 -0500 - Store modes in the databases told to us during runtime that we don't have information any about. Allows mlocking things like InspIRCds +w etc. Also fixes part of #1235
Revision c83b2b7 - Sun, 20 Feb 2011 01:05:16 -0500 - Much more work on the live SQL. Should work pretty decently now under heavy load.
Revision dfbb526 - Sat, 19 Feb 2011 21:17:53 -0500 - Inspircd does not send CAPAB NOQUIT, assume it
Revision f49a3e0 - Sat, 19 Feb 2011 19:03:05 -0500 - Fixed aborting because of invalid values given to mode +f on inspircd
Revision 109d174 - Fri, 18 Feb 2011 11:49:52 -0500 - Update SQL when a nick is deleted
Revision 470f8af - Fri, 18 Feb 2011 11:48:29 -0500 - Fixed some logic fail when determining when a recognized user gets access
Revision a1296a3 - Fri, 18 Feb 2011 11:48:20 -0500 - Changed the OnNickDrop event to call before the nick is deleted
Revision f38fe24 - Thu, 17 Feb 2011 14:32:51 -0500 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 536ea21 - Thu, 17 Feb 2011 14:31:21 -0500 - Split db_mysql_live into two modules so other modules can make use of the asynchronous command interface
Revision ab0422b - Thu, 17 Feb 2011 07:00:03 +0100 - set the vhost before we call ns_ajoin or other modules on identify
Revision 18bd33f - Wed, 16 Feb 2011 12:50:23 -0500 - Use precompiled headers when building with gnu g++ to speed up build time
Revision d436e4c - Sun, 13 Feb 2011 20:06:01 +0100 - added Anope::printf()
Revision 1372dc1 - Sat, 12 Feb 2011 16:17:17 -0500 - Removed the Wallop config options and replaced them with the new log system
Revision 9ef7352 - Fri, 11 Feb 2011 18:30:58 -0500 - Merged os_umode into os_mode
Revision 2529ff6 - Fri, 11 Feb 2011 03:12:39 -0500 - Made the help command description code more sane
Revision 7bdf592 - Wed, 9 Feb 2011 21:54:28 -0500 - Log rawio when in debug mode and fixed expiring session exceptions
Revision f463b77 - Wed, 9 Feb 2011 20:09:26 -0500 - Removed a lot of the old capab flags we dont/have never used
Revision eec8977 - Wed, 9 Feb 2011 17:41:07 -0500 - Enable quitstorm for ngircd
Revision f87c665 - Wed, 9 Feb 2011 13:31:47 -0500 - Foward port ebe0ce6610e1 / b6ab031fc1822
Revision 36d3fd1 - Wed, 9 Feb 2011 13:25:28 -0500 - Do not crash if a user is introduced with a nonexistant server
Revision d26a19b - Wed, 9 Feb 2011 01:12:43 -0500 - Made ./Config output a userful error message if cmake is not found
Revision a55b374 - Sat, 5 Feb 2011 18:35:20 -0500 - Removed the LIBINTL include hack
Revision 8355666 - Fri, 4 Feb 2011 21:01:33 -0500 - try/catch-ified all instances of convertTo to keep from aborting when a user gives too large or too small a number
Revision faf5f31 - Fri, 4 Feb 2011 19:31:02 -0500 - Merge 032c30dd5dc4
Revision a53a797 - Fri, 4 Feb 2011 18:32:04 -0500 - Replaced all of the old %S's in the language strings that were used for service nicks
Revision 08583dc - Fri, 4 Feb 2011 15:30:31 -0500 - Moved the language strings which are only used once out of the core and into the modules that use them.
Revision c362a1e - Sat, 29 Jan 2011 12:05:34 +0000 - DP in "an user" grammar police mode.
Revision 140208e - Sat, 29 Jan 2011 12:00:12 +0000 - Another typo pointed out by the grammar police. ;)
Revision 679d3c3 - Sat, 29 Jan 2011 11:58:59 +0000 - Fixing leftover spaces and other rubbish I missed on the first pass.
Revision 557ecee - Sat, 29 Jan 2011 11:06:38 +0000 - Updated some docs/ & removed TROUBLESHOOTING as it is redundant.
Revision 9704ccc - Sat, 29 Jan 2011 10:44:27 +0000 - QA fixes / refinements for example.conf
Revision e626641 - Fri, 28 Jan 2011 23:09:25 -0500 - Added patricia_tree::iterator
Revision 3eadc15 - Fri, 28 Jan 2011 13:19:26 -0500 - Fixed setting usermode +k on our clients on InspIRCd 2.0
Revision 9910aa3 - Fri, 28 Jan 2011 00:09:34 +0000 - Bug #1237 - only set umode +h on a user joining help chan if they have op access
Revision 2a53e5f - Mon, 24 Jan 2011 19:03:15 -0500 - Fixed the order queries are done during sqlsync to make the new foreign keys happy
Revision 2e8acfb - Mon, 24 Jan 2011 17:50:34 -0500 - Fixed some SQL queries
Revision 48fa096 - Mon, 24 Jan 2011 02:54:09 -0500 - Added %N for network name in dnsbl:reason
Revision bf559d7 - Mon, 24 Jan 2011 01:11:10 -0500 - Fixed loading forbidden nicks
Revision 3bfc8e9 - Sun, 23 Jan 2011 12:56:21 -0500 - std::stringstream::clear doesn't clear it
Revision a162f1d - Fri, 21 Jan 2011 23:01:48 -0500 - Bug #1234 - Fix reading resolv.conf if it has multiple spaces or tabs
Revision a86873c - Fri, 21 Jan 2011 16:49:25 +0000 - fixed some minor presentation, grammar mis-use and copyright date in DP's ngircd
Revision 05933e9 - Thu, 20 Jan 2011 19:42:27 -0500 - Removed db-upgrade, its no longer needed
Revision ab2e34d - Wed, 19 Jan 2011 00:31:18 -0500 - Added options:nomlock
Revision e7a8bcc - Tue, 18 Jan 2011 18:47:08 -0500 - Bug #1232 - Fixed db-convert to properly convert mode lock parameters
Revision 34c6c66 - Tue, 18 Jan 2011 18:41:16 -0500 - Added amsg kicker settings to /bs info
Revision 4a3ee91 - Tue, 18 Jan 2011 19:05:20 +0100 - fixed a bug in the ngircd protocol module
Revision 6f0d1af - Mon, 17 Jan 2011 20:41:57 -0500 - Made db_plain buffer database writes which prevents databases from coming corrupted if we crash or if write fails. Also fixed loading all ajoin channels.
Revision 01feb5b - Mon, 17 Jan 2011 20:29:33 -0500 - Fixed ns_ajoins list output formatting
Revision 8975b52 - Mon, 17 Jan 2011 15:46:53 -0500 - Added ns_ajoin
Revision 7acbbbb - Sat, 15 Jan 2011 21:02:14 -0500 - Fixed flag names to match 1.9.3s
Revision 4fecafa - Sat, 15 Jan 2011 16:45:48 -0500 - Made db_plain save amsg settings
Revision a4ded88 - Sat, 15 Jan 2011 16:29:17 -0500 - Made CA_SET always be accessable, even if db-converter messes up levels
Revision 1b6aab0 - Sat, 15 Jan 2011 16:13:31 -0500 - Fixed /ns confirm's log message to show the nick of who was confirmed
Revision c669820 - Sat, 15 Jan 2011 16:11:31 -0500 - Added an amsg kicker
Revision ecc2fc6 - Fri, 14 Jan 2011 04:50:01 +0000 - Fix CODINGs formatting and a missed typo
Revision e490202 - Tue, 11 Jan 2011 22:19:46 -0500 - Bug #1230 - Fixed unknown CTCPs from crashing services
Revision fd2412a - Mon, 10 Jan 2011 17:41:09 -0500 - Send new memo replies to the receiver of the memo
Revision 07528ea - Sun, 9 Jan 2011 13:38:15 -0500 - Fixed CanAdd() to use safe iteration and make SNLine::Check really work (cherry picked from commit 1bdadde68aed5a93225a5a625484505f1126a8a9)
Revision ce8a069 - Sat, 8 Jan 2011 18:55:12 -0500 - Changed db_mysql_live to use a safer mutex system to prevent deadlocks
Revision 2ba97ae - Sat, 8 Jan 2011 03:35:04 -0500 - Ignore EINTR error from poll()
Revision a674d81 - Sat, 8 Jan 2011 08:38:16 +0100 - updated the README file
Revision efb61ed - Sat, 8 Jan 2011 08:21:18 +0100 - enabled modeonid in example.conf
Revision 2e7d08c - Sat, 8 Jan 2011 08:18:46 +0100 - fixed a small bug in the ratbox protocol module
Revision 47b87e9 - Sat, 8 Jan 2011 08:15:48 +0100 - added support for ngIRCd protocol
Revision ddeff72 - Sat, 8 Jan 2011 00:52:46 -0500 - Process flag changes from SQL
Revision 43995b4 - Sat, 8 Jan 2011 00:25:30 -0500 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 512d23d - Sat, 8 Jan 2011 00:25:11 -0500 - Made the Flag class able to convert flags to strings and back
Revision 0eb9152 - Fri, 7 Jan 2011 23:01:19 +0000 - fix some more copyright and typos (not mine) spotted by chaz :P
Revision 4403849 - Fri, 7 Jan 2011 15:57:13 -0500 - Added db_mysql_live which allows Anope to pull data from the four main SQL tables in realtime, which effectively gives us "live" SQL. Changed eventfd pipe engine to not use buffered write. Added TryLock to threading engines. Made blocking SQL queries in our SQL API thread-safe.
Revision 9efebe5 - Wed, 5 Jan 2011 18:34:38 +0000 - update copyrights for 2011
Revision 7198fa7 - Tue, 4 Jan 2011 07:33:34 +0100 - removed SendSVSPart(), we dont use it
Revision 03ba592 - Tue, 4 Jan 2011 07:14:50 +0100 - removed SendSVSMode(), we dont use it
Revision 57a06f7 - Fri, 31 Dec 2010 21:20:34 +0000 - fixed a crash bug when a server squits
Revision 3019ba6 - Thu, 30 Dec 2010 06:44:18 +0100 - restoring topic for permchans on burst
Revision 2784cd1 - Thu, 30 Dec 2010 05:50:55 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 03cc9eb - Wed, 29 Dec 2010 23:30:28 -0500 - Assign bots to new empty permanent channels on IRCds without permchannel mode not just join
Revision 72b8f46 - Wed, 29 Dec 2010 23:12:26 -0500 - Use empty SJOINs when allowed to create empty permanent channels
Revision d36e53f - Wed, 29 Dec 2010 20:19:37 -0500 - Added a ConvertException to be thrown when convertTo fails
Revision a36f14c - Wed, 29 Dec 2010 19:59:26 -0500 - Automatically quit bots when they are deleted
Revision 292e187 - Wed, 29 Dec 2010 22:39:20 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 16cab97 - Tue, 28 Dec 2010 16:32:18 -0500 - Bug #1225 - Made REGISTER show in /cs help
Revision fd7f542 - Tue, 28 Dec 2010 07:00:47 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 5ead326 - Mon, 27 Dec 2010 15:33:49 -0500 - Fixed build on debian lenny
Revision a1c635b - Mon, 27 Dec 2010 01:35:08 -0500 - Load session exceptions on start when using SQL
Revision d896bf9 - Mon, 27 Dec 2010 01:00:12 -0500 - Bug #1222 - Fixed crash from reading to read a range of memos
Revision 49dd1c3 - Mon, 27 Dec 2010 00:42:38 -0500 - Bug #1220 - Fixed an event in /hs activate and /ms del
Revision fce491e - Mon, 27 Dec 2010 00:41:04 -0500 - Made socket engine stop processing once all sockets have been checked
Revision 87d0fc8 - Sun, 26 Dec 2010 20:15:54 -0500 - Fixed poll engine to not reorder sockets if we remove the last socket because there is no need
Revision f638d10 - Sun, 26 Dec 2010 09:36:45 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 8af2465 - Sun, 26 Dec 2010 00:31:11 -0500 - Bug #1219 - Correctly restrict people from registering potentential guest names
Revision 1b3f256 - Sun, 26 Dec 2010 00:14:49 -0500 - Fixed a potential crash from dropping nicks
Revision 036d451 - Sat, 25 Dec 2010 15:27:02 +0000 - updated crontab instructions in INSTALL
Revision 80721d1 - Sat, 25 Dec 2010 02:30:39 -0500 - Forward port part of 821995bf604b5c6e18e6c0c93a31e149565160c8
Revision aa9e33c - Fri, 24 Dec 2010 19:55:09 -0500 - Bug #1216 - Do not apply SQLines on our own clients
Revision 8690017 - Fri, 24 Dec 2010 19:07:47 -0500 - Made clearing SXLines remove the XLine from the IRCd too
Revision d5c1d6e - Fri, 24 Dec 2010 16:12:08 -0500 - Do not allow xop del to delete users on another list
Revision 35e328b - Fri, 24 Dec 2010 01:23:22 -0500 - Fixed Windows build
Revision befb4b3 - Fri, 24 Dec 2010 01:22:07 -0500 - Made the default socket poller use poll() because it is supported on most platforms
Revision 4235df2 - Fri, 24 Dec 2010 06:42:55 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision a6c8a6a - Thu, 23 Dec 2010 23:33:02 -0500 - Prevent version.cpp from prepending version.sh's VERSION_EXTRA on every build
Revision 1a3ba00 - Thu, 23 Dec 2010 21:56:06 -0500 - Fixed noexpire channels expiring
Revision e8a2072 - Thu, 23 Dec 2010 19:18:25 -0500 - Added a missing os_ignore.h
Revision 4886b56 - Thu, 23 Dec 2010 19:14:07 -0500 - Fixed a crash in m_alias
Revision 15d29ed - Thu, 23 Dec 2010 18:50:27 -0500 - Do not clear want write on a socket if we are unable to completely write its buffer
Revision 3009540 - Thu, 23 Dec 2010 18:39:54 -0500 - Rewrote the ignore code. Adds creator and reason to /os ignore list.
Revision a0ad3c4 - Thu, 23 Dec 2010 07:15:32 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 265006b - Thu, 23 Dec 2010 00:03:50 -0500 - Fixed deleting expired SXLines
Revision 11b3b8a - Wed, 22 Dec 2010 19:12:04 -0500 - Made SQLine clear work
Revision 2783c82 - Wed, 22 Dec 2010 18:28:22 -0500 - Removed match_usermask
Revision 184e7b3 - Wed, 22 Dec 2010 07:05:40 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 18377ac - Tue, 21 Dec 2010 15:57:57 -0500 - Allow hostmasks to be in uplink:host
Revision 184e14e - Sun, 19 Dec 2010 08:56:31 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 21125cf - Sat, 18 Dec 2010 19:53:32 -0500 - Made the version generator code work right when we are on a tag because git describe just gives the tag name and nothing else.
Revision 0d20c47 - Sat, 18 Dec 2010 19:41:13 -0500 - Don't send SXLines until after we start bursting with our uplink
Revision 7f9a5e0 - Fri, 17 Dec 2010 03:09:51 -0500 - NULL the core *serv pointers when core clients are deleted
Revision eb9b12e - Wed, 15 Dec 2010 12:47:35 -0500 - Bug #1211 - Fixed loading and saving anope_os_sxlines
Revision 4a4c088 - Wed, 15 Dec 2010 12:18:20 -0500 - Bug #1212 - Fixed some bad logic in /os exception preventing valid exceptions from being added
Revision 0247633 - Tue, 14 Dec 2010 08:13:09 +0100 - Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9
Revision 49d3c97 - Mon, 13 Dec 2010 16:36:36 -0500 - Bug #1079 - Don't use users real host and IPs when matching against bans and excepts, except when a user is unbanning themselves, in an attempt to prevent people from gaining other users IPs. This removes support for Unreal and Bahamuts SVSMode -b because it will unban users by real host and IP.
Revision 97467cb - Mon, 13 Dec 2010 13:26:01 -0500 - Bug #1113 - Document the fantasy character in /bs help
Revision 6a43886 - Mon, 13 Dec 2010 07:34:06 +0100 - removed an unused variable
Revision 5d56a24 - Mon, 13 Dec 2010 07:26:05 +0100 - changed a few 'if' to 'else if'
Revision eb138a0 - Sun, 12 Dec 2010 19:37:04 -0500 - Do not validate users during netburst until after the server is done syncing
Revision 2a4d0e3 - Sun, 12 Dec 2010 19:37:04 -0500 - Allow getting users opertype from XMLRPC requests
Revision 9f7a2e4 - Sun, 12 Dec 2010 19:37:04 -0500 - Bug #1177 - Readded in support for cs_mode to act on every channel
Revision 25e995b - Sun, 12 Dec 2010 19:37:04 -0500 - Fixed a few places in the plexus protocol module where we were sending nick not UID
Revision ad5da2a - Sun, 12 Dec 2010 19:37:03 -0500 - Handle not being able to completely flush our write buffer correctly
Revision 6ab7cf9 - Sun, 12 Dec 2010 19:37:03 -0500 - fixed a compile error in plexus protocol module
Revision 099ead0 - Sun, 12 Dec 2010 19:37:03 -0500 - store the ssl fingerprint in the userstruct
Revision f1d04a2 - Sun, 12 Dec 2010 19:37:03 -0500 - Allow command aliases to be redirected to different pseudo clients
Revision aed53db - Sun, 12 Dec 2010 19:37:03 -0500 - Cleaned up some things, made the protocol modules use some basic inheritance to cut back on their code duplication. More work can be done in the future to remove even more of it.
Revision a507816 - Sun, 12 Dec 2010 19:37:03 -0500 - Fixed looking up users to use case insensitivity
Revision c41c828 - Sun, 12 Dec 2010 19:37:03 -0500 - Do not use wildcard matching when looking up hosts on access add/del
Revision 5fe41fb - Sun, 12 Dec 2010 19:37:02 -0500 - Document that /cs owner and deowner allow nick args
Revision 0ba5664 - Sun, 12 Dec 2010 19:37:02 -0500 - Allowing adding hostmasks to channel access lists
Revision 2a4d57a - Sun, 12 Dec 2010 19:37:02 -0500 - Fixed subcommands
Revision 71c433c - Sun, 12 Dec 2010 19:37:00 -0500 - The rest of the earlier command changes
Revision 2b10cc8 - Sun, 12 Dec 2010 19:36:19 -0500 - Added /bs set msg
Revision cb6ef57 - Sun, 12 Dec 2010 19:36:19 -0500 - Send replies from fantasy commands back to the channel, this will be expanded on later
Revision 37e02a3 - Sun, 12 Dec 2010 19:36:19 -0500 - Added cs_entrymsg
Revision 7d1cfe9 - Sun, 12 Dec 2010 19:36:18 -0500 - Fixed some sed failure
Revision 9870ee0 - Sun, 12 Dec 2010 19:36:18 -0500 - Removed some unused code paths in some of the modules
Revision 1a28639 - Sun, 12 Dec 2010 19:36:16 -0500 - Added a plexus3 protocol module
Revision 697dc89 - Sun, 12 Dec 2010 19:36:01 -0500 - Added a default expiry time for suspended and forbidden nicks and channels
Revision 4d342d9 - Sun, 12 Dec 2010 19:35:58 -0500 - Fixed some of the language strings
Revision c5eb349 - Sun, 12 Dec 2010 19:35:30 -0500 - Removed the AUTODEOP level, it is unnecessary now because of cs_mode
Revision 7790a7f - Sun, 12 Dec 2010 19:35:30 -0500 - Allow the patricia tree to store non-pointers
Revision 246f44b - Sun, 12 Dec 2010 19:35:27 -0500 - Added cs_mode, rewrote the old list mode code, and added CIDR support
Revision a851121 - Sun, 12 Dec 2010 19:33:59 -0500 - Removed and deprecated /cs set mlock, removed /cs clear, removed /os clearmodes, removed /cs akick (un)stick, added /cs clearusers
Revision 5f18cb0 - Sun, 12 Dec 2010 19:33:58 -0500 - Allow users to drop their own nickrequests
Revision 872bc3f - Sun, 12 Dec 2010 19:33:58 -0500 - Allow users to remove their own access in channels
Revision 1625a5a - Sun, 12 Dec 2010 19:33:58 -0500 - Added /chanserv clone command
Revision 2e9a632 - Sun, 12 Dec 2010 19:33:58 -0500 - Allow akill/szline/sqline to accept user names as a mask argument
Revision 3c9d4e9 - Sun, 12 Dec 2010 19:33:58 -0500 - Added command aliases
Revision c792c7f - Sun, 12 Dec 2010 19:33:58 -0500 - Switched the system for storing users, channels, and sesions to a patricia tree from STL's unordered_map, which was giving horrible performance.
Revision e512760 - Sun, 12 Dec 2010 19:33:50 -0500 - Fixed DNS caching and made DNS cache empty results
Revision ac41137 - Sun, 12 Dec 2010 19:31:00 -0500 - Added /ms ignore
Revision 28aba58 - Sun, 12 Dec 2010 19:30:28 -0500 - Just store lang strings in a char array, no need for the extra overhead of STL strings
Revision 4ec661c - Sun, 12 Dec 2010 19:30:14 -0500 - If a channel drops because a nick drops, set the channel founder to the user with the highest access if there is no successor
Revision 87bdf73 - Sun, 12 Dec 2010 19:30:14 -0500 - Document XMLRPC calls and added a .php class wrapper for them
Revision 21c8e89 - Sun, 12 Dec 2010 19:30:14 -0500 - Do not allow ghosting unidentified users if the recover command exists
Revision 8fbe366 - Sun, 12 Dec 2010 19:30:14 -0500 - Added m_xmlrpc and m_xmlrpc main, which allows remote programs to execute remote RPC calls to Anope in realtime and receive responses
Revision 5cd4fef - Sun, 12 Dec 2010 19:30:11 -0500 - Bump for 1.9.4-git
Revision 82e588a - Sun, 12 Dec 2010 18:42:14 -0500 - Anope 1.9.3 Release
Revision 7b7301e - Sun, 12 Dec 2010 18:40:04 -0500 - Made ./Config with a .git directory work ok if we are on a git tag
Revision 70d6537 - Sun, 12 Dec 2010 17:58:19 -0500 - Updated version.log
Revision af8cf44 - Sun, 12 Dec 2010 17:58:09 -0500 - Made version.cpp ok with an empty VERSION_EXTRA
Revision be4ec3c - Sun, 12 Dec 2010 16:54:46 -0500 - Updated docs/WIN32.txt with instructions on how to get the libraries to build with gettext, ssl, and mysql
Revision 587e5d9 - Thu, 9 Dec 2010 19:58:41 -0500 - Fixed build on cmake 2.4.x
@@ -2687,7 +3165,7 @@ Revision 17d9d5a - Fri, 31 Dec 2004 06:09:37 +0000 - BUILD : 1.7.6 (517) BUGS :
Revision 2a8bc51 - Thu, 30 Dec 2004 17:38:35 +0000 - BUILD : 1.7.6 (516) BUGS : 261 NOTES : This should be it finally! The moduleAddData function was using the old head to append/prepend the new moduleData to, but it had to use the new head. Thanks to DrStein for finding the cause! :)
Revision 35096db - Thu, 30 Dec 2004 17:12:06 +0000 - BUILD : 1.7.6 (515) BUGS : 261 NOTES : Fixed a few memleaks with moduleData functions returning early, and fixed the list handling with deleting moduleData (thanks DrStein)
Revision ae23e2f - Thu, 30 Dec 2004 16:51:04 +0000 - BUILD : 1.7.6 (514) BUGS : 261 NOTES : Modules can no longer call addCommand directly. The mod_name of the command MUST be set if it is a module.
Revision ae0f3c4 - Thu, 30 Dec 2004 15:00:22 +0000 - BUILD : 1.7.6 (513) BUGS : NOTES : Added warnings for NULL-args with sstrdup, and NULL modname with module*Data functions. Fixed Catserv to use moduleAddCommand instead of addCommand.
Revision ae0f3c48 - Thu, 30 Dec 2004 15:00:22 +0000 - BUILD : 1.7.6 (513) BUGS : NOTES : Added warnings for NULL-args with sstrdup, and NULL modname with module*Data functions. Fixed Catserv to use moduleAddCommand instead of addCommand.
Revision 2be6713 - Thu, 30 Dec 2004 14:27:22 +0000 - BUILD : 1.7.6 (512) BUGS : NOTES : Indenting src/modules.c correctly.... it got skipped somehow...
Revision 1fe375c - Thu, 30 Dec 2004 14:25:56 +0000 - BUILD : 1.7.6 (511) BUGS : NOTES : Rollback to 507
Revision 428c78c - Thu, 30 Dec 2004 05:55:10 +0000 - BUILD : 1.7.6 (510) BUGS : N/A NOTES : Clean up after the last commit
+18
View File
@@ -1,3 +1,21 @@
Anope Version 1.9.5
--------------------
A Extended LDAP support
A Added os_oper, os_kill, os_forbid, m_statusupdate, cs_sync, and bs_autoassign
A Added a new configuration file format
A Added a new commands system
A Added a new access system, and cs_flags
F Fixed not logging debug logs to file
F Fixed the mail delay time
F Fixed sending account data for unconfirmed nicks
F Fixed poll() engine build on FreeBSD
F Fixed really large HELP replies being truncated
F Fixed sometimes appending !*@* to valid hosts on access lists
F Fixed m_ssl sometimes failing connecting for no reason
F Fixed crash in cs_entrymsg
F Fixed setting -P on channels with only a botserv bot in it
F Fixed modemanager complaining about prefixless modes on InspIRCd
Anope Version 1.9.4
--------------------
A Automatically set channel founder to the user with the highest access if there is no successor
+4
View File
@@ -1,3 +1,7 @@
Anope Version 1.9.5
-------------------
Don't even try it, get a new config and start over.
Anope Version 1.9.4
-------------------
** ADDED CONFIGURATION DIRECTIVES **
+13 -6
View File
@@ -7,7 +7,7 @@ Anope Mutli Language Support
1) Building Anope with gettext support
To build Anope with gettext support gettext and its devlopmental libraries must be installed on the system.
To build Anope with gettext support, gettext and its development libraries must be installed on the system.
Anope does not require locales to be installed or enabled on the system, but does require the locales-all
package on Debian and Debian based systems.
@@ -32,8 +32,15 @@ Anope Mutli Language Support
3) Using langages with modules
Module authors can easially add the ability to have their modules translated by adding _() around the strings they
need translated (messages to the user, etc). See a few of the modules in /modules/extras (cs_appendtopic, hs_request)
for examples of this. If you want to translate a module someone has made, first generate a .pot file if there is none.
Run `xgettext -s -d modulename -o modulename.pot --from-code=utf-8 modulename.cpp`. Then, run msginit on the .pot file
with `msginit -l language -o modulename.language.po -i modulename.pot`. Translate the new .po file, then place it in
the lang folder and rerun ./Config; make && make install.
want translated (messages to the user, etc).
If you want to translate a module someone has made, first generate a .pot file if there isn't one already using
`xgettext -s -d modulename -o modulename.pot --from-code=utf-8 modulename.cpp`.
The .pot file is a template of all of the language strings extracted from the source file.
Next, run msginit on the .pot file with
`msginit -l language -o modulename.language.po -i modulename.pot`.
Translate the new .po file and rerun ./Config; make && make install.
All .po and .pot files should be placed in modules/language/third. Additionally an update script is provided there
that will create .pot files and merge any changes to it with existing .po files.
-31
View File
@@ -116,37 +116,6 @@ Table of Contents
* Christopher N. <saka@epiknet.org> (fr.l)
* Yusuf Kurekci <ysfm.20@gmail.com> (tr.l)
Anope uses the strlcat() and strlcpy() functions from OpenSSH 2.5.1p2.
These functions are copyrighted by Todd C. Miller:
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
2) Presentation
Anope is a set of Services for IRC networks that allows users to manage
+16 -25
View File
@@ -3,43 +3,34 @@ Legend:
? = unsure
+ = in progress
1.9.4
1.9.5
-----
[x] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
[x] Allow users to delete their own access
[x] ChanServ CLONE command
[x] XMLRPC to execute commands and get data from Anope
[+] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
[x] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc.
[ ] understanding extbans for /cs unban etc.
[ ] (optional?) A way to confirm email changes by users
[ ] Auto identify through SSL key
[ ] Optional os_login system that can also use SSL keys.
[ ] os_info module to show useful configuration settings to services opers.
[ ] Remove nick requests. Instead use an unconfirmed nick group which cant recieve umode +r and auto expires after 1d?
[ ] LDAP
[+] More LDAP
[x] Rewrite silly forbid system
[x] Fix the modules language system to work without needing its own functions..
[x] Rewrite commands system
[x] Rewrite access system
[x] NS INFO: separate field for last seen realhost, shown to SRA only
[x] Configurable bot usermodes
Future
------
[ ] NS IDENTIFY changes
[?] Last failed identify? Maybe more useful for sopers only, so users don't get unnecessarily worried
[?] Last successful login time/ip? perhaps both of these should be a new nick setting
[ ] NS INFO: seperate field for last seen realhost, shown to SRA only
[ ] NS SUSPEND: show suspender and reason, probably to sopers only (see CS SUSPEND)
[ ] Allow channel founders to change the fantasy trigger for their channel.
[ ] CIDR Akills, session exceptions, etc
[+] CIDR Akills, session exceptions, etc
[?] Language charset stuff, including collation (1.9.1? phoenix?)
[?] a way for a module to queue itself (or even another module) for unloading
[ ] Useful/common "third party" modules to core distro
[ ] NS AJOIN
[+] Useful/common "third party" modules to core distro
[x] NS AJOIN
[x] CS ENTRYMSG
[?] Don't allow soper accounts to expire
[?] Reason for CS SET RESTRICTED
[x] AKILL/SGLINE/etc..
[x] Setter
[x] Time added
[+] Time modified (can they be modified?)
[x] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human)
[x] Reason
[ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs
[ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs
[ ] HS ACTIVATE -ALL (rob sez this all needs reviewing)
[ ] No nickname ownership?
[ ] More commands need to be split up such as /bs bot, /ms set, /bs kick, /bs set, /os set? etc.
[ ] Customize email messages
+5 -4
View File
@@ -4,9 +4,10 @@ set_source_files_properties(version.cpp PROPERTIES LANGUAGE CXX COMPILE_FLAGS "$
add_executable(version version.cpp)
set_target_properties(version PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}")
get_target_property(version_BINARY version LOCATION)
# Modify version.h from the above executable, with dependencies to the given headers, version.cpp, and all source files in the main Anope build
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h
COMMAND ${version_BINARY} ${Anope_SOURCE_DIR}/src/version.sh ${CMAKE_CURRENT_SOURCE_DIR}/version.h
# Modify version.h from the above executable, with dependencies to version.cpp
# and all of the source files in the main build
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_build
COMMAND ${version_BINARY} ${Anope_SOURCE_DIR}/src/version.sh ${CMAKE_CURRENT_BINARY_DIR}/version.h
DEPENDS version ${SRC_SRCS}
)
# Add version to list of files for CPack to ignore
@@ -44,4 +45,4 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX)
# Add a custom target to the above file
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version.h ${PCH_SOURCES_GCH})
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version_build ${PCH_SOURCES_GCH})
+94
View File
@@ -0,0 +1,94 @@
#ifndef ACCESS_H
#define ACCESS_H
enum ChannelAccess
{
CA_ACCESS_LIST,
CA_NOKICK,
CA_FANTASIA,
CA_GREET,
CA_AUTOVOICE,
CA_VOICEME,
CA_VOICE,
CA_INFO,
CA_SAY,
CA_AUTOHALFOP,
CA_HALFOPME,
CA_HALFOP,
CA_KICK,
CA_SIGNKICK,
CA_BAN,
CA_TOPIC,
CA_MODE,
CA_GETKEY,
CA_INVITE,
CA_UNBAN,
CA_AUTOOP,
CA_OPDEOPME,
CA_OPDEOP,
CA_AUTOPROTECT,
CA_AKICK,
CA_BADWORDS,
CA_ASSIGN,
CA_MEMO,
CA_ACCESS_CHANGE,
CA_PROTECTME,
CA_PROTECT,
CA_SET,
CA_AUTOOWNER,
CA_OWNERME,
CA_OWNER,
CA_FOUNDER,
CA_SIZE
};
class ChanAccess;
class CoreExport AccessProvider : public Service
{
public:
AccessProvider(Module *o, const Anope::string &n);
virtual ~AccessProvider();
virtual ChanAccess *Create() = 0;
};
class CoreExport ChanAccess
{
public:
AccessProvider *provider;
ChannelInfo *ci;
Anope::string mask;
Anope::string creator;
time_t last_seen;
time_t created;
ChanAccess(AccessProvider *p);
virtual ~ChanAccess();
virtual bool Matches(User *u, NickCore *nc) = 0;
virtual bool HasPriv(ChannelAccess priv) = 0;
virtual Anope::string Serialize() = 0;
virtual void Unserialize(const Anope::string &data) = 0;
bool operator>(ChanAccess &other);
bool operator<(ChanAccess &other);
bool operator>=(ChanAccess &other);
bool operator<=(ChanAccess &other);
};
class CoreExport AccessGroup : public std::vector<ChanAccess *>
{
public:
ChannelInfo *ci;
NickCore *nc;
bool SuperAdmin, Founder;
AccessGroup();
bool HasPriv(ChannelAccess priv) const;
ChanAccess *Highest() const;
bool operator>(const AccessGroup &other) const;
bool operator<(const AccessGroup &other) const;
bool operator>=(const AccessGroup &other) const;
bool operator<=(const AccessGroup &other) const;
};
#endif
+20 -7
View File
@@ -6,8 +6,8 @@
class NickAlias;
class NickCore;
typedef unordered_map_namespace::unordered_map<Anope::string, NickAlias *, ci::hash, std::equal_to<ci::string> > nickalias_map;
typedef unordered_map_namespace::unordered_map<Anope::string, NickCore *, ci::hash, std::equal_to<ci::string> > nickcore_map;
typedef Anope::insensitive_map<NickAlias *> nickalias_map;
typedef Anope::insensitive_map<NickCore *> nickcore_map;
extern CoreExport nickalias_map NickAliasList;
extern CoreExport nickcore_map NickCoreList;
@@ -20,8 +20,6 @@ enum NickNameFlag
{
NS_BEGIN,
/* Nick may not be registered or used */
NS_FORBIDDEN,
/* Nick never expires */
NS_NO_EXPIRE,
/* This nick is being held after a kill by an enforcer client
@@ -39,7 +37,7 @@ enum NickNameFlag
};
const Anope::string NickNameFlagStrings[] = {
"BEGIN", "FORBIDDEN", "NO_EXPIRE", "HELD", "COLLIDED", ""
"BEGIN", "NO_EXPIRE", "HELD", "COLLIDED", ""
};
/** Flags set on NickCores
@@ -114,6 +112,7 @@ class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag, NS_EN
Anope::string last_quit; /* Last quit message */
Anope::string last_realname; /* Last realname */
Anope::string last_usermask; /* Last usermask */
Anope::string last_realhost; /* Last uncloaked usermask, requires nickserv/auspex to see */
time_t time_registered; /* When the nick was registered */
time_t last_seen; /* When it was seen online for the last time */
NickCore *nc; /* I'm an alias of this */
@@ -251,7 +250,7 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
/** Timer for colliding nicks to force people off of nicknames
*/
class NickServCollide : public Timer
class CoreExport NickServCollide : public Timer
{
dynamic_reference<User> u;
Anope::string nick;
@@ -273,9 +272,23 @@ class NickServCollide : public Timer
void Tick(time_t t);
};
/** Timers for removing HELD status from nicks.
*/
class NickServHeld : public Timer
{
dynamic_reference<NickAlias> na;
Anope::string nick;
public:
NickServHeld(NickAlias *n, long t);
~NickServHeld();
void Tick(time_t);
};
/** Timers for releasing nicks to be available for use
*/
class NickServRelease : public User, public Timer
class CoreExport NickServRelease : public User, public Timer
{
Anope::string nick;
+56 -18
View File
@@ -156,6 +156,12 @@ namespace Anope
*/
inline size_type length() const { return this->_string.length(); }
/**
* Returns the size of the currently allocated storage space in the string object.
* This can be equal or greater than the length of the string.
*/
inline size_type capacity() const { return this->_string.capacity(); }
/**
* Add a char to the end of the string.
*/
@@ -173,6 +179,17 @@ namespace Anope
inline iterator erase(const iterator &first, const iterator &last) { return this->_string.erase(first, last); }
inline void erase(size_type pos = 0, size_type n = std::string::npos) { this->_string.erase(pos, n); }
/**
* Trim leading and trailing white spaces from the string.
*/
inline void trim()
{
while (!this->_string.empty() && isspace(this->_string[0]))
this->_string.erase(this->_string.begin());
while (!this->_string.empty() && isspace(this->_string[this->_string.length() - 1]))
this->_string.erase(this->_string.length() - 1);
}
/**
* Clears the string.
*/
@@ -316,9 +333,9 @@ namespace Anope
*/
extern CoreExport bool Match(const Anope::string &str, const Anope::string &mask, bool case_sensitive = false);
/** Returns a list of pointers to message handlers
* @param The message name as sent by the IRCd
* @return a vector with pointers to the messagehandlers (you can bind more than one handler to a message)
/** Find a message in the message table
* @param name The name of the message were looking for
* @return NULL if we cant find it, or a pointer to the Message if we can
*/
extern CoreExport std::vector<Message *> FindMessage(const string &name);
@@ -335,6 +352,18 @@ namespace Anope
*/
extern CoreExport void Unhex(const Anope::string &src, Anope::string &dest);
extern CoreExport void Unhex(const Anope::string &src, char *dest);
/** Base 64 encode a string
* @param src The string to encode
* @param target Where the encoded string is placed
*/
extern CoreExport void B64Encode(const Anope::string &src, Anope::string &target);
/** Base 64 decode a string
* @param src The base64 encoded string
* @param target The plain text result
*/
extern CoreExport void B64Decode(const Anope::string &src, Anope::string &target);
/** Returns a sequence of data formatted as the format argument specifies.
** After the format parameter, the function expects at least as many
@@ -345,7 +374,12 @@ namespace Anope
*/
extern CoreExport string printf(const char *fmt, ...);
/** Return the last error, uses errno/GetLastError() to determin this
/** Return the last error code
* @return The error code
*/
extern CoreExport int LastErrorCode();
/** Return the last error, uses errno/GetLastError() to determine this
* @return An error message
*/
extern CoreExport const Anope::string LastError();
@@ -457,7 +491,7 @@ class dynamic_reference : public dynamic_reference_base
this->invalid = false;
this->ref = NULL;
}
else if (ref)
else if (this->operator bool())
ref->DelReference(this);
}
@@ -468,7 +502,21 @@ class dynamic_reference : public dynamic_reference_base
this->invalid = false;
this->ref = NULL;
}
return this->ref;
return this->ref != NULL;
}
virtual inline operator T*()
{
if (this->operator bool())
return this->ref;
return NULL;
}
virtual inline T *operator->()
{
if (this->operator bool())
return this->ref;
return NULL;
}
virtual inline void operator=(T *newref)
@@ -478,22 +526,12 @@ class dynamic_reference : public dynamic_reference_base
this->invalid = false;
this->ref = NULL;
}
else if (this->ref)
else if (this->operator bool())
this->ref->DelReference(this);
this->ref = newref;
if (this->ref)
if (this->operator bool())
this->ref->AddReference(this);
}
virtual inline T *operator->()
{
return this->ref;
}
virtual inline T *operator*()
{
return this->ref;
}
};
#endif // ANOPE_H
+31 -5
View File
@@ -8,12 +8,11 @@
#ifndef BOTS_H
#define BOTS_H
#include "commands.h"
class BotInfo;
extern CoreExport Anope::insensitive_map<BotInfo *> BotListByNick;
extern CoreExport Anope::map<BotInfo *> BotListByUID;
typedef Anope::insensitive_map<BotInfo *> botinfo_map;
/** Flags settable on a bot
*/
@@ -25,11 +24,13 @@ enum BotFlag
BI_CORE,
/* This bot can only be assigned by IRCops */
BI_PRIVATE,
/* This bot is defined in the config */
BI_CONF,
BI_END
};
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "" };
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "CONF", "" };
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
{
@@ -37,20 +38,26 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
uint32 chancount;
time_t created; /* Birth date ;) */
time_t lastmsg; /* Last time we said something */
CommandMap Commands; /* Commands on this bot */
typedef Anope::insensitive_map<CommandInfo> command_map;
command_map commands; /* Commands, actual name to service name */
Anope::string botmodes; /* Modes the bot should have as configured in service:modes */
bool introduced; /* Whether or not this bot is introduced */
/** Create a new bot.
* @param nick The nickname to assign to the bot.
* @param user The ident to give the bot.
* @param host The hostname to give the bot.
* @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 = "");
BotInfo(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 GenerateUID();
/** Change the nickname for the bot.
* @param newnick The nick to change to
*/
@@ -90,6 +97,25 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
* @param reason The reason we're parting
*/
void Part(Channel *c, const Anope::string &reason = "");
/** Called when a user messages this bot
* @param u The user
* @param message The users' message
*/
virtual void OnMessage(User *u, const Anope::string &message);
/** Link a command name to a command in services
* @param cname The command name
* @param sname The service name
* @param permission Permission required to execute the command, if any
*/
void SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission = "");
/** Get command info for a command
* @param cname The command name
* @return A struct containing service name and permission
*/
CommandInfo *GetCommand(const Anope::string &cname);
};
#endif // BOTS_H
+6 -33
View File
@@ -9,41 +9,12 @@
#ifndef CHANNELS_H
#define CHANNELS_H
typedef unordered_map_namespace::unordered_map<Anope::string, Channel *, ci::hash, std::equal_to<ci::string> > channel_map;
typedef Anope::insensitive_map<Channel *> channel_map;
extern CoreExport channel_map ChannelList;
struct UserData
{
UserData()
{
Clear();
}
virtual ~UserData() { }
void Clear()
{
last_use = last_start = Anope::CurTime;
lines = times = 0;
lastline.clear();
}
/* Data validity */
time_t last_use;
/* for flood kicker */
int16 lines;
time_t last_start;
/* for repeat kicker */
Anope::string lastline;
int16 times;
};
struct UserContainer
struct UserContainer : public Extensible
{
User *user;
UserData ud;
ChannelStatus *Status;
UserContainer(User *u) : user(u) { }
@@ -54,6 +25,8 @@ typedef std::list<UserContainer *> CUserList;
enum ChannelFlag
{
/* ChanServ is currently holding the channel */
CH_INHABIT,
/* Channel still exists when emptied */
CH_PERSIST,
/* If set the channel is syncing users (channel was just created) and it should not be deleted */
@@ -62,6 +35,8 @@ enum ChannelFlag
CH_LOGCHAN
};
const Anope::string ChannelFlagString[] = { "CH_INABIT", "CH_PERSIST", "CH_SYNCING", "CH_LOGCHAN", "" };
class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
{
public:
@@ -93,8 +68,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
Anope::string topic_setter; /* Who set the topic */
time_t topic_time; /* When the topic was set*/
std::list<BanData *> bd;
time_t server_modetime; /* Time of last server MODE */
time_t chanserv_modetime; /* Time of last check_modes() */
int16 server_modecount; /* Number of server MODEs this second */
+27 -59
View File
@@ -18,54 +18,39 @@ class Module;
class BotInfo;
class Command;
typedef std::map<Anope::string, Command *, std::less<ci::string> > CommandMap;
/** The return value from commands.
*/
enum CommandReturn
{
MOD_CONT,
MOD_STOP
};
extern CoreExport Command *FindCommand(BotInfo *bi, const Anope::string &cmd);
extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cmd);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &message);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope::string &command, const Anope::string &message);
enum CommandFlag
{
CFLAG_ALLOW_UNREGISTERED,
CFLAG_ALLOW_FORBIDDEN,
CFLAG_ALLOW_SUSPENDED,
CFLAG_ALLOW_UNREGISTEREDCHANNEL,
CFLAG_STRIP_CHANNEL,
CFLAG_DISABLE_FANTASY
CFLAG_STRIP_CHANNEL
};
const Anope::string CommandFlagStrings[] = {
"CFLAG_ALLOW_UNREGISTERED",
"CFLAG_ALLOW_FORBIDDEN",
"CFLAG_ALLOW_SUSPENDED",
"CFLAG_ALLOW_UNREGISTEREDCHANNEL",
"CFLAG_STRIP_CHANNEL",
"CFLAG_DISABLE_FANTASY",
""
};
struct CommandInfo
{
Anope::string name;
Anope::string permission;
};
/* The source for a command */
struct CoreExport CommandSource
{
/* User executing the command */
User *u;
/* Channel (if applicable) */
ChannelInfo *ci;
/* Channel the command was executed on (fantasy) */
Channel *c;
/* The service this command is on */
BotInfo *owner;
/* The service the reply should come from, *not* necessarily the service the command is on */
BotInfo *service;
/* Whether or not this was a fantasy command */
bool fantasy;
/* The actual name of the command being executed */
Anope::string command;
/* The permission of the command being executed */
Anope::string permission;
std::list<Anope::string> reply;
@@ -77,44 +62,49 @@ struct CoreExport CommandSource
/** Every services command is a class, inheriting from Command.
*/
class CoreExport Command : public Flags<CommandFlag>, public Base
class CoreExport Command : public Service, public Flags<CommandFlag>
{
Anope::string desc;
std::vector<Anope::string> syntax;
public:
/* Maximum paramaters accepted by this command */
size_t MaxParams;
/* Minimum parameters required to use this command */
size_t MinParams;
/* Command name */
Anope::string name;
/* Permission needed to use this comand */
Anope::string permission;
/* Module which owns us */
Module *module;
/* Service this command is on */
BotInfo *service;
/** Create a new command.
* @param owner The owner of the command
* @param sname The command name
* @param min_params The minimum number of parameters the parser will require to execute this command
* @param max_params The maximum number of parameters the parser will create, after max_params, all will be combined into the last argument.
* NOTE: If max_params is not set (default), there is no limit to the max number of params.
*/
Command(const Anope::string &sname, size_t min_params, size_t max_params = 0, const Anope::string &spermission = "");
Command(Module *owner, const Anope::string &sname, size_t min_params, size_t max_params = 0);
virtual ~Command();
protected:
void SetDesc(const Anope::string &d);
void ClearSyntax();
void SetSyntax(const Anope::string &s);
void SendSyntax(CommandSource &);
void SendSyntax(CommandSource &, const Anope::string &syntax);
public:
/** Get the command description
* @return The commands description
*/
const Anope::string &GetDesc() const;
/** Execute this command.
* @param source The source
* @param params Command parameters
*/
virtual CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
/** Called when HELP is requsted for the client this command is on.
* @param source The source
@@ -133,28 +123,6 @@ class CoreExport Command : public Flags<CommandFlag>, public Base
* @param subcommand The subcommand the user tried to use
*/
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand);
/** Set which command permission (e.g. chanserv/forbid) is required for this command.
* @param reststr The permission required to successfully execute this command
*/
void SetPermission(const Anope::string &reststr);
/** Add a subcommand to this command
* @param creator The creator of the subcommand
* @param c The command
*/
virtual bool AddSubcommand(Module *creator, Command *c);
/** Delete a subcommand from this command
* @param c The command
*/
virtual bool DelSubcommand(Command *c);
/** Find a subcommand
* @param name The subcommand name
* @return The subcommand
*/
virtual Command *FindSubcommand(const Anope::string &subcommand);
};
#endif // COMMANDS_H
+20 -144
View File
@@ -33,7 +33,6 @@ enum ConfigDataType
DT_INTEGER, // Integer
DT_UINTEGER, // Unsigned Integer
DT_LUINTEGER, // Long Unsigned Integer
DT_CHARPTR, // Char pointer
DT_STRING, // Anope::string
DT_BOOLEAN, // Boolean
DT_HOSTNAME, // Hostname syntax
@@ -42,7 +41,7 @@ enum ConfigDataType
DT_TIME, // Time value
DT_NORELOAD = 32, // Item can't be reloaded after startup
DT_ALLOW_WILD = 64, // Allow wildcards/CIDR in DT_IPADDRESS
DT_ALLOW_NEWLINE = 128 // New line characters allowed in DT_CHARPTR
DT_ALLOW_NEWLINE = 128 // New line characters allowed in DT_STRING
};
/** Holds a config value, either string, integer or boolean.
@@ -57,28 +56,16 @@ class CoreExport ValueItem
/** Actual data */
Anope::string v;
public:
/** Initialize with nothing */
ValueItem();
/** Initialize with an int */
ValueItem(int);
/** Initialize with a bool */
ValueItem(bool);
/** Initialize with a char pointer */
ValueItem(const char *);
/** Initialize with an std::string */
ValueItem(const std::string &);
/** Initialize with a ci::string */
ValueItem(const ci::string &);
/** Initialize with an Anope::string */
ValueItem(const Anope::string &);
/** Initialize with a long */
ValueItem(long);
/** Change value to a char pointer */
//void Set(char *);
/** Change value to a const char pointer */
void Set(const char *);
/** Change value to an std::string */
void Set(const std::string &);
/** Change value to a ci::string */
void Set(const ci::string &);
/** Change value to an Anope::string */
void Set(const Anope::string &);
/** Change value to an int */
@@ -137,40 +124,6 @@ template<typename T> class ValueContainer : public ValueContainerBase
}
};
/** This a specific version of ValueContainer to handle character arrays specially
*/
template<> class ValueContainer<char **> : public ValueContainerBase
{
private:
/** Contained item */
char **val;
public:
/** Initialize with nothing */
ValueContainer() : ValueContainerBase(), val(NULL) { }
/** Initialize with a value of type T */
ValueContainer(char **Val) : ValueContainerBase(), val(Val) { }
/** Initialize with a copy */
ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
ValueContainer &operator=(const ValueContainer &Val)
{
val = Val.val;
return *this;
}
/** Change value to type T of size s */
void Set(const char *newval, size_t s)
{
if (*val)
delete [] *val;
if (!*newval)
{
*val = NULL;
return;
}
*val = new char[s];
strlcpy(*val, newval, s);
}
};
/** This a specific version of ValueContainer to handle Anope::string specially
*/
template<> class ValueContainer<Anope::string *> : public ValueContainerBase
@@ -217,11 +170,6 @@ typedef ValueContainer<unsigned *> ValueContainerUInt;
*/
typedef ValueContainer<long unsigned *> ValueContainerLUInt;
/** A specialization of ValueContainer to hold a pointer to
* a char array.
*/
typedef ValueContainer<char **> ValueContainerChar;
/** A specialization of ValueContainer to hold a pointer to
* an int
*/
@@ -264,7 +212,6 @@ bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateDefCon(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data);
bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
@@ -395,22 +342,15 @@ class CoreExport ServerConfig
/** Below here is a list of variables which contain the config files values
*/
/* IRCd module in use */
Anope::string IRCDModule;
/* Host to connect to **/
/* Host to bind to */
Anope::string LocalHost;
/* List of uplink servers to try and connect to */
std::list<Uplink *> Uplinks;
std::vector<Uplink *> Uplinks;
/* Our server name */
Anope::string ServerName;
/* Our servers description */
Anope::string ServerDesc;
/* The username/ident of services clients */
Anope::string ServiceUser;
/* The hostname if services clients */
Anope::string ServiceHost;
/* Name of the network were on */
Anope::string NetworkName;
@@ -424,41 +364,19 @@ class CoreExport ServerConfig
/* Max length of passwords */
unsigned PassLen;
/* NickServ Name */
Anope::string s_NickServ;
/* ChanServ Name */
Anope::string s_ChanServ;
/* MemoServ Name */
Anope::string s_MemoServ;
/* BotServ Name */
Anope::string s_BotServ;
/* OperServ name */
Anope::string s_OperServ;
/* Global name */
Anope::string s_GlobalNoticer;
/* NickServs realname */
Anope::string desc_NickServ;
/* ChanServ realname */
Anope::string desc_ChanServ;
/* MemoServ realname */
Anope::string desc_MemoServ;
/* BotServ realname */
Anope::string desc_BotServ;
/* OperServ realname */
Anope::string desc_OperServ;
/* Global realname */
Anope::string desc_GlobalNoticer;
/* HostServ Name */
Anope::string s_HostServ;
/* HostServ realname */
Anope::string desc_HostServ;
/* Filename for the PID file */
Anope::string PIDFilename;
/* MOTD filename */
Anope::string MOTDFilename;
Anope::string BotServ;
Anope::string ChanServ;
Anope::string Global;
Anope::string HostServ;
Anope::string NickServ;
Anope::string OperServ;
Anope::string MemoServ;
/* True if its ok to not be able to save backs */
bool NoBackupOkay;
/* Do password checking when new people register */
@@ -501,8 +419,6 @@ class CoreExport ServerConfig
Anope::string BotModes;
/* THe actual modes */
ChannelStatus BotModeList;
/* How many times to try and reconnect to the uplink before giving up */
unsigned MaxRetries;
/* How long to wait between connection attempts */
int RetryWait;
/* If services should hide unprivileged commands */
@@ -550,8 +466,6 @@ class CoreExport ServerConfig
time_t NSExpire;
/* How long before suspended nicks expire */
time_t NSSuspendExpire;
/* How long before forbidden nicks expire */
time_t NSForbidExpire;
/* Time before unconfirmed nicks expire */
time_t NSUnconfirmedExpire;
/* Force email when registering */
@@ -568,8 +482,6 @@ class CoreExport ServerConfig
Anope::string NSEnforcerHost;
/* How long before recovered nicks are released */
time_t NSReleaseTimeout;
/* /nickserv list is oper only */
bool NSListOpersOnly;
/* Max number of entries that can be returned from the list command */
unsigned NSListMax;
/* Only allow usermode +a etc on real services admins */
@@ -578,6 +490,8 @@ class CoreExport ServerConfig
bool NSStrictPrivileges;
/* Use email to verify new users registering */
bool NSEmailReg;
/* Core NickServ modules */
Anope::string NickCoreModules;
/* Set the proper channel modes on users when they identify */
bool NSModeOnID;
/* Add the users hostnask their access list when they register */
@@ -585,6 +499,8 @@ class CoreExport ServerConfig
/* Maximum number of channels on AJoin */
unsigned AJoinMax;
/* Core ChanServ modules */
Anope::string ChanCoreModules;
/* Default flags for newly registered channels */
Flags<ChannelInfoFlag, CI_END> CSDefFlags;
/* Max number of channels a user can own */
@@ -605,8 +521,6 @@ class CoreExport ServerConfig
Anope::string CSAutokickReason;
/* Time ChanServ should stay in the channel to hold it to keep users from getting in */
time_t CSInhabit;
/* ChanServ's LIST command is oper only */
bool CSListOpersOnly;
/* Max number of entries allowed to be returned from the LIST command */
unsigned CSListMax;
/* true to make ChanServ oper only */
@@ -621,7 +535,9 @@ class CoreExport ServerConfig
/* Who can use memos reciepts */
unsigned MSMemoReceipt;
/* Defai;t BotServ flags */
/* Core BotServ modules */
Anope::string BotCoreModules;
/* Default BotServ flags */
Flags<BotServFlag> BSDefFlags;
/* How long before botserv forgets a user. This is used for flood kickers etc */
time_t BSKeepData;
@@ -706,46 +622,6 @@ class CoreExport ServerConfig
/* List of modules to autoload */
std::list<Anope::string> ModulesAutoLoad;
/* Encryption modules */
std::list<Anope::string> EncModuleList;
/* Database modules */
std::list<Anope::string> DBModuleList;
/* HostServ Core Modules */
std::list<Anope::string> HostServCoreModules;
/* MemoServ Core Modules */
std::list<Anope::string> MemoServCoreModules;
/* BotServ Core Modules */
std::list<Anope::string> BotServCoreModules;
/* OperServ Core Modules */
std::list<Anope::string> OperServCoreModules;
/* NickServ Core Modules */
std::list<Anope::string> NickServCoreModules;
/* ChanServ Core Modules */
std::list<Anope::string> ChanServCoreModules;
/* Default defcon level */
int DefConLevel;
/* Timeout before defcon is reset */
time_t DefConTimeOut;
/* Session limiit to use when using defcon */
unsigned DefConSessionLimit;
/* How long to add akills for defcon */
time_t DefConAKILL;
/* Chan modes for defcon */
Anope::string DefConChanModes;
/* Should we global on defcon */
bool GlobalOnDefcon;
/* Should we send DefconMessage aswell? */
bool GlobalOnDefconMore;
/* Message to send when defcon is off */
Anope::string DefConOffMessage;
/* Message to send when defcon is on*/
Anope::string DefconMessage;
/* Reason to akill clients for defcon */
Anope::string DefConAkillReason;
/* The socket engine in use */
Anope::string SocketEngine;
/* User keys to use for generating random hashes for pass codes etc */
unsigned long UserKey1;
+7 -21
View File
@@ -137,40 +137,26 @@ struct CoreExport DNSRecord
operator bool() const;
};
/** The socket used to talk to the nameserver, uses UDP
*/
class DNSSocket : public ConnectionSocket
{
private:
int SendTo(const unsigned char *buf, size_t len) const;
int RecvFrom(char *buf, size_t size, sockaddrs &addrs) const;
public:
DNSSocket();
virtual ~DNSSocket();
bool ProcessRead();
bool ProcessWrite();
};
/** DNS manager, manages the connection and all requests
*/
class CoreExport DNSManager : public Timer
class CoreExport DNSManager : public Timer, public Socket
{
std::multimap<Anope::string, DNSRecord *> cache;
sockaddrs addrs;
public:
DNSSocket *sock;
std::deque<DNSPacket *> packets;
std::map<short, DNSRequest *> requests;
static const int DNSPort = 53;
DNSManager();
DNSManager(const Anope::string &nameserver, int port);
~DNSManager();
bool ProcessRead();
bool ProcessWrite();
void AddCache(DNSRecord *rr);
bool CheckCache(DNSRequest *request);
void Tick(time_t now);
+12 -138
View File
@@ -17,8 +17,6 @@
#include "hashcomp.h"
E void ModuleRunTimeDirCleanUp();
/* IRC Variables */
E IRCDVar *ircd;
@@ -27,101 +25,49 @@ E IRCdMessage *ircdmessage;
/**** actions.c ****/
E void kill_user(const Anope::string &source, User *user, const Anope::string &reason);
E bool bad_password(User *u);
E void common_unban(ChannelInfo *ci, User *u, bool full = false);
E BotInfo *BotServ;
E BotInfo *ChanServ;
E BotInfo *Global;
E BotInfo *HostServ;
E BotInfo *MemoServ;
E BotInfo *NickServ;
E BotInfo *OperServ;
/**** botserv.c ****/
E void get_botserv_stats(long *nrec, long *memuse);
E void bs_init();
E void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf);
E BotInfo *findbot(const Anope::string &nick);
/** Finds a pseudoclient, given a UID. Useful for TS6 protocol modules.
* @param uid The UID to search for
* @return The pseudoclient structure, or NULL if one could not be found
*/
E Anope::string normalizeBuffer(const Anope::string &);
E void check_ban(ChannelInfo *ci, User *u, int ttbtype);
E void bot_kick(ChannelInfo *ci, User *u, const char *message, ...);
E void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
E void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
/**** channels.c ****/
E void get_channel_stats(long *nrec, long *memuse);
E Channel *findchan(const Anope::string &chan);
E User *nc_on_chan(Channel *c, const NickCore *nc);
E Anope::string get_xop_level(int level);
E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts);
E void do_join(const Anope::string &source, const Anope::string &channels, const Anope::string &ts);
E void do_kick(const Anope::string &source, const Anope::string &channel, const Anope::string &users, const Anope::string &reason);
E void do_part(const Anope::string &source, const Anope::string &channels, const Anope::string &reason);
E void MassChannelModes(BotInfo *bi, const Anope::string &modes);
E void chan_set_correct_modes(User *user, Channel *c, int give_modes);
inline BotInfo *whosends(ChannelInfo *ci)
{
if (!ci || !ci->bi || !ci->c || !ci->botflags.HasFlag(BS_SYMBIOSIS) || !ci->c->FindUser(ci->bi))
return ChanServ ? ChanServ : NickServ;
return ci->bi;
}
/**** chanserv.c ****/
E LevelInfo levelinfo[];
E void get_chanserv_stats(long *nrec, long *memuse);
E void reset_levels(ChannelInfo *ci);
E void cs_init();
E void expire_chans();
E void cs_remove_nick(NickCore *nc);
E void check_modes(Channel *c);
E int check_valid_admin(User *user, Channel *chan, int servermode);
E int check_valid_op(User *user, Channel *chan, int servermode);
E ChannelInfo *cs_findchan(const Anope::string &chan);
E int check_access(User *user, ChannelInfo *ci, int what);
E bool IsFounder(User *user, ChannelInfo *ci);
E void update_cs_lastseen(User *user, ChannelInfo *ci);
E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret);
E int levelinfo_maxwidth;
E Anope::string get_mlock_modes(ChannelInfo *ci, int complete);
/**** config.c ****/
E ConfigurationFile services_conf;
E ServerConfig *Config;
/* hostserv.c */
E void do_on_id(User *u);
E void HostServSyncVhosts(NickAlias *na);
/**** encrypt.c ****/
E int enc_encrypt(const Anope::string &src, Anope::string &dest);
E int enc_decrypt(const Anope::string &src, Anope::string &dest);
E void enc_encrypt(const Anope::string &src, Anope::string &dest);
E bool enc_decrypt(const Anope::string &src, Anope::string &dest);
/**** hostserv.c ****/
E void get_hostserv_stats(long *nrec, long *memuse);
E void hostserv_init();
/**** init.c ****/
@@ -129,7 +75,6 @@ E void introduce_user(const Anope::string &user);
E bool GetCommandLineArgument(const Anope::string &name, char shortname = 0);
E bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::string &param);
E void Init(int ac, char **av);
E Uplink *uplink_server;
/**** ircd.c ****/
E void pmodule_ircd_proto(IRCDProto *);
@@ -138,16 +83,12 @@ E void pmodule_ircd_message(IRCdMessage *message);
/**** language.cpp ****/
E std::vector<Anope::string> languages;
E std::vector<Anope::string> domains;
E void InitLanguages();
E const Anope::string GetString(NickCore *nc, const char *string);
E const Anope::string GetString(const Anope::string &domain, const Anope::string &lang, const char *string);
E void PushLanguage(const Anope::string &, Anope::string);
E void PopLanguage();
E const char *anope_gettext(const char *string);
E void SyntaxError(CommandSource &source, const Anope::string &command, const Anope::string &message);
/*** logger.cpp ***/
E void InitLogChannels(ServerConfig *);
E const char *translate(const char *string);
E const char *translate(User *u, const char *string);
E const char *translate(NickCore *nc, const char *string);
E const char *anope_gettext(const char *lang, const char *string);
/**** main.c ****/
@@ -161,36 +102,15 @@ E bool noexpire;
E bool protocoldebug;
E bool quitting;
E bool shutting_down;
E bool restarting;
E Anope::string quitmsg;
E bool save_data;
E time_t start_time;
E ConnectionSocket *UplinkSock;
E int CurrentUplink;
E void save_databases();
E void expire_all();
E void sighandler(int signum);
E void do_restart_services();
/* The socket to our uplink */
class CoreExport UplinkSocket : public ConnectionSocket
{
public:
UplinkSocket(bool ipv6 = false);
virtual ~UplinkSocket();
bool Read(const Anope::string &buf);
};
/**** memoserv.c ****/
E void ms_init();
E void rsend_notify(CommandSource &source, Memo *m, const Anope::string &chan);
E void check_memos(User *u);
E MemoInfo *getmemoinfo(const Anope::string &name, bool &ischan, bool &isforbid);
E void memo_send(CommandSource &source, const Anope::string &name, const Anope::string &text, int z);
/**** messages.cpp ****/
@@ -225,17 +145,11 @@ E bool OnError(const Anope::string &, const std::vector<Anope::string> &);
E bool IsFile(const Anope::string &filename);
E int toupper(char);
E int tolower(char);
#ifndef HAVE_STRLCPY
E size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
E size_t strlcat(char *, const char *, size_t);
#endif
E time_t dotime(const Anope::string &s);
E Anope::string duration(time_t seconds);
E Anope::string duration(const time_t &seconds, NickCore *nc = NULL);
E Anope::string expire_left(NickCore *nc, time_t expires);
E Anope::string do_strftime(const time_t &t);
E Anope::string do_strftime(const time_t &t, NickCore *nc = NULL, bool short_output = false);
E bool doValidHost(const Anope::string &host, int type);
E bool isValidHost(const Anope::string &host, int type);
@@ -244,7 +158,6 @@ E bool isvalidchar(char c);
E Anope::string myStrGetToken(const Anope::string &str, char dilim, int token_number);
E Anope::string myStrGetTokenRemainder(const Anope::string &str, char dilim, int token_number);
E int myNumToken(const Anope::string &str, char dilim);
E void EnforceQlinedNick(const Anope::string &nick, const Anope::string &killer);
E bool nickIsServices(const Anope::string &nick, bool bot);
E void add_entropy_userkeys();
@@ -253,13 +166,12 @@ E unsigned char getrandom8();
E uint16 getrandom16();
E uint32 getrandom32();
E char *str_signed(unsigned char *str);
E std::list<Anope::string> BuildStringList(const Anope::string &, char = ' ');
E std::vector<Anope::string> BuildStringVector(const Anope::string &, char = ' ');
E bool str_is_wildcard(const Anope::string &str);
E bool str_is_pure_wildcard(const Anope::string &str);
E Anope::string normalizeBuffer(const Anope::string &);
/**** modes.cpp ****/
/* Number of generic modes we support */
@@ -269,15 +181,9 @@ E void SetDefaultMLock(ServerConfig *config);
/**** nickserv.c ****/
E void get_aliases_stats(long &count, long &mem);
E void get_core_stats(long &count, long &mem);
E void change_core_display(NickCore *nc);
E void change_core_display(NickCore *nc, const Anope::string &newdisplay);
E int do_setmodes(User *u);
E void ns_init();
E int validate_user(User *u);
E void expire_nicks();
E NickAlias *findnick(const Anope::string &nick);
E NickCore *findcore(const Anope::string &nick);
E bool is_on_access(const User *u, const NickCore *nc);
@@ -292,27 +198,8 @@ E void send_cmd(const Anope::string &source, const char *fmt, ...) FORMAT(printf
E void notice_server(const Anope::string &source, const Server *s, const char *fmt, ...) FORMAT(printf, 3, 4);
/**** sessions.c ****/
E std::vector<Exception *> exceptions;
E void get_session_stats(long &count, long &mem);
E void get_exception_stats(long &count, long &mem);
E void add_session(User *u);
E void del_session(User *u);
E void expire_exceptions();
E Session *findsession(const Anope::string &host);
E Exception *find_host_exception(const Anope::string &host);
E Exception *find_hostip_exception(const Anope::string &host, const Anope::string &hostip);
E int exception_add(User *u, const Anope::string &mask, unsigned limit, const Anope::string &reason, const Anope::string &who, time_t expires);
/**** sockets.cpp ****/
E SocketEngineBase *SocketEngine;
E int32 TotalRead;
E int32 TotalWritten;
E SocketIO normalSocketIO;
@@ -323,8 +210,6 @@ E int32 opcnt;
E uint32 maxusercnt, usercnt;
E time_t maxusertime;
E void get_user_stats(long &count, long &mem);
E User *finduser(const Anope::string &nick);
E User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid, const Anope::string &modes);
@@ -333,18 +218,7 @@ E void do_umode(const Anope::string &user, const Anope::string &modes);
E void do_kill(User *user, const Anope::string &reason);
E bool matches_list(Channel *c, User *user, ChannelModeName mode);
E bool is_excepted_mask(ChannelInfo *ci, const Anope::string &mask);
E Anope::string create_mask(User *u);
/******************************************************************************/
E void b64_encode(const Anope::string &src, Anope::string &target);
E void b64_decode(const Anope::string &src, Anope::string &target);
#ifdef _WIN32
E Anope::string GetWindowsVersion();
E bool SupportedWindowsVersion();
#endif
#endif /* EXTERN_H */
+90 -105
View File
@@ -6,110 +6,95 @@
* Please read COPYING and README for further details.
*/
#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 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."
#define PASSWORD_TOO_LONG "Your password is too long. Please try again with a shorter password."
#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_FORBIDDEN "Nick \002%s\002 may not be registered or used."
#define NICK_X_FORBIDDEN_OPER "Nick \002%s\002 has been forbidden by %s:\n" \
"%s"
#define NICK_X_SUSPENDED "Nick %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 CHAN_X_FORBIDDEN "Channel \002%s\002 may not be registered or used."
#define CHAN_X_FORBIDDEN_OPER "Channel \002%s\002 has been forbidden by %s:\n" \
"%s"
#define NICK_IDENTIFY_REQUIRED "Password authentication required for that command.\n" \
"Retry after typing \002%s%s IDENTIFY \037password\037\002."
#define MAIL_X_INVALID "\002%s\002 is not a valid e-mail address."
#define NO_REASON "No reason"
#define UNKNOWN "<unknown>"
#define NO_EXPIRE "does not expire"
#define END_OF_ANY_LIST "End of \002%s\002 list."
#define LIST_INCORRECT_RANGE "Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002."
#define UNKNOWN_OPTION "Unknown option \002%s\002.\n" \
"Type %s%s HELP %s for more information."
#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" \
#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. Please try again with a shorter password.")
#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 NO_REASON _("No reason")
#define UNKNOWN _("<unknown>")
#define NO_EXPIRE _("does not expire")
#define END_OF_ANY_LIST _("End of \002%s\002 list.")
#define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.")
#define UNKNOWN_OPTION _("Unknown option \002%s\002.\n" \
"Type %s%s HELP %s for more information.")
#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_SYNTAX "SET \037option\037 \037parameters\037"
#define NICK_SET_DISABLED "Sorry, nickname option setting is temporarily disabled."
#define NICK_SET_UNKNOWN_OPTION "Unknown SET option \002%s%s\002."
#define NICK_SET_DISPLAY_CHANGED "The new display is now \002%s\002."
#define NICK_SASET_SYNTAX "SASET \037nickname\037 \037option\037 \037parameters\037"
#define NICK_SASET_DISPLAY_INVALID "The new display for \002%s\002 MUST be a nickname of the nickname group!"
#define NICK_SASET_PASSWORD_FAILED "Sorry, couldn't change password for \002%s\002."
#define NICK_SASET_PASSWORD_CHANGED "Password for \002%s\002 changed."
#define NICK_SASET_PASSWORD_CHANGED_TO "Password for \002%s\002 changed to \002%s\002."
#define NICK_INFO_OPTIONS " Options: %s"
#define NICK_LIST_SYNTAX "LIST \037pattern\037"
#define LIST_HEADER "List of entries matching \002%s\002:"
#define NICK_RECOVERED "User claiming your nick has been killed.\n" \
"\002%s%s RELEASE %s\002 to get it back before %s timeout."
#define NICK_REQUESTED "This nick has already been requested, please check your e-mail address for the pass code"
#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_SASET_SYNTAX "SASET \002channel\002 \037option\037 \037parameters\037"
#define CHAN_SET_SYNTAX "SET \037channel\037 \037option\037 \037parameters\037"
#define CHAN_SET_DISABLED "Sorry, channel option setting is temporarily disabled."
#define CHAN_SETTING_CHANGED "%s for %s set to %s."
#define CHAN_SETTING_UNSET "%s for %s unset."
#define CHAN_SET_MLOCK_DEPRECATED "MLOCK is deprecated. Use \002%s%s HELP MODE\002 instead."
#define CHAN_ACCESS_LEVEL_RANGE "Access level must be between %d and %d inclusive."
#define CHAN_ACCESS_LIST_HEADER "Access list for %s:\n" \
" Num Lev Mask"
#define CHAN_ACCESS_VIEW_XOP_FORMAT " %3d %s %s\n" \
" by %s, last seen %s"
#define CHAN_ACCESS_VIEW_AXS_FORMAT " %3d %4d %s\n" \
" by %s, last seen %s"
#define CHAN_AKICK_VIEW_FORMAT "%3d %s (by %s on %s)\n" \
" %s"
#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 have been removed."
#define CHAN_LIST_ENTRY "%3d %s\n" \
" Added by %s on %s"
#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_SYNTAX "SEND {\037nick\037 | \037channel\037} \037memo-text\037"
#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.\n" \
"Type %s%s HELP ASSIGN for more information."
#define BOT_NOT_ON_CHANNEL "Bot is not on channel \002%s\002."
#define BOT_ASSIGN_READONLY "Sorry, bot assignment is temporarily disabled."
#define ENABLED "Enabled"
#define DISABLED "Disabled"
#define OPER_LIST_FORMAT " %3d %-32s %s"
#define OPER_VIEW_FORMAT "%3d %s (by %s on %s; %s)\n" \
" %s"
#define HOST_SET_ERROR "A vhost must be in the format of a valid hostmask."
#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 host shorter than %d characters."
#define HOST_SET_IDENTTOOLONG "Error! The 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"
"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_SYNTAX _("SET \037option\037 \037parameters\037")
#define NICK_SET_DISABLED _("Sorry, nickname option setting is temporarily disabled.")
#define NICK_SET_UNKNOWN_OPTION _("Unknown SET option \002%s%s\002.")
#define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.")
#define NICK_LIST_SYNTAX _("LIST \037pattern\037")
#define LIST_HEADER _("List of entries matching \002%s\002:")
#define NICK_RECOVERED _("User claiming your nick has been killed.\n" \
"\002%s%s RELEASE %s\002 to get it back before %s timeout.")
#define NICK_REQUESTED _("This nick has already been requested, please check your e-mail address for the pass code")
#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_SET_DISABLED _("Sorry, channel option setting is temporarily disabled.")
#define CHAN_SETTING_CHANGED _("%s for %s set to %s.")
#define CHAN_SETTING_UNSET _("%s for %s unset.")
#define CHAN_SET_MLOCK_DEPRECATED _("MLOCK is deprecated. Use \002%s%s HELP MODE\002 instead.")
#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
#define CHAN_ACCESS_LIST_HEADER _("Access list for %s:\n" \
" Num Lev Mask")
#define CHAN_ACCESS_VIEW_AXS_FORMAT _(" %3d %4d %s\n" \
" by %s on %s, last seen %s")
#define CHAN_AKICK_VIEW_FORMAT _("%3d %s (by %s on %s)\n" \
" %s")
#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 have been removed.")
#define CHAN_LIST_ENTRY _("%3d %s\n" \
" Added by %s on %s")
#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_SYNTAX _("SEND {\037nick\037 | \037channel\037} \037memo-text\037")
#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 BOT_ASSIGN_READONLY _("Sorry, bot assignment is temporarily disabled.")
#define ENABLED _("Enabled")
#define DISABLED _("Disabled")
#define OPER_LIST_FORMAT _(" %3d %-32s %s")
#define OPER_VIEW_FORMAT _("%3d %s (by %s on %s; %s)\n" \
" %s")
#define HOST_SET_ERROR _("A vhost must be in the format of a valid hostmask.")
#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 host shorter than %d characters.")
#define HOST_SET_IDENTTOOLONG _("Error! The 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")
+4 -6
View File
@@ -29,6 +29,8 @@ struct LogFile
Anope::string GetName() const;
};
class Command;
class CoreExport Log
{
public:
@@ -39,7 +41,7 @@ class CoreExport Log
std::stringstream buf;
Log(LogType type = LOG_NORMAL, const Anope::string &category = "", BotInfo *bi = Global);
Log(LogType type = LOG_NORMAL, const Anope::string &category = "", BotInfo *bi = NULL);
/* LOG_COMMAND/OVERRIDE/ADMIN */
Log(LogType type, User *u, Command *c, ChannelInfo *ci = NULL);
@@ -88,11 +90,7 @@ class CoreExport LogInfo
void AddType(std::list<Anope::string> &list, const Anope::string &type);
bool HasType(std::list<Anope::string> &list, const Anope::string &type) const;
std::list<Anope::string> &GetList(LogType type);
bool HasType(LogType Type);
bool HasType(LogType ltype, const Anope::string &type) const;
void ProcessMessage(const Log *l);
};
+1 -11
View File
@@ -193,7 +193,7 @@ class CoreExport ChannelMode : public Mode
* NOTE: User CAN be NULL, this is for checking if it can be locked with defcon
* @param u The user, or NULL
*/
bool CanSet(User *u) const;
virtual bool CanSet(User *u) const;
/** Returns the mode name as a string
*/
@@ -289,16 +289,6 @@ class CoreExport ChannelModeStatus : public ChannelMode
virtual ~ChannelModeStatus();
};
/** Channel mode +b
*/
class CoreExport ChannelModeBan : public ChannelModeList
{
public:
ChannelModeBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { }
void OnAdd(Channel *chan, const Anope::string &mask);
};
/** Channel mode +k (key)
*/
class CoreExport ChannelModeKey : public ChannelModeParam
+2 -1
View File
@@ -2,7 +2,8 @@
#define MODULE_H
#include "services.h"
#include "commands.h"
#include "modules.h"
#include "oper.h"
#include "commands.h"
#endif // MODULE_H
+136 -175
View File
@@ -17,7 +17,6 @@
#include <stdio.h>
#include "timers.h"
#include "hashcomp.h"
#include "commands.h"
/* Cross OS compatibility macros */
#ifdef _WIN32
@@ -27,7 +26,7 @@
# define dlsym(file, symbol) (HMODULE)GetProcAddress(file, symbol)
# define dlclose(file) FreeLibrary(file) ? 0 : 1
# define ano_modclearerr() SetLastError(0)
# define ano_moderr() Anope::LastError().c_str()
# define ano_moderr() (Anope::LastError().empty() ? NULL : Anope::LastError().c_str())
#else
typedef void * ano_module_t;
@@ -127,10 +126,6 @@ else \
class Message;
extern CoreExport Module *FindModule(const Anope::string &name);
int protocol_module_init();
extern CoreExport bool moduleMinVersion(int major, int minor, int patch, int build);
enum ModuleReturn
{
MOD_ERR_OK,
@@ -138,15 +133,9 @@ enum ModuleReturn
MOD_ERR_PARAMS,
MOD_ERR_EXISTS,
MOD_ERR_NOEXIST,
MOD_ERR_NOUSER,
MOD_ERR_NOLOAD,
MOD_ERR_NOUNLOAD,
MOD_ERR_SYNTAX,
MOD_ERR_NODELETE,
MOD_ERR_UNKNOWN,
MOD_ERR_FILE_IO,
MOD_ERR_NOSERVICE,
MOD_ERR_NO_MOD_NAME,
MOD_ERR_EXCEPTION,
MOD_ERR_VERSION
};
@@ -155,7 +144,7 @@ enum ModuleReturn
*/
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 MODType { MT_BEGIN, THIRD, QATESTED, SUPPORTED, CORE, DATABASE, ENCRYPTION, PROTOCOL, SOCKETENGINE, MT_END };
enum ModType { MT_BEGIN, THIRD, SUPPORTED, CORE, DATABASE, ENCRYPTION, PROTOCOL, MT_END };
typedef std::multimap<Anope::string, Message *> message_map;
extern CoreExport message_map MessageMap;
@@ -197,8 +186,9 @@ class Version
int GetBuild() const;
};
/* Forward declaration of CallBack class for the Module class */
class CallBack;
class XLineManager;
struct CommandSource;
/** Every module in Anope is actually a class.
*/
@@ -211,6 +201,10 @@ class CoreExport Module : public Extensible
*/
Anope::string name;
/** What type this module is
*/
ModType type;
/** The temporary path/filename
*/
Anope::string filename;
@@ -235,24 +229,17 @@ class CoreExport Module : public Extensible
*/
Anope::string author;
/** What type this module is
*/
MODType type;
/** Creates and initialises a new module.
* @param modname The module name
* @param loadernick The nickname of the user loading the module.
* @param type The module type
*/
Module(const Anope::string &modname, const Anope::string &loadernick);
Module(const Anope::string &modname, const Anope::string &loadernick, ModType type = THIRD);
/** Destroys a module, freeing resources it has allocated.
*/
virtual ~Module();
/** Sets a given type (CORE,PROTOCOL,3RD etc) on a module.
* @param type The type to set the module as.
*/
void SetType(MODType type);
/** Toggles the permanent flag on a module. If a module is permanent,
* then it may not be unloaded.
*
@@ -283,28 +270,6 @@ class CoreExport Module : public Extensible
*/
Version GetVersion() const;
/** Send a message to a user in their language, if a translation is available
* @param source The source of the message
* @param fmt The message
*/
void SendMessage(CommandSource &source, const char *fmt, ...);
/**
* Add a module provided command to the given service.
* @param bi The service to add the command to
* @param c The command to add
* @return MOD_ERR_OK on successfully adding the command
*/
int AddCommand(BotInfo *bi, Command *c);
/**
* Delete a command from the service given.
* @param bi The service to remove the command from
* @param c Thec command to delete
* @return returns MOD_ERR_OK on success
*/
int DelCommand(BotInfo *bi, Command *c);
/** Called when the ircd notifies that a user has been kicked from a channel.
* @param c The channel the user has been kicked from.
* @param target The user that has been kicked.
@@ -314,9 +279,8 @@ class CoreExport Module : public Extensible
virtual void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &kickmsg) { }
/** Called when Services' configuration has been loaded.
* @param startup True if Services is starting for the first time, false otherwise.
*/
virtual void OnReload(bool startup) {}
virtual void OnReload() { }
/** Called before a bot is assigned to a channel.
* @param sender The user assigning the bot
@@ -333,20 +297,11 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) { return EVENT_CONTINUE; }
/** Called after a user has been introduced, but before any type
* of checking has been done (akills, defcon, s*lines, etc)
* return EVENT_STOP here to allow the user to get by untouched,
* or kill them then return EVENT_STOP to tell Anope the user no
* longer exists
* @param u The user
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing
*/
virtual EventReturn OnPreUserConnect(User *u) { return EVENT_CONTINUE; }
/** 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) { }
virtual void OnUserConnect(dynamic_reference<User> &u, bool &exempt) { }
/** Called when a new server connects to the network.
* @param s The server that has connected to the network
@@ -359,15 +314,17 @@ class CoreExport Module : public Extensible
*/
virtual void OnUserNickChange(User *u, const Anope::string &oldnick) { }
/** Called immediatly when a user tries to run a command
* @param u The user
* @param bi The bot the command is being run from
* @param command The command
* @param message The parameters used for the command
* @param ci If a tanasy command, the channel the comman was used on
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
/** Called when someone uses the generic/help command
* @param source Command source
* @param params Params
*/
virtual EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci) { return EVENT_CONTINUE; }
virtual void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) { }
/** Called when someone uses the generic/help command
* @param source Command source
* @param params Params
*/
virtual void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) { }
/** Called before a command is due to be executed.
* @param source The source of the command
@@ -375,7 +332,7 @@ class CoreExport Module : public Extensible
* @param params The parameters the user is sending
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called after a command has been executed.
* @param source The source of the command
@@ -474,6 +431,13 @@ class CoreExport Module : public Extensible
*/
virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) { }
/** Called when a user leaves a channel.
* From either parting, being kicked, or quitting/killed!
* @param u The user
* @param c The channel
*/
virtual void OnLeaveChannel(User *u, Channel *c) { }
/** Called before a user joins a channel
* @param u The user
* @param c The channel
@@ -504,12 +468,9 @@ class CoreExport Module : public Extensible
*/
virtual void OnChanExpire(ChannelInfo *ci) { }
/** Called before Anope connects to its uplink
* @param u The uplink we're going to connect to
* @param Number What number the uplink is
* @return Other than EVENT_CONTINUE to stop attempting to connect
/** Called before Anope connecs to its uplink
*/
virtual EventReturn OnPreServerConnect(Uplink *u, int Number) { return EVENT_CONTINUE; }
virtual void OnPreServerConnect() { }
/** Called when Anope connects to its uplink
*/
@@ -523,16 +484,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnServerDisconnect() { }
/** Called before the database expire routines are called
* Note: Code that is in seperate expiry routines should just be done
* when we save the DB, theres no need to have both
*/
virtual void OnPreDatabaseExpire() { }
/** Called when the database expire routines are called
*/
virtual void OnDatabaseExpire() { }
/** Called when the flatfile dbs are being written
* @param Write A callback to the function used to insert a line into the database
*/
@@ -600,28 +551,14 @@ class CoreExport Module : public Extensible
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci) { }
/** Called before services restart
*/
virtual void OnPreRestart() { }
/** Called when services restart
*/
virtual void OnRestart() { }
/** Called before services shutdown
*/
virtual void OnPreShutdown() { }
/** Called when services shutdown
*/
virtual void OnShutdown() { }
/** Called on signal
* @param signum The signum
* @param msg The quitmsg
*/
virtual void OnSignal(int signum, const Anope::string &msg) { }
/** Called before a nick expires
* @param na The nick
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
@@ -638,25 +575,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnDefconLevel(int level) { }
/** Called before an akill is added
* @param u The user adding the akill
* @param ak The akill
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnAddAkill(User *u, XLine *ak) { return EVENT_CONTINUE; }
/** Called before an akill is deleted
* @param u The user removing the akill
* @param ak The akill, can be NULL for all akills!
*/
virtual void OnDelAkill(User *u, XLine *ak) { }
/** Called after an exception has been added
* @param u The user who added it
* @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(User *u, Exception *ex) { return EVENT_CONTINUE; }
virtual EventReturn OnExceptionAdd(Exception *ex) { return EVENT_CONTINUE; }
/** Called before an exception is deleted
* @param u The user who is deleting it
@@ -666,18 +589,24 @@ class CoreExport Module : public Extensible
/** Called before a XLine is added
* @param u The user adding the XLine
* @param sx The XLine
* @param Type The type of XLine this is
* @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(User *u, XLine *x, XLineType Type) { return EVENT_CONTINUE; }
virtual EventReturn OnAddXLine(User *u, XLine *x, XLineManager *xlm) { return EVENT_CONTINUE; }
/** Called before a XLine is deleted
* @param u The user deleting the XLine
* @param sx The XLine, can be NULL for all XLines
* @param Type The type of XLine this is
* @param x The XLine, can be NULL for all XLines
* @param xlm The xline manager it was deleted from
*/
virtual void OnDelXLine(User *u, XLine *x, XLineType Type) { }
virtual void OnDelXLine(User *u, XLine *x, XLineManager *xlm) { }
/** Called when a user is checked for whether they are a services oper
* @param u The user
* @return EVENT_ALLOW to allow, anything else to deny
*/
virtual EventReturn IsServicesOper(User *u) { return EVENT_CONTINUE; }
/** Called when a server quits
* @param server The server
@@ -717,13 +646,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { }
/** Called when access is changed
* @param ci The channel
* @param u The user who changed the access
* @param u access The access changed
*/
virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { }
/** Called when access is added
* @param ci The channel
* @param u The user who added the access
@@ -770,6 +692,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnChanUnsuspend(ChannelInfo *ci) { }
/** Called when a channel is being created, for any reason
* @param ci The channel
*/
virtual void OnCreateChan(ChannelInfo *ci) { }
/** Called when a channel is being deleted, for any reason
* @param ci The channel
*/
@@ -799,6 +726,14 @@ class CoreExport Module : public Extensible
*/
virtual void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) { }
/** Called after a user join a channel when we decide whether to kick them or not
* @param u The user
* @param ci The channel
* @param kick Set to true to kick
* @return EVENT_ALLOW to stop processing immediatly
*/
virtual EventReturn OnCheckKick(User *u, ChannelInfo *ci, bool &kick) { return EVENT_CONTINUE; }
/** Called when a user requests info for a channel
* @param source The user requesting info
* @param ci The channel the user is requesting info for
@@ -811,6 +746,20 @@ class CoreExport Module : public Extensible
*/
virtual void OnFindChan(const Anope::string &chname) { }
/** 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(ChanAccess *access, ChannelAccess priv) { return EVENT_CONTINUE; }
/** 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, ChannelAccess priv) { return EVENT_CONTINUE; }
/** Called when a nick is dropped
* @param u The user dropping the nick
* @param na The nick
@@ -930,7 +879,12 @@ class CoreExport Module : public Extensible
* @param password The password
* @return EVENT_ALLOW to allow the password, EVENT_STOP to stop processing completely
*/
virtual EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
virtual EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
/** Called when a user does /ns update
* @param u The user
*/
virtual void OnNickUpdate(User *u) { }
/** Called when we get informed about a users SSL fingerprint
* when we call this, the fingerprint should already be stored in the user struct
@@ -938,6 +892,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnFingerprint(User *u) { }
/** Called when a user becomes (un)away
* @param message The message, is .empty() if unaway
*/
virtual void OnUserAway(User *u, const Anope::string &message) { }
/** Called when a vhost is deleted
* @param na The nickalias of the vhost
*/
@@ -949,18 +908,12 @@ class CoreExport Module : public Extensible
virtual void OnSetVhost(NickAlias *na) { }
/** Called when a memo is sent
* @param u The user sending the memo
* @param nc The nickcore of who the memo was sent to
* @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(User *u, NickCore *nc, Memo *m) { }
/** Called when a memo is sent
* @param u The user sending the memo
* @param ci The channel the memo was sent to
* @param m The memo
*/
virtual void OnMemoSend(User *u, ChannelInfo *ci, Memo *m) { }
virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) { }
/** Called when a memo is deleted
* @param nc The nickcore of the memo being deleted
@@ -1058,21 +1011,14 @@ class CoreExport Module : public Extensible
* @param message The message
* @return EVENT_STOP to halt processing
*/
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, const Anope::string &message) { return EVENT_CONTINUE; }
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) { return EVENT_CONTINUE; }
/** Called when we receive a PRIVMSG for a registered channel we are in
* @param u The source of the message
* @param ci The channel
* @param c The channel
* @param msg The message
* @param Allow set to false to make the flood kickers halt
* @return MOD_STOP to stop processing completely
*/
virtual EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) { return EVENT_CONTINUE; }
/** Called when any object is destroyed
* @param b The object
*/
virtual void OnObjectDestroy(Base *b) { }
virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg) { }
};
/** Implementation-specific flags which may be set in ModuleManager::Attach()
@@ -1087,12 +1033,13 @@ enum Implementation
I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
I_OnNickClearCert, I_OnNickAddCert, I_OnNickEraseCert,
I_OnNickInfo, I_OnFindNick, I_OnFindCore, I_OnCheckAuthentication,
I_OnNickUpdate,
/* ChanServ */
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel,
I_OnChanInfo, I_OnFindChan,
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnCreateChan, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick,
I_OnChanInfo, I_OnFindChan, I_OnCheckPriv, I_OnGroupCheckPriv,
/* BotServ */
I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign,
@@ -1105,28 +1052,27 @@ enum Implementation
I_OnMemoSend, I_OnMemoDel,
/* Users */
I_OnPreUserConnect, I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnFingerprint,
I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnLeaveChannel, I_OnFingerprint, I_OnUserAway,
/* OperServ */
I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
I_OnAddXLine, I_OnDelXLine,
I_OnAddXLine, I_OnDelXLine, I_IsServicesOper,
/* Database */
I_OnPostLoadDatabases, I_OnSaveDatabase, I_OnLoadDatabase,
I_OnDatabaseExpire,
I_OnDatabaseWrite, I_OnDatabaseRead, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata,
/* Modules */
I_OnModuleLoad, I_OnModuleUnload,
/* Other */
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun,
I_OnPreCommand, I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
I_OnReload, I_OnNewServer, I_OnPreServerConnect, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect,
I_OnPreHelp, I_OnPostHelp, I_OnPreCommand, I_OnPostCommand, I_OnRestart, I_OnShutdown,
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnObjectDestroy,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg,
I_END
};
@@ -1146,6 +1092,10 @@ class CoreExport ModuleManager
*/
static std::vector<Module *> EventHandlers[I_END];
/** Clean up the module runtime directory
*/
static void CleanupRuntimeDirectory();
/** Load up a list of modules.
* @param module_list The list of modules to load
**/
@@ -1165,6 +1115,27 @@ class CoreExport ModuleManager
*/
static ModuleReturn UnloadModule(Module *m, User * u);
/** Find a module
* @param name The module name
* @return The module
*/
static Module *FindModule(const Anope::string &name);
/** Find the first module of a certain type
* @param type The module type
* @return The module
*/
static Module *FindFirstOf(ModType type);
/** Checks whether this version of Anope is at least major.minor.patch.build
* Throws a ModuleException if not
* @param major The major version
* @param minor The minor vesion
* @param patch The patch version
* @param build The build version
*/
static void RequireVersion(int major, int minor, int patch, int build);
/** 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
@@ -1222,8 +1193,7 @@ class CoreExport ModuleManager
*/
static void ClearCallBacks(Module *m);
/** Unloading all modules, NEVER call this when Anope isn't shutting down.
* Ever.
/** Unloading all modules except the protocol module.
*/
static void UnloadAll();
@@ -1245,11 +1215,17 @@ class CoreExport ModuleManager
*/
static Service *GetService(const Anope::string &name);
/** Get the existing service key names
* @return The keys
*/
static std::vector<Anope::string> GetServiceKeys();
private:
/** Call the module_delete function to safely delete the module
* @param m the module to delete
* @return MOD_ERR_OK on success, anything else on fail
*/
static void DeleteModule(Module *m);
static ModuleReturn DeleteModule(Module *m);
};
/** Class used for callbacks within modules
@@ -1272,17 +1248,6 @@ class CallBack : public Timer
}
};
class CoreExport Service : public Base
{
public:
Module *owner;
Anope::string name;
Service(Module *o, const Anope::string &n);
virtual ~Service();
};
template<typename T>
class service_reference : public dynamic_reference<T>
{
@@ -1293,10 +1258,6 @@ class service_reference : public dynamic_reference<T>
{
}
virtual ~service_reference()
{
}
operator bool()
{
if (this->invalid)
+16 -104
View File
@@ -6,41 +6,10 @@
* Please read COPYING and README for further details.
*/
#ifndef OPERSERV_H
#define OPERSERV_H
extern CoreExport std::vector<NewsItem *> News;
extern CoreExport std::vector<std::bitset<32> > DefCon;
extern CoreExport bool DefConModesSet;
extern CoreExport Flags<ChannelModeName, CMODE_END * 2> DefConModesOn;
extern CoreExport Flags<ChannelModeName, CMODE_END * 2> DefConModesOff;
extern CoreExport std::map<ChannelModeName, Anope::string> DefConModesOnParams;
#ifndef OPER_H
#define OPER_H
class XLineManager;
extern CoreExport XLineManager *SGLine;
extern CoreExport XLineManager *SZLine;
extern CoreExport XLineManager *SQLine;
extern CoreExport XLineManager *SNLine;
extern CoreExport bool SetDefConParam(ChannelModeName, const Anope::string &);
extern CoreExport bool GetDefConParam(ChannelModeName, Anope::string &);
extern CoreExport void UnsetDefConParam(ChannelModeName);
extern CoreExport bool CheckDefCon(DefconLevel Level);
extern CoreExport bool CheckDefCon(int level, DefconLevel Level);
extern CoreExport void AddDefCon(int level, DefconLevel Level);
extern CoreExport void DelDefCon(int level, DefconLevel Level);
extern CoreExport void os_init();
extern CoreExport void oper_global(const Anope::string &nick, const char *fmt, ...);
extern CoreExport void server_global(const Server *s, const Anope::string &message);
enum XLineType
{
X_SNLINE,
X_SQLINE,
X_SZLINE
};
class CoreExport XLine
{
@@ -60,24 +29,29 @@ class CoreExport XLine
Anope::string GetHost() const;
};
class CoreExport XLineManager
class CoreExport XLineManager : public Service
{
private:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
char type;
protected:
/* List of XLines in this XLineManager */
std::vector<XLine *> XLines;
public:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
/** Constructor
*/
XLineManager();
XLineManager(Module *creator, const Anope::string &name, char t);
/** Destructor
*/
virtual ~XLineManager();
/** The type of xline provided by this service
* @return The type
*/
const char &Type();
/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
* It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
* clients and one handing them free olines, you would want the akilling one first. This way if a client
@@ -129,14 +103,13 @@ class CoreExport XLineManager
void Clear();
/** Add an entry to this XLine Manager
* @param bi The bot error replies should be sent from
* @param u The user adding the XLine
* @param mask The mask of the XLine
* @param creator The creator of the XLine
* @param expires When this should expire
* @param reaosn The reason
* @return A pointer to the XLine
*/
virtual XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
virtual XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
private:
/** Delete an XLine, eg, remove it from the IRCd.
@@ -186,65 +159,4 @@ class CoreExport XLineManager
virtual void Send(User *u, XLine *x) = 0;
};
/* This is for AKILLS */
class SGLineManager : public XLineManager
{
public:
XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
class SNLineManager : public XLineManager
{
public:
XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
XLine *Check(User *u);
};
class SQLineManager : public XLineManager
{
public:
XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
static bool Check(Channel *c);
};
class SZLineManager : public XLineManager
{
public:
XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
void Del(XLine *x);
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
#endif // OPERSERV_H
#endif // OPER_H
+9 -4
View File
@@ -12,15 +12,16 @@
class OperType;
struct Oper
struct CoreExport Oper
{
Anope::string name;
Anope::string password;
Anope::string certfp;
OperType *ot;
bool config;
Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) :
name(n), password(p), certfp(c), ot(o) { }
name(n), password(p), certfp(c), ot(o), config(false) { }
/** Find an oper block by name
* @param name The name
@@ -55,6 +56,10 @@ class CoreExport OperType
*/
std::set<OperType *> inheritances;
public:
/** Modes to set when someone identifys using this opertype
*/
Anope::string modes;
/** Find an oper type by name
* @param name The name
* @return The oper type
@@ -100,12 +105,12 @@ class CoreExport OperType
/** Gets the icommands for this opertype
* @return A list of commands
*/
const std::list<Anope::string> &GetCommands() const;
const std::list<Anope::string> GetCommands() const;
/** Gets the privileges for this opertype
* @return A list of privileges
*/
const std::list<Anope::string> &GetPrivs() const;
const std::list<Anope::string> GetPrivs() const;
};
#endif // OPERTYPE_H
+41 -76
View File
@@ -9,7 +9,7 @@
#ifndef REGCHANNEL_H
#define REGCHANNEL_H
typedef unordered_map_namespace::unordered_map<Anope::string, ChannelInfo *, ci::hash, std::equal_to<ci::string> > registered_channel_map;
typedef Anope::insensitive_map<ChannelInfo *> registered_channel_map;
extern CoreExport registered_channel_map RegisteredChannelList;
/** Flags used for the ChannelInfo class
@@ -18,8 +18,6 @@ enum ChannelInfoFlag
{
CI_BEGIN,
/* ChanServ is currently holding the channel */
CI_INHABIT,
/* Retain the topic even after the channel is emptied */
CI_KEEPTOPIC,
/* Don't allow non-authorized users to be opped */
@@ -34,8 +32,6 @@ enum ChannelInfoFlag
CI_PEACE,
/* Don't allow any privileges unless a user is IDENTIFIED with NickServ */
CI_SECURE,
/* Don't allow the channel to be registered or used */
CI_FORBIDDEN,
/* Channel does not expire */
CI_NO_EXPIRE,
/* Channel memo limit may not be changed */
@@ -48,8 +44,6 @@ enum ChannelInfoFlag
CI_SIGNKICK,
/* Sign kicks if level is < than the one defined by the SIGNKIGK level */
CI_SIGNKICK_LEVEL,
/* Uses XOP */
CI_XOP,
/* Channel is suspended */
CI_SUSPENDED,
/* Channel still exists when emptied, this can be caused by setting a perm
@@ -63,22 +57,9 @@ enum ChannelInfoFlag
};
const Anope::string ChannelInfoFlagStrings[] = {
"BEGIN", "INHABIT", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
"PEACE", "SECURE", "FORBIDDEN", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
"SIGNKICK", "SIGNKICK_LEVEL", "XOP", "SUSPENDED", "PERSIST", ""
};
class CoreExport ChanAccess
{
Anope::string mask; /* Mask of the access entry */
public:
int16 level;
NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
time_t last_seen;
Anope::string creator;
ChanAccess(const Anope::string &umask);
const Anope::string &GetMask();
"BEGIN", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
"PEACE", "SECURE", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
"SIGNKICK", "SIGNKICK_LEVEL", "SUSPENDED", "PERSIST", ""
};
/** Flags for auto kick
@@ -120,14 +101,15 @@ struct ModeLock
class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, CI_END>
{
private:
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
private:
std::vector<ChanAccess *> access; /* List of authorized users */
NickCore *founder; /* Channel founder */
std::vector<ChanAccess *> access; /* List of authorized users */
std::vector<AutoKick *> akick; /* List of users to kickban */
std::vector<BadWord *> badwords; /* List of badwords */
ModeList mode_locks;
public:
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
ModeList mode_locks;
/** Default constructor
* @param chname The channel name
*/
@@ -136,14 +118,13 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
/** Copy constructor
* @param ci The ChannelInfo to copy settings to
*/
ChannelInfo(ChannelInfo *ci);
ChannelInfo(ChannelInfo &ci);
/** Default destructor
*/
~ChannelInfo();
Anope::string name; /* Channel name */
NickCore *founder;
NickCore *successor; /* Who gets the channel if the founder nick is dropped or expires */
Anope::string desc;
@@ -154,38 +135,41 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
Anope::string last_topic_setter; /* Setter */
time_t last_topic_time; /* Time */
// These two should be using extensible
Anope::string forbidby;
Anope::string forbidreason;
int16 bantype;
int16 *levels; /* Access levels for commands */
int16 levels[CA_SIZE];
MemoInfo memos;
Channel *c; /* Pointer to channel record (if channel is currently in use) */
/* For BotServ */
BotInfo *bi; /* Bot used on this channel */
Flags<BotServFlag> botflags;
int16 *ttb; /* Times to ban for each kicker */
int16 ttb[TTB_SIZE]; /* Times to ban for each kicker */
int16 capsmin, capspercent; /* For CAPS kicker */
int16 floodlines, floodsecs; /* For FLOOD kicker */
int16 repeattimes; /* For REPEAT kicker */
/** Add an entry to the channel access list
*
* @param mask The mask of the access entry
* @param level The channel access level the user has on the channel
* @param creator The user who added the access
* @param last_seen When the user was last seen within the channel
* @return The new access class
*
* Creates a new access list entry and inserts it into the access list.
/** Change the founder of the channek
* @params nc The new founder
*/
ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0);
void SetFounder(NickCore *nc);
/** Get the founder of the channel
* @return The founder
*/
NickCore *GetFounder() const;
/** Find which bot should send mode/topic/etc changes for this channel
* @return The bot
*/
BotInfo *WhoSends();
/** 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
*
@@ -196,36 +180,11 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
ChanAccess *GetAccess(unsigned index);
/** Get an entry from the channel access list by User
*
* @param u The User to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @return A ChanAccess struct corresponding to the User, or NULL if not found
*
* Retrieves an entry from the access list that matches the given User, optionally also matching a certain level.
/** 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).
*/
ChanAccess *GetAccess(User *u, int16 level = 0);
/** Get an entry from the channel access list by NickCore
*
* @param u The NickCore to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
*
* Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
*/
ChanAccess *GetAccess(NickCore *nc, int16 level = 0);
/** Get an entry from the channel access list by mask
*
* @param u The mask to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @param wildcard True to match using wildcards
* @return A ChanAccess struct corresponding to the mask, or NULL if not found
*
* Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level.
*/
ChanAccess *GetAccess(const Anope::string &mask, int16 level = 0, bool wildcard = true);
AccessGroup AccessFor(User *u);
AccessGroup AccessFor(NickCore *nc);
/** Get the size of the accss vector for this channel
* @return The access vector size
@@ -371,6 +330,12 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
ModeLock *GetMLock(ChannelModeName mname, const Anope::string &param = "");
/** Get the current mode locks as a string
* @param complete True to show mlock parameters aswell
* @return A string of mode locks, eg: +nrt
*/
Anope::string GetMLockAsString(bool complete) const;
/** Check whether a user is permitted to be on this channel
* @param u The user
* @return true if they are allowed, false if they aren't and were kicked
@@ -392,7 +357,7 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
/** A timer used to keep the BotServ bot/ChanServ in the channel
* after kicking the last user in a channel
*/
class ChanServTimer : public Timer
class CoreExport ChanServTimer : public Timer
{
private:
dynamic_reference<Channel> c;
+7 -2
View File
@@ -6,8 +6,8 @@ extern CoreExport Server *Me;
extern CoreExport void do_server(const Anope::string &source, const Anope::string &servername, unsigned int hops, const Anope::string &descript, const Anope::string &numeric);
extern CoreExport const char *ts6_uid_retrieve();
extern CoreExport const char *ts6_sid_retrieve();
extern CoreExport const Anope::string ts6_uid_retrieve();
extern CoreExport const Anope::string ts6_sid_retrieve();
/* Types of capab
*/
@@ -107,6 +107,11 @@ class CoreExport Server : public Flags<ServerFlag>
*/
const Anope::string &GetDescription() const;
/** Change this servers SID
* @param sid The new SID
*/
void SetSID(const Anope::string &sid);
/** Get the server numeric/SID
* @return The numeric/SID
*/
+73 -164
View File
@@ -45,10 +45,8 @@
#if GETTEXT_FOUND
# include <libintl.h>
# define _(x) anope_gettext(x)
#else
# define _(x) x
#endif
#define _(x) x
#ifndef _WIN32
# include <unistd.h>
@@ -59,9 +57,6 @@
# include <sys/socket.h>
# include <sys/time.h>
# include <dirent.h>
# ifdef HAVE_BACKTRACE
# include <execinfo.h>
# endif
# define DllExport
# define CoreExport
# define MARK_DEPRECATED __attribute((deprecated))
@@ -244,6 +239,23 @@ class DatabaseException : public CoreException
virtual ~DatabaseException() throw() { }
};
class Signal
{
static std::vector<Signal *> SignalHandlers;
static void SignalHandler(int signal);
struct sigaction action, old;
sig_atomic_t called;
public:
static void Process();
int signal;
Signal(int s);
~Signal();
virtual void OnSignal() = 0;
};
/** Debug cast to be used instead of dynamic_cast, this uses dynamic_cast
* for debug builds and static_cast on releass builds to speed up the program
* because dynamic_cast relies on RTTI.
@@ -272,6 +284,7 @@ template<typename T, size_t Size = 32> class Flags
const Anope::string *Flag_Strings;
public:
Flags() : Flag_Strings(NULL) { }
Flags(const Anope::string *flag_strings) : Flag_Strings(flag_strings) { }
/** Add a flag to this item
@@ -332,6 +345,20 @@ template<typename T, size_t Size = 32> class Flags
}
};
class Module;
class CoreExport Service : public Base
{
public:
Module *owner;
Anope::string name;
Service(Module *o, const Anope::string &n);
virtual ~Service();
};
#include "sockets.h"
#include "socketengine.h"
#include "extensible.h"
@@ -409,7 +436,6 @@ class ChannelInfo;
class Channel;
class Server;
class Entry;
struct Session;
#include "threadengine.h"
#include "opertype.h"
@@ -454,13 +480,11 @@ enum MemoFlag
/* Memo is unread */
MF_UNREAD,
/* Sender requests a receipt */
MF_RECEIPT,
/* Memo is a notification of receipt */
MF_NOTIFYS
MF_RECEIPT
};
const Anope::string MemoFlagStrings[] = {
"MF_UNREAD", "MF_RECEIPT", "MF_NOTIFYS", ""
"MF_UNREAD", "MF_RECEIPT", ""
};
/* Memo info structures. Since both nicknames and channels can have memos,
@@ -478,7 +502,7 @@ struct CoreExport MemoInfo
{
int16 memomax;
std::vector<Memo *> memos;
std::vector<ci::string> ignores;
std::vector<Anope::string> ignores;
unsigned GetIndex(Memo *m) const;
void Del(unsigned index);
@@ -486,6 +510,23 @@ struct CoreExport MemoInfo
bool HasIgnore(User *u);
};
struct Session
{
Anope::string host; /* Host of the session */
unsigned count; /* Number of clients with this host */
unsigned hits; /* Number of subsequent kills for a host */
};
struct Exception
{
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 */
};
/*************************************************************************/
class CoreExport HostInfo
@@ -535,28 +576,6 @@ class CoreExport HostInfo
const time_t GetTime() const;
};
enum AccessLevel
{
/* Note that these two levels also serve as exclusive boundaries for valid
* access levels. ACCESS_FOUNDER may be assumed to be strictly greater
* than any valid access level, and ACCESS_INVALID may be assumed to be
* strictly less than any valid access level. Also read below.
*/
ACCESS_FOUNDER = 10001, /* Numeric level indicating founder access */
ACCESS_INVALID = -10000, /* Used in levels[] for disabled settings */
/* There is one exception to the above access levels: SuperAdmins will have
* access level 10001. This level is never stored, however; it is only used
* in comparison and to let SuperAdmins win from founders where needed
*/
ACCESS_SUPERADMIN = 10002,
/* Levels for xOP */
ACCESS_VOP = 3,
ACCESS_HOP = 4,
ACCESS_AOP = 5,
ACCESS_SOP = 10,
ACCESS_QOP = 10000
};
/** Flags for badwords
*/
enum BadWordType
@@ -578,51 +597,6 @@ struct BadWord
BadWordType type;
};
/* Indices for cmd_access[]: */
enum ChannelAccess
{
CA_INVITE,
CA_AKICK,
CA_SET, /* but not FOUNDER or PASSWORD */
CA_UNBAN,
CA_AUTOOP,
CA_AUTOVOICE,
CA_OPDEOP, /* ChanServ commands OP and DEOP */
CA_ACCESS_LIST,
CA_NOJOIN, /* Maximum */
CA_ACCESS_CHANGE,
CA_MEMO,
CA_ASSIGN, /* BotServ ASSIGN command */
CA_BADWORDS, /* BotServ BADWORDS command */
CA_NOKICK, /* Not kicked by the bot */
CA_FANTASIA,
CA_SAY,
CA_GREET,
CA_VOICEME,
CA_VOICE,
CA_GETKEY,
CA_AUTOHALFOP,
CA_AUTOPROTECT,
CA_OPDEOPME,
CA_HALFOPME,
CA_HALFOP,
CA_PROTECTME,
CA_PROTECT,
CA_KICKME,
CA_KICK,
CA_SIGNKICK,
CA_BANME,
CA_BAN,
CA_TOPIC,
CA_MODE,
CA_INFO,
CA_AUTOOWNER,
CA_OWNER,
CA_OWNERME,
CA_FOUNDER,
CA_SIZE
};
/* BotServ SET flags */
enum BotServFlag
{
@@ -633,8 +607,6 @@ enum BotServFlag
BS_DONTKICKVOICES,
/* BotServ bot accepts fantasy commands */
BS_FANTASY,
/* BotServ bot sets modes etc instead of ChanServ */
BS_SYMBIOSIS,
/* BotServ should show greets */
BS_GREET,
/* BotServ bots are not allowed to be in this channel */
@@ -669,7 +641,7 @@ enum BotServFlag
};
const Anope::string BotServFlagStrings[] = {
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "SYMBIOSIS", "GREET", "NOBOT",
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "GREET", "NOBOT",
"KICK_BOLDs", "KICK_COLORS", "KICK_REVERSES", "KICK_UNDERLINES", "KICK_BADWORDS", "KICK_CAPS",
"KICK_FLOOD", "KICK_REPEAT", "KICK_ITALICS", "KICK_AMSGS", "MSG_PRIVMSG", "MSG_NOTICE",
"MSG_NOTICEOPS", ""
@@ -691,6 +663,7 @@ enum
TTB_SIZE
};
#include "access.h"
#include "regchannel.h"
/*************************************************************************/
@@ -701,22 +674,8 @@ enum
#include "users.h"
#include "account.h"
#include "commands.h"
#include "bots.h"
struct BanData
{
Anope::string mask; /* Since a nick is unsure and a User structure is unsafe */
time_t last_use; /* Since time is the only way to check whether it's still useful */
int16 ttb[TTB_SIZE];
};
struct LevelInfo
{
int what;
Anope::string name;
const char *desc;
};
#include "channels.h"
/** Channelban type flags
@@ -763,33 +722,6 @@ class CoreExport Entry : public Flags<EntryType>
/*************************************************************************/
/* News stuff */
enum NewsType
{
NEWS_LOGON,
NEWS_RANDOM,
NEWS_OPER
};
struct NewsMessages
{
NewsType type;
Anope::string name;
const char *msgs[10];
};
struct NewsItem
{
NewsType type;
uint32 num;
Anope::string Text;
Anope::string who;
time_t time;
};
/*************************************************************************/
/* Mail data */
struct MailInfo
@@ -801,43 +733,7 @@ struct MailInfo
/*************************************************************************/
struct Exception
{
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 */
};
/*************************************************************************/
extern CoreExport Anope::map<Session *> SessionList;
struct Session
{
Anope::string host;
unsigned count; /* Number of clients with this host */
unsigned hits; /* Number of subsequent kills for a host */
};
/*************************************************************************/
/* Defcon */
enum DefconLevel
{
DEFCON_NO_NEW_CHANNELS,
DEFCON_NO_NEW_NICKS,
DEFCON_NO_MLOCK_CHANGE,
DEFCON_FORCE_CHAN_MODES,
DEFCON_REDUCE_SESSION,
DEFCON_NO_NEW_CLIENTS,
DEFCON_OPER_ONLY,
DEFCON_SILENT_OPER_ONLY,
DEFCON_AKILL_NEW_CLIENTS,
DEFCON_NO_NEW_MEMOS
};
/*************************************************************************/
@@ -860,10 +756,10 @@ class IRCdMessage;
struct Uplink;
class ServerConfig;
class ConfigurationFile;
class XLine;
#include "extern.h"
#include "language.h"
#include "operserv.h"
#include "mail.h"
#include "servers.h"
#include "logger.h"
@@ -888,7 +784,7 @@ class CoreExport IRCDProto
public:
virtual ~IRCDProto() { }
virtual void SendSVSNOOP(const Anope::string &, int) { }
virtual void SendSVSNOOP(const Server *, bool) { }
virtual void SendTopic(BotInfo *, Channel *) = 0;
virtual void SendVhostDel(User *) { }
virtual void SendAkill(User *, const XLine *) = 0;
@@ -896,7 +792,7 @@ class CoreExport IRCDProto
virtual void SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...);
virtual void SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...);
virtual void SendClientIntroduction(const User *u, const Anope::string &) = 0;
virtual void SendClientIntroduction(const User *u) = 0;
virtual void SendKick(const BotInfo *bi, const Channel *chan, const User *user, const char *fmt, ...);
virtual void SendNoticeChanops(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
@@ -909,7 +805,7 @@ class CoreExport IRCDProto
virtual void SendQuit(const User *u, const char *fmt, ...);
virtual void SendPing(const Anope::string &servname, const Anope::string &who);
virtual void SendPong(const Anope::string &servname, const Anope::string &who);
virtual void SendJoin(BotInfo *, Channel *, const ChannelStatus *) = 0;
virtual void SendJoin(User *, Channel *, const ChannelStatus *) = 0;
virtual void SendSQLineDel(const XLine *x) { }
virtual void SendInvite(const BotInfo *bi, const Anope::string &chan, const Anope::string &nick);
virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...);
@@ -995,6 +891,19 @@ struct Uplink
bool ipv6;
Uplink(const Anope::string &_host, int _port, const Anope::string &_password, bool _ipv6) : host(_host), port(_port), password(_password), ipv6(_ipv6) { }
bool operator==(const Uplink &other) const
{
if (this->host != other.host)
return false;
if (this->port != other.port)
return false;
if (this->password != other.password)
return false;
if (this->ipv6 != other.ipv6)
return false;
return true;
}
inline bool operator!=(const Uplink &other) const { return !(*this == other); }
};
/** A class to process numbered lists (passed to most DEL/LIST/VIEW commands).
+11 -15
View File
@@ -12,47 +12,43 @@
#ifndef SOCKETENGINE_H
#define SOCKETENGINE_H
class CoreExport SocketEngineBase
class CoreExport SocketEngine
{
public:
#ifdef _WIN32
/* Windows crap */
WSADATA wsa;
#endif
/* Map of sockets */
std::map<int, Socket *> Sockets;
static std::map<int, Socket *> Sockets;
/** Default constructor
/** Called to initialize the socket engine
*/
SocketEngineBase();
static void Init();
/** Default destructor
/** Called to shutdown the socket engine
*/
virtual ~SocketEngineBase();
static void Shutdown();
/** Add a socket to the internal list
* @param s The socket
*/
virtual void AddSocket(Socket *s) { }
static void AddSocket(Socket *s);
/** Delete a socket from the internal list
* @param s The socket
*/
virtual void DelSocket(Socket *s) { }
static void DelSocket(Socket *s);
/** Mark a socket as writeable
* @param s The socket
*/
virtual void MarkWritable(Socket *s) { }
static void MarkWritable(Socket *s);
/** Unmark a socket as writeable
* @param s The socket
*/
virtual void ClearWritable(Socket *s) { }
static void ClearWritable(Socket *s);
/** Read from sockets and do things
*/
virtual void Process() { }
static void Process();
};
#endif // SOCKETENGINE_H
+76 -19
View File
@@ -137,27 +137,46 @@ class CoreExport SocketIO
* @param sz How much to read
* @return Number of bytes received
*/
virtual int Recv(Socket *s, char *buf, size_t sz) const;
virtual int Recv(Socket *s, char *buf, size_t sz);
/** Write something to the socket
* @param s The socket
* @param buf What to write
* @return Number of bytes written
*/
virtual int Send(Socket *s, const Anope::string &buf) const;
virtual int Send(Socket *s, const Anope::string &buf);
/** Accept a connection from a socket
* @param s The socket
* @return The new socket
*/
virtual void Accept(ListenSocket *s);
virtual ClientSocket *Accept(ListenSocket *s);
/** Check if a connection has been accepted
* @param s The client socket
* @return -1 on error, 0 to wait, 1 on success
*/
virtual int Accepted(ClientSocket *cs);
/** Bind a socket
* @param s The socket
* @param ip The IP to bind to
* @param port The optional port to bind to
*/
virtual void Bind(Socket *s, const Anope::string &ip, int port = 0);
/** Connect the socket
* @param s THe socket
* @param s The socket
* @param target IP to connect to
* @param port to connect to
* @param bindip IP to bind to, if any
*/
virtual void Connect(ConnectionSocket *s, const Anope::string &target, int port, const Anope::string &bindip = "");
virtual void Connect(ConnectionSocket *s, const Anope::string &target, int port);
/** Check if this socket is connected
* @param s The socket
* @return -1 for error, 0 for wait, 1 for connected
*/
virtual int Connected(ConnectionSocket *s);
/** Called when the socket is destructing
*/
@@ -173,6 +192,9 @@ class CoreExport Socket : public Flags<SocketFlag, 2>
bool IPv6;
public:
/* Sockaddrs for bind() (if it's bound) */
sockaddrs bindaddr;
/* I/O functions used for this socket */
SocketIO *IO;
@@ -214,6 +236,12 @@ class CoreExport Socket : public Flags<SocketFlag, 2>
*/
bool SetNonBlocking();
/** Bind the socket to an ip and port
* @param ip The ip
* @param port The port
*/
void Bind(const Anope::string &ip, int port = 0);
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
@@ -234,11 +262,11 @@ class CoreExport BufferedSocket : public Socket
{
protected:
/* Things to be written to the socket */
std::string WriteBuffer;
Anope::string WriteBuffer;
/* Part of a message sent from the server, but not totally received */
std::string extrabuf;
Anope::string extrabuf;
/* How much data was received from this socket */
size_t RecvLen;
int RecvLen;
public:
/** Blank constructor
@@ -281,20 +309,16 @@ class CoreExport BufferedSocket : public Socket
/** Get the length of the read buffer
* @return The length of the read buffer
*/
size_t ReadBufferLen() const;
int ReadBufferLen() const;
/** Get the length of the write buffer
* @return The length of the write buffer
*/
size_t WriteBufferLen() const;
int WriteBufferLen() const;
};
class CoreExport ListenSocket : public Socket
{
protected:
/* Sockaddrs for bindip/port */
sockaddrs listenaddrs;
public:
/** Constructor
* @param bindip The IP to bind to
@@ -323,10 +347,10 @@ class CoreExport ListenSocket : public Socket
class CoreExport ConnectionSocket : public BufferedSocket
{
public:
/* Sockaddrs for bindip (if there is one) */
sockaddrs bindaddr;
/* Sockaddrs for connection ip/port */
sockaddrs conaddr;
/* True if connected */
bool connected;
/** Constructor
* @param ipv6 true to use IPv6
@@ -337,9 +361,32 @@ class CoreExport ConnectionSocket : public BufferedSocket
/** Connect the socket
* @param TargetHost The target host to connect to
* @param Port The target port to connect to
* @param BindHost The host to bind to for connecting
*/
void Connect(const Anope::string &TargetHost, int Port, const Anope::string &BindHost = "");
void Connect(const Anope::string &TargetHost, int Port);
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
bool ProcessRead();
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
bool ProcessWrite();
/** Called when there is an error for this socket
* @return true on success, false to drop this socket
*/
void ProcessError();
/** Called on a successful connect
*/
virtual void OnConnect();
/** Called when a connection is not successful
* @param error The error
*/
virtual void OnError(const Anope::string &error);
};
class CoreExport ClientSocket : public BufferedSocket
@@ -356,6 +403,16 @@ class CoreExport ClientSocket : public BufferedSocket
* @param addr Address the connection came from
*/
ClientSocket(ListenSocket *ls, int fd, const sockaddrs &addr);
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
bool ProcessRead();
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
bool ProcessWrite();
};
class CoreExport Pipe : public BufferedSocket
+2 -3
View File
@@ -7,15 +7,14 @@
#cmakedefine HAVE_SYS_TYPES_H 1
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STDDEF_H 1
#cmakedefine HAVE_BACKTRACE 1
#cmakedefine HAVE_SETGRENT 1
#cmakedefine HAVE_STRCASECMP 1
#cmakedefine HAVE_STRICMP 1
#cmakedefine HAVE_STRINGS_H 1
#cmakedefine HAVE_STRLCAT 1
#cmakedefine HAVE_STRLCPY 1
#cmakedefine HAVE_UMASK 1
#cmakedefine HAVE_EVENTFD 1
#cmakedefine HAVE_EPOLL 1
#cmakedefine HAVE_POLL 1
#cmakedefine GETTEXT_FOUND 1
#cmakedefine RUNGROUP "@RUNGROUP@"
+5 -1
View File
@@ -63,6 +63,11 @@ class CoreExport Timer : public Extensible
*/
bool GetRepeat() const;
/** Set the interval between ticks
* @paramt t The new interval
*/
void SetSecs(time_t t);
/** Returns the interval between ticks
* @return The interval
*/
@@ -85,7 +90,6 @@ class CoreExport Timer : public Extensible
*/
class CoreExport TimerManager : public Extensible
{
protected:
/** A list of timers
*/
static std::vector<Timer *> Timers;
+14 -4
View File
@@ -54,8 +54,7 @@ class CoreExport User : public Extensible
Server *server; /* Server user is connected to */
time_t timestamp; /* Timestamp of the nick */
time_t my_signon; /* When did _we_ see the user? */
int isSuperAdmin; /* is SuperAdmin on or off? */
bool SuperAdmin; /* is SuperAdmin on or off? */
/* Channels the user is in */
UChannelList chans;
@@ -77,7 +76,7 @@ class CoreExport User : public Extensible
* @param shost The hostname of the user
* @param suid The unique identifier of the user.
*/
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid);
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid = "");
/** Destroy a user.
*/
@@ -195,7 +194,7 @@ class CoreExport User : public Extensible
* @param CheckSecure Only returns true if the user has secure off
* @return true or false
*/
virtual bool IsRecognized(bool CheckSecure = false);
virtual bool IsRecognized(bool CheckSecure = true);
/** Check if the user is a services oper
* @return true if they are an oper
@@ -272,6 +271,11 @@ class CoreExport User : public Extensible
*/
void SetModesInternal(const char *umodes, ...);
/** Get modes set for this user.
* @return A string of modes set on the user
*/
Anope::string GetModes() const;
/** Find the channel container for Channel c that the user is on
* This is preferred over using FindUser in Channel, as there are usually more users in a channel
* than channels a user is in
@@ -284,6 +288,12 @@ class CoreExport User : public Extensible
* @return true or false
*/
bool IsProtected() const;
/** Kill a user
* @param source The user/server doing the kill
* @param reason The reason for the kill
*/
void Kill(const Anope::string &source, const Anope::string &reason);
};
#endif // USERS_H
+8339 -8179
View File
File diff suppressed because it is too large Load Diff
+8516 -8268
View File
File diff suppressed because it is too large Load Diff
+13864 -9707
View File
File diff suppressed because it is too large Load Diff
+8167 -8030
View File
File diff suppressed because it is too large Load Diff
+9107 -8803
View File
File diff suppressed because it is too large Load Diff
+8990 -8581
View File
File diff suppressed because it is too large Load Diff
+8338 -8131
View File
File diff suppressed because it is too large Load Diff
+8119 -7970
View File
File diff suppressed because it is too large Load Diff
+8827 -8527
View File
File diff suppressed because it is too large Load Diff
-8641
View File
File diff suppressed because it is too large Load Diff
+8602 -8344
View File
File diff suppressed because it is too large Load Diff
+14235 -8956
View File
File diff suppressed because it is too large Load Diff
+8619 -8215
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,20 +1,20 @@
#!/bin/bash
rm anope.pot
rm -f anope.pot
touch anope.pot
cd ..
FILES=`find ./ -name *.cpp -o -name *.h | grep -v /modules/extra/`
FILES=`find ./ -name *.cpp -o -name *.h | grep -v /modules/third/`
for f in $FILES
do
xgettext -C -s -d Anope -j -o language/anope.pot --from-code=utf-8 --keyword=_ $f
xgettext -E -C -s -d Anope -j -o language/anope.pot --from-code=utf-8 --keyword --keyword=_ $f
done
cd -
for f in *.po
do
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
msgmerge -E -v -s -U $f `echo $f | cut -d'.' -f1`.pot
done
rm -f *~
+10 -4
View File
@@ -1,4 +1,4 @@
add_subdirectory("extra/language")
add_subdirectory("third/language")
# Get a list of ALL files and directories within the current directory
file(GLOB MODULES_FOLDERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
@@ -77,7 +77,10 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
set(WIN32_NO_LIBS)
endif(WIN32)
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}")
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
add_dependencies(${SO} ${PROGRAM_NAME})
if(GETTEXT_FOUND)
add_dependencies(${SO} module_language)
endif(GETTEXT_FOUND)
# 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} ${TEMP_DEPENDENCIES})
@@ -96,7 +99,7 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
# Get a list of ALL files and directories within this modules directory
file(GLOB SUBMODULE_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${MODULE_FOLDER}/*")
remove_item_from_list(SUBMODULE_DIRS "CMakeFiles")
remove_item_from_list(SUBMODULE_DIRS "extra/language")
remove_item_from_list(SUBMODULE_DIRS "third/language")
foreach(SUBDIR ${SUBMODULE_DIRS})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
@@ -174,7 +177,10 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
# Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand
add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS})
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}")
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
add_dependencies(${SO} ${PROGRAM_NAME})
if(GETTEXT_FOUND)
add_dependencies(${SO} module_language)
endif(GETTEXT_FOUND)
# 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} ${SUBDIR_EXTRA_DEPENDS})
+168
View File
@@ -0,0 +1,168 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
const Anope::string &chan = params[0];
const Anope::string &nick = params[1];
User *u = source.u;
if (readonly)
{
source.Reply(BOT_ASSIGN_READONLY);
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
BotInfo *bi = findbot(nick);
if (!bi)
{
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
if (ci->botflags.HasFlag(BS_NOBOT) || (!ci->AccessFor(u).HasPriv(CA_ASSIGN) && !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
}
if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private"))
{
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 = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick;
bi->Assign(u, 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)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Assigns a bot pointed out by nick to the channel chan. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."));
return true;
}
};
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)
{
User *u = source.u;
if (readonly)
{
source.Reply(BOT_ASSIGN_READONLY);
return;
}
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_ASSIGN))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (ci->HasFlag(CI_PERSIST) && !ModeManager::FindChannelModeByName(CMODE_PERM))
{
source.Reply(_("You can not unassign bots while persist is set on the channel."));
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick;
ci->bi->UnAssign(u, ci);
source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Unassigns a bot from a channel. When you use this command,\n"
"the bot won't join the channel anymore. However, bot\n"
"configuration for the channel is kept, so you will always\n"
"be able to reassign a bot later without have to reconfigure\n"
"it entirely."));
return true;
}
};
class BSAssign : public Module
{
CommandBSAssign commandbsassign;
CommandBSUnassign commandbsunassign;
public:
BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsassign(this), commandbsunassign(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsassign);
ModuleManager::RegisterService(&commandbsunassign);
}
};
MODULE_INIT(BSAssign)
@@ -16,31 +16,32 @@
class BadwordsListCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
BadwordsListCallback(CommandSource &_source, const Anope::string &list) : NumberList(list, false), source(_source), SentHeader(false)
BadwordsListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), source(_source), ci(_ci), SentHeader(false)
{
}
~BadwordsListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetBadWordCount())
if (!Number || Number > ci->GetBadWordCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), source.ci->name.c_str());
" Num Word Type"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetBadWord(Number - 1));
DoList(source, Number - 1, ci->GetBadWord(Number - 1));
}
static void DoList(CommandSource &source, unsigned Number, BadWord *bw)
@@ -52,51 +53,51 @@ class BadwordsListCallback : public NumberList
class BadwordsDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
bool override;
public:
BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false)
BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0), override(false)
{
if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
if (!ci->AccessFor(source.u).HasPriv(CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
this->override = true;
}
~BadwordsDelCallback()
{
if (!Deleted)
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
else if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s bad words list."), source.ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s bad words list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, source.ci->name.c_str());
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetBadWordCount())
if (!Number || Number > ci->GetBadWordCount())
return;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "DEL " << source.ci->GetBadWord(Number - 1)->word;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "DEL " << ci->GetBadWord(Number - 1)->word;
++Deleted;
source.ci->EraseBadWord(Number - 1);
ci->EraseBadWord(Number - 1);
}
};
class CommandBSBadwords : public Command
{
private:
CommandReturn DoList(CommandSource &source, const Anope::string &word)
void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
bool override = !check_access(source.u, ci, CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
if (!ci->GetBadWordCount())
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
{
BadwordsListCallback list(source, word);
BadwordsListCallback list(source, ci, word);
list.Process();
}
else
@@ -125,12 +126,11 @@ class CommandBSBadwords : public Command
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
return MOD_CONT;
return;
}
CommandReturn DoAdd(CommandSource &source, const Anope::string &word)
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
size_t pos = word.rfind(' ');
BadWordType type = BW_ANY;
Anope::string realword = word;
@@ -153,7 +153,7 @@ class CommandBSBadwords : public Command
if (ci->GetBadWordCount() >= Config->BSBadWordsMax)
{
source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax);
return MOD_CONT;
return;
}
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
@@ -163,26 +163,25 @@ class CommandBSBadwords : public Command
if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word))))
{
source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
}
bool override = !check_access(source.u, ci, CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "ADD " << realword;
ci->AddBadWord(realword, type);
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
CommandReturn DoDelete(CommandSource &source, const Anope::string &word)
void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
/* Special case: is it a number/list? Only do search if it isn't. */
if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos)
{
BadwordsDelCallback list(source, this, word);
BadwordsDelCallback list(source, ci, this, word);
list.Process();
}
else
@@ -201,10 +200,10 @@ class CommandBSBadwords : public Command
if (i == end)
{
source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str());
return MOD_CONT;
return;
}
bool override = !check_access(source.u, ci, CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "DEL " << badword->word;
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
@@ -212,78 +211,83 @@ class CommandBSBadwords : public Command
ci->EraseBadWord(i);
}
return MOD_CONT;
return;
}
CommandReturn DoClear(CommandSource &source)
void DoClear(CommandSource &source, ChannelInfo *ci)
{
ChannelInfo *ci = source.ci;
bool override = !check_access(source.u, ci, CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR";
ci->ClearBadWords();
source.Reply(_("Bad words list is now empty."));
return MOD_CONT;
return;
}
public:
CommandBSBadwords() : Command("BADWORDS", 2, 3)
CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3)
{
this->SetDesc(_("Maintains bad words list"));
this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[1];
const Anope::string &word = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR");
if (!need_args && word.empty())
{
this->OnSyntaxError(source, cmd);
return MOD_CONT;
return;
}
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
}
if (readonly)
{
source.Reply(_("Sorry, channel bad words list modification is temporarily disabled."));
return MOD_CONT;
return;
}
if (cmd.equals_ci("ADD"))
return this->DoAdd(source, word);
return this->DoAdd(source, ci, word);
else if (cmd.equals_ci("DEL"))
return this->DoDelete(source, word);
return this->DoDelete(source, ci, word);
else if (cmd.equals_ci("LIST"))
return this->DoList(source, word);
return this->DoList(source, ci, word);
else if (cmd.equals_ci("CLEAR"))
return this->DoClear(source);
return this->DoClear(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BADWORDS \037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]\002\n"
" \002BADWORDS \037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}\002\n"
" \002BADWORDS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002BADWORDS \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002bad words list\002 for a channel. The bad\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002bad words list\002 for a channel. The bad\n"
"words list determines which words are to be kicked\n"
"when the bad words kicker is enabled. For more information,\n"
"type \002%s%s HELP KICK BADWORDS\002.\n"
"type \002%s%s HELP KICK %s\002.\n"
" \n"
"The \002BADWORDS ADD\002 command adds the given word to the\n"
"The \002ADD\002 command adds the given word to the\n"
"badword list. If SINGLE is specified, a kick will be\n"
"done only if a user says the entire word. If START is \n"
"specified, a kick will be done if a user says a word\n"
@@ -291,28 +295,23 @@ class CommandBSBadwords : public Command
"will be done if a user says a word that ends with\n"
"\037word\037. If you don't specify anything, a kick will\n"
"be issued every time \037word\037 is said by a user.\n"
" \n"), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
source.Reply(_("The \002BADWORDS DEL\002 command removes the given word from the\n"
" \n"), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), source.command.c_str());
source.Reply(_("The \002DEL\002 command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
" \n"
"The \002BADWORDS LIST\002 command displays the bad words list. If\n"
"The \002LIST\002 command displays the bad words list. If\n"
"a wildcard mask is given, only those entries matching the\n"
"mask are displayed. If a list of entry numbers is given,\n"
"only those entries are shown; for example:\n"
" \002BADWORDS #channel LIST 2-5,7-9\002\n"
" \002#channel LIST 2-5,7-9\002\n"
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
"The \002BADWORDS CLEAR\002 command clears all entries of the\n"
"The \002CLEAR\002 command clears all entries of the\n"
"bad words list."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "BADWORDS", _("BADWORDS \037channel\037 {ADD|DEL|LIST|CLEAR} [\037word\037 | \037entry-list\037] [SINGLE|START|END]"));
}
};
class BSBadwords : public Module
@@ -320,12 +319,12 @@ class BSBadwords : public Module
CommandBSBadwords commandbsbadwords;
public:
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbadwords(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbsbadwords);
ModuleManager::RegisterService(&commandbsbadwords);
}
};
@@ -16,7 +16,7 @@
class CommandBSBot : public Command
{
private:
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[1];
const Anope::string &user = params[2];
@@ -27,60 +27,60 @@ class CommandBSBot : public Command
if (findbot(nick))
{
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
return;
}
if (nick.length() > Config->NickLen)
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (user.length() > Config->UserLen)
{
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (host.length() > Config->HostLen)
{
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
return;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* Check the host is valid re RFC 2812 */
if (!isValidHost(host, 3))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
if (!isalnum(user[i]))
{
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
return;
}
/* We check whether the nick is registered, and inform the user
@@ -89,26 +89,21 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
return;
}
if (!(bi = new BotInfo(nick, user, host, real)))
{
// XXX this cant happen?
source.Reply(_("Sorry, bot creation failed."));
return MOD_CONT;
}
bi = new BotInfo(nick, user, host, real);
Log(LOG_ADMIN, source.u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
source.Reply(_("%s!%s@%s (%s) added to the bot list."), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi));
return MOD_CONT;
return;
}
CommandReturn DoChange(CommandSource &source, const std::vector<Anope::string> &params)
void DoChange(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &oldnick = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
@@ -120,43 +115,43 @@ class CommandBSBot : public Command
if (oldnick.empty() || nick.empty())
{
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
return;
}
if (!(bi = findbot(oldnick)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
if (!oldnick.equals_ci(nick) && nickIsServices(oldnick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
if (nick.length() > Config->NickLen)
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (!user.empty() && user.length() > Config->UserLen)
{
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (!host.empty() && host.length() > Config->HostLen)
{
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
return;
}
if (!oldnick.equals_ci(nick) && nickIsServices(nick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
return;
}
/* Checks whether there *are* changes.
@@ -167,34 +162,34 @@ class CommandBSBot : public Command
if (nick.equals_cs(bi->nick) && (!user.empty() ? user.equals_cs(bi->GetIdent()) : 1) && (!host.empty() ? host.equals_cs(bi->host) : 1) && (!real.empty() ? real.equals_cs(bi->realname) : 1))
{
source.Reply(_("Old info is equal to the new one."));
return MOD_CONT;
return;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
return;
}
if (!host.empty() && !isValidHost(host, 3))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
return;
}
if (!user.empty())
@@ -202,13 +197,13 @@ class CommandBSBot : public Command
if (!isalnum(user[i]))
{
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
return;
}
if (!nick.equals_ci(bi->nick) && findbot(nick))
{
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
return;
}
if (!nick.equals_ci(bi->nick))
@@ -219,20 +214,20 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
return;
}
/* The new nick is really different, so we remove the Q line for
the old nick. */
/* The new nick is really different, so we remove the Q line for the old nick. */
if (ircd->sqline)
{
XLine x(bi->nick);
ircdproto->SendSQLineDel(&x);
}
/* We check whether user with this nick is online, and kill it if so */
EnforceQlinedNick(nick, Config->s_BotServ);
/* Add a Q line for the new nick */
XLine x(nick, "Reserved for services");
ircdproto->SendSQLine(NULL, &x);
}
if (!user.empty())
@@ -240,8 +235,6 @@ class CommandBSBot : public Command
else
{
ircdproto->SendChangeBotNick(bi, nick);
XLine x(bi->nick, "Reserved for services");
ircdproto->SendSQLine(NULL, &x);
}
if (!nick.equals_cs(bi->nick))
@@ -256,9 +249,7 @@ class CommandBSBot : public Command
if (!user.empty())
{
ircdproto->SendClientIntroduction(bi, ircd->pseudoclient_mode);
XLine x(bi->nick, "Reserved for services");
ircdproto->SendSQLine(NULL, &x);
ircdproto->SendClientIntroduction(bi);
bi->RejoinAll();
}
@@ -266,10 +257,10 @@ class CommandBSBot : public Command
Log(LOG_ADMIN, source.u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
FOREACH_MOD(I_OnBotChange, OnBotChange(bi));
return MOD_CONT;
return;
}
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[1];
BotInfo *bi;
@@ -277,19 +268,19 @@ class CommandBSBot : public Command
if (nick.empty())
{
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
return;
}
if (!(bi = findbot(nick)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
if (nickIsServices(nick, false))
{
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
return;
}
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
@@ -298,16 +289,18 @@ class CommandBSBot : public Command
source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str());
delete bi;
return MOD_CONT;
return;
}
public:
CommandBSBot() : Command("BOT", 1, 6)
CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Maintains network bot list"));
this->SetSyntax(_("\002ADD \037nick\037 \037user\037 \037host\037 \037real\037\002"));
this->SetSyntax(_("\002CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002"));
this->SetSyntax(_("\002DEL \037nick\037\002"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[0];
User *u = source.u;
@@ -315,7 +308,7 @@ class CommandBSBot : public Command
if (readonly)
{
source.Reply(_("Sorry, bot modification is temporarily disabled."));
return MOD_CONT;
return;
}
if (cmd.equals_ci("ADD"))
@@ -323,14 +316,14 @@ class CommandBSBot : public Command
// ADD nick user host real - 5
if (!u->HasCommand("botserv/bot/add"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 5)
{
this->OnSyntaxError(source, "ADD");
return MOD_CONT;
return;
}
std::vector<Anope::string> tempparams = params;
@@ -346,14 +339,14 @@ class CommandBSBot : public Command
// but only oldn and newn are required
if (!u->HasCommand("botserv/bot/change"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 3)
{
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
return;
}
return this->DoChange(source, params);
@@ -363,14 +356,14 @@ class CommandBSBot : public Command
// DEL nick
if (!u->HasCommand("botserv/bot/del"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() < 1)
{
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
return;
}
return this->DoDel(source, params);
@@ -378,16 +371,14 @@ class CommandBSBot : public Command
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\002\n"
" \002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
" \002BOT DEL \037nick\037\002\n"
" \n"
"Allows Services Operators to create, modify, and delete\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
"channels.\n"
" \n"
@@ -404,13 +395,6 @@ class CommandBSBot : public Command
"using the nick, they will be killed."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "BOT", _("BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\n"
"\002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
"\002BOT DEL \037nick\037\002"));
}
};
class BSBot : public Module
@@ -418,12 +402,12 @@ class BSBot : public Module
CommandBSBot commandbsbot;
public:
BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbot(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbsbot);
ModuleManager::RegisterService(&commandbsbot);
}
};
@@ -16,12 +16,13 @@
class CommandBSBotList : public Command
{
public:
CommandBSBotList() : Command("BOTLIST", 0, 0)
CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
{
this->SetDesc(_("Lists available bots"));
this->SetSyntax("");
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
unsigned count = 0;
@@ -61,14 +62,14 @@ class CommandBSBotList : public Command
else
source.Reply(_("%d bots available."), count);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BOTLIST\002\n"
" \n"
"Lists all available bots on this network."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists all available bots on this network."));
return true;
}
};
@@ -78,12 +79,12 @@ class BSBotList : public Module
CommandBSBotList commandbsbotlist;
public:
BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsbotlist(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbsbotlist);
ModuleManager::RegisterService(&commandbsbotlist);
}
};
+158
View File
@@ -0,0 +1,158 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandBSSay : public Command
{
public:
CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2)
{
this->SetDesc(_("Makes the bot say the given text on the given channel"));
this->SetSyntax(_("\037channel\037 \037text\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &text = params[1];
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SAY))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
return;
}
if (text[0] == '\001')
{
this->OnSyntaxError(source, "");
return;
}
ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", text.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX need a way to find if someone is overriding this
Log(LOG_COMMAND, u, this, ci) << text;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Makes the bot say the given text on the given channel."));
return true;
}
};
class CommandBSAct : public Command
{
public:
CommandBSAct(Module *creator) : Command(creator, "botserv/act", 2, 2)
{
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
this->SetSyntax(_("\037channel\037 \037text\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string message = params[1];
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SAY))
{
source.Reply(ACCESS_DENIED);
return;
}
if (!ci->bi)
{
source.Reply(BOT_NOT_ASSIGNED);
return;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
return;
}
size_t i = 0;
while ((i = message.find(1)) && i != Anope::string::npos)
message.erase(i, 1);
ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str());
ci->bi->lastmsg = Anope::CurTime;
// XXX Need to be able to find if someone is overriding this.
Log(LOG_COMMAND, u, this, ci) << message;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n"
"on the given channel using the given text."));
return true;
}
};
class BSControl : public Module
{
CommandBSSay commandbssay;
CommandBSAct commandbsact;
public:
BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbssay(this), commandbsact(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbssay);
ModuleManager::RegisterService(&commandbsact);
}
};
MODULE_INIT(BSControl)
@@ -40,13 +40,13 @@ class CommandBSInfo : public Command
return;
}
public:
CommandBSInfo() : Command("INFO", 1, 1)
CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Allows you to see BotServ information about a channel or a bot"));
this->SetSyntax(_("\002INFO {\037chan\037 | \037nick\037}\002"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &query = params[0];
@@ -70,13 +70,13 @@ class CommandBSInfo : public Command
}
else if ((ci = cs_findchan(query)))
{
if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration"))
if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("botserv/administration"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
source.Reply(_(CHAN_INFO_HEADER), ci->name.c_str());
source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
if (ci->bi)
source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str());
else
@@ -85,93 +85,93 @@ class CommandBSInfo : public Command
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
if (ci->ttb[TTB_BADWORDS])
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BADWORDS]);
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BADWORDS]);
else
source.Reply(_(" Bad words kicker : %s"), _(ENABLED));
source.Reply(_(" Bad words kicker : %s"), ENABLED);
}
else
source.Reply(_(" Bad words kicker : %s"), _(DISABLED));
source.Reply(_(" Bad words kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_BOLDS))
{
if (ci->ttb[TTB_BOLDS])
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BOLDS]);
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BOLDS]);
else
source.Reply(_(" Bolds kicker : %s"), _(ENABLED));
source.Reply(_(" Bolds kicker : %s"), ENABLED);
}
else
source.Reply(_(" Bolds kicker : %s"), _(DISABLED));
source.Reply(_(" Bolds kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_CAPS))
{
if (ci->ttb[TTB_CAPS])
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), _(ENABLED), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), ENABLED, ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
else
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), _(ENABLED), ci->capsmin, ci->capspercent);
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), ENABLED, ci->capsmin, ci->capspercent);
}
else
source.Reply(_(" Caps kicker : %s"), _(DISABLED));
source.Reply(_(" Caps kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_COLORS))
{
if (ci->ttb[TTB_COLORS])
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_COLORS]);
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_COLORS]);
else
source.Reply(_(" Colors kicker : %s"), _(ENABLED));
source.Reply(_(" Colors kicker : %s"), ENABLED);
}
else
source.Reply(_(" Colors kicker : %s"), _(DISABLED));
source.Reply(_(" Colors kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
if (ci->ttb[TTB_FLOOD])
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), _(ENABLED), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), ENABLED, ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
else
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), _(ENABLED), ci->floodlines, ci->floodsecs);
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), ENABLED, ci->floodlines, ci->floodsecs);
}
else
source.Reply(_(" Flood kicker : %s"), _(DISABLED));
source.Reply(_(" Flood kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (ci->ttb[TTB_REPEAT])
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), _(ENABLED), ci->ttb[TTB_REPEAT], ci->repeattimes);
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), ENABLED, ci->ttb[TTB_REPEAT], ci->repeattimes);
else
source.Reply(_(" Repeat kicker : %s (%d times)"), _(ENABLED), ci->repeattimes);
source.Reply(_(" Repeat kicker : %s (%d times)"), ENABLED, ci->repeattimes);
}
else
source.Reply(_(" Repeat kicker : %s"), _(DISABLED));
source.Reply(_(" Repeat kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_REVERSES))
{
if (ci->ttb[TTB_REVERSES])
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_REVERSES]);
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_REVERSES]);
else
source.Reply(_(" Reverses kicker : %s"), _(ENABLED));
source.Reply(_(" Reverses kicker : %s"), ENABLED);
}
else
source.Reply(_(" Reverses kicker : %s"), _(DISABLED));
source.Reply(_(" Reverses kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES))
{
if (ci->ttb[TTB_UNDERLINES])
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_UNDERLINES]);
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_UNDERLINES]);
else
source.Reply(_(" Underlines kicker : %s"), _(ENABLED));
source.Reply(_(" Underlines kicker : %s"), ENABLED);
}
else
source.Reply(_(" Underlines kicker : %s"), _(DISABLED));
source.Reply(_(" Underlines kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_ITALICS))
{
if (ci->ttb[TTB_ITALICS])
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_ITALICS]);
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_ITALICS]);
else
source.Reply(_(" Italics kicker : %s"), _(ENABLED));
source.Reply(_(" Italics kicker : %s"), ENABLED);
}
else
source.Reply(_(" Italics kicker : %s"), _(DISABLED));
source.Reply(_(" Italics kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_KICK_AMSGS))
{
if (ci->ttb[TTB_AMSGS])
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_AMSGS]);
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_AMSGS]);
else
source.Reply(_(" AMSG kicker : %s"), _(ENABLED));
source.Reply(_(" AMSG kicker : %s"), ENABLED);
}
else
source.Reply(_(" AMSG kicker : %s"), _(DISABLED));
source.Reply(_(" AMSG kicker : %s"), DISABLED);
if (ci->botflags.HasFlag(BS_MSG_PRIVMSG))
source.Reply(_(" Fantasy reply : %s"), "PRIVMSG");
@@ -207,34 +207,24 @@ class CommandBSInfo : public Command
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("No bot"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_SYMBIOSIS))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Symbiosis"));
need_comma = true;
}
source.Reply(_(" Options : %s"), *buf ? buf : _("None"));
}
else
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INFO {\037chan\037 | \037nick\037}\002\n"
" \n"
"Allows you to see %s information about a channel or a bot.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows you to see %s information about a channel or a bot.\n"
"If the parameter is a channel, then you'll get information\n"
"such as enabled kickers. If the parameter is a nick,\n"
"you'll get information about a bot, such as creation\n"
"time or number of channels it is on."), NickServ->nick.c_str());
"time or number of channels it is on."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INFO", _("INFO {\037chan\037 | \037nick\037}"));
}
};
class BSInfo : public Module
@@ -242,12 +232,12 @@ class BSInfo : public Module
CommandBSInfo commandbsinfo;
public:
BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsinfo(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbsinfo);
ModuleManager::RegisterService(&commandbsinfo);
}
};
@@ -17,12 +17,13 @@
class CommandBSKick : public Command
{
public:
CommandBSKick() : Command("KICK", 3, 6)
CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 3, 6)
{
this->SetDesc(_("Configures kickers"));
this->SetSyntax(_("\037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
@@ -30,21 +31,23 @@ class CommandBSKick : public Command
const Anope::string &ttb = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (readonly)
source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
else if (ci == NULL)
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
else if (chan.empty() || option.empty() || value.empty())
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
this->OnSyntaxError(source, "");
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
source.Reply(_(ACCESS_DENIED));
this->OnSyntaxError(source, "");
else if (!ci->AccessFor(u).HasPriv(CA_SET) && !u->HasPriv("botserv/administration"))
source.Reply(ACCESS_DENIED);
else if (!ci->bi)
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
source.Reply(BOT_NOT_ASSIGNED);
else
{
bool override = !check_access(u, ci, CA_SET);
bool override = !ci->AccessFor(u).HasPriv(CA_SET);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("BADWORDS"))
@@ -64,7 +67,7 @@ class CommandBSKick : public Command
/* reset the value back to 0 - TSL */
ci->ttb[TTB_BADWORDS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -101,7 +104,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_BOLDS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -137,7 +140,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_CAPS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -192,7 +195,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_COLORS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -229,7 +232,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_FLOOD] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -285,7 +288,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_REPEAT] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -331,7 +334,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_REVERSES] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -364,7 +367,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_UNDERLINES] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -398,7 +401,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_ITALICS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -432,7 +435,7 @@ class CommandBSKick : public Command
{
ci->ttb[TTB_AMSGS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
return;
}
}
else
@@ -451,17 +454,18 @@ class CommandBSKick : public Command
}
}
else
source.Reply(_(UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
source.Reply(UNKNOWN_OPTION, Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
source.Reply(_("Syntax: \002KICK \037channel\037 \037option\037 \037parameters\037\002\n"
" \n"
"Configures bot kickers. \037option\037 can be one of:\n"
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Configures bot kickers. \037option\037 can be one of:\n"
" \n"
" AMSGS Sets if the bot kicks for amsgs\n"
" BOLDS Sets if the bot kicks bolds\n"
@@ -479,9 +483,10 @@ class CommandBSKick : public Command
"on a specific option.\n"
" \n"
"Note: access to this command is controlled by the\n"
"level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
"level SET."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
else if (subcommand.equals_ci("BADWORDS"))
source.Reply(_("Syntax: \002KICK \037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bad words kicker on or off. When enabled, this\n"
"option tells the bot to kick users who say certain words\n"
"on the channels.\n"
@@ -490,16 +495,16 @@ class CommandBSKick : public Command
"more information.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
"the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
else if (subcommand.equals_ci("BOLDS"))
source.Reply(_("Syntax: \002KICK \037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bolds kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use bolds.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("CAPS"))
source.Reply(_("Syntax: \002KICK \037channel\037 CAPS {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002\n"
source.Reply(_("Syntax: \002\037channel\037 CAPS {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002\n"
"Sets the caps kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are talking in\n"
"CAPS.\n"
@@ -511,14 +516,14 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("COLORS"))
source.Reply(_("Syntax: \002KICK \037channel\037 COLORS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 COLORS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the colors kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use colors.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("FLOOD"))
source.Reply(_("Syntax: \002KICK \037channel\037 FLOOD {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002\n"
source.Reply(_("Syntax: \002\037channel\037 FLOOD {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002\n"
"Sets the flood kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are flooding\n"
"the channel using at least \002ln\002 lines in \002secs\002 seconds\n"
@@ -528,7 +533,7 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REPEAT"))
source.Reply(_("Syntax: \002KICK \037#channel\037 REPEAT {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002\n"
source.Reply(_("Syntax: \002\037#channel\037 REPEAT {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002\n"
"Sets the repeat kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are repeating\n"
"themselves \002num\002 times (if num is not given, it\n"
@@ -537,28 +542,28 @@ class CommandBSKick : public Command
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REVERSES"))
source.Reply(_("Syntax: \002KICK \037channel\037 REVERSES {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 REVERSES {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the reverses kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use reverses.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("UNDERLINES"))
source.Reply(_("Syntax: \002KICK \037channel\037 UNDERLINES {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 UNDERLINES {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the underlines kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use underlines.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("ITALICS"))
source.Reply(_("Syntax: \002KICK \037channel\037 ITALICS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 ITALICS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the italics kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use italics.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("AMSGS"))
source.Reply(_("Syntax: \002KICK \037channel\037 AMSGS {\037ON|OFF\037} [\037ttb\037]\002\n"
source.Reply(_("Syntax: \002\037channel\037 AMSGS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the amsg kicker on or off. When enabled, the bot will\n"
"kick users who send the same message to multiple channels\n"
"where BotServ bots are.\n"
@@ -570,58 +575,436 @@ class CommandBSKick : public Command
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
struct BanData
{
Anope::string mask;
time_t last_use;
int16 ttb[TTB_SIZE];
BanData()
{
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
this->Clear();
}
void Clear()
{
last_use = 0;
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
}
};
struct UserData
{
UserData()
{
this->Clear();
}
void Clear()
{
last_use = last_start = Anope::CurTime;
lines = times = 0;
lastline.clear();
}
/* Data validity */
time_t last_use;
/* for flood kicker */
int16 lines;
time_t last_start;
/* for repeat kicker */
Anope::string lastline;
Anope::string lasttarget;
int16 times;
};
class BanDataPurger : public CallBack
{
public:
BanDataPurger(Module *owner) : CallBack(owner, 300, Anope::CurTime, true) { }
void Tick(time_t)
{
Log(LOG_DEBUG) << "bs_main: Running bandata purger";
for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
std::map<Anope::string, BanData> bandata;
if (c->GetExtRegular("bs_main_bandata", bandata))
{
for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end;)
{
const Anope::string &user = it2->first;
BanData *bd = &it2->second;
++it2;
if (Anope::CurTime - bd->last_use > Config->BSKeepData)
{
bandata.erase(user);
continue;
}
}
if (bandata.empty())
c->Shrink("bs_main_bandata");
}
}
}
};
class BSKick : public Module
{
CommandBSKick commandbskick;
BanDataPurger purger;
BanData *GetBanData(User *u, Channel *c)
{
std::map<Anope::string, BanData> bandatamap;
if (!c->GetExtRegular("bs_main_bandata", bandatamap));
c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
c->GetExtRegular("bs_main_bandata", bandatamap);
BanData *bd = &bandatamap[u->GetMask()];
if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
bd->Clear();
bd->last_use = Anope::CurTime;
return bd;
}
UserData *GetUserData(User *u, Channel *c)
{
UserData *ud = NULL;
UserContainer *uc = c->FindUser(u);
if (uc != NULL && !uc->GetExtPointer("bs_main_userdata", ud))
{
ud = new UserData();
uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
}
return ud;
}
void check_ban(ChannelInfo *ci, User *u, int ttbtype)
{
/* Don't ban ulines */
if (u->server->IsULined())
return;
BanData *bd = this->GetBanData(u, ci->c);
++bd->ttb[ttbtype];
if (ci->ttb[ttbtype] && bd->ttb[ttbtype] >= ci->ttb[ttbtype])
{
/* Should not use == here because bd->ttb[ttbtype] could possibly be > ci->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 */
Anope::string mask;
bd->ttb[ttbtype] = 0;
get_idealban(ci, u, mask);
if (ci->c)
ci->c->SetMode(NULL, CMODE_BAN, mask);
FOREACH_MOD(I_OnBotBan, 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->server->IsULined())
return;
Anope::string fmt = 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)
BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbskick(this), purger(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbskick);
ModuleManager::RegisterService(&commandbskick);
ModuleManager::Attach(I_OnPrivmsg, this);
}
EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow)
~BSKick()
{
Anope::string m, ch;
time_t time;
if (u->GetExtRegular("bs_kick_lastmsg", m) && u->GetExtRegular("bs_kick_lasttime", time) && u->GetExtRegular("bs_kick_lastchan", ch))
for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
{
if (time == Anope::CurTime && m == msg && ch != ci->name)
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *c = (*it)->chan;
++it;
cit->second->Shrink("bs_main_userdata");
cit->second->Shrink("bs_main_bandata");
}
}
if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS))
void OnPrivmsg(User *u, Channel *c, Anope::string &msg)
{
/* Now we can make kicker stuff. We try to order the checks
* from the fastest one to the slowest one, since there's
* 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;
bool Allow = true;
if (ci->AccessFor(u).HasPriv(CA_NOKICK))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (c->HasUserStatus(u, CMODE_HALFOP) || c->HasUserStatus(u, CMODE_OP) || c->HasUserStatus(u, CMODE_PROTECT) || c->HasUserStatus(u, CMODE_OWNER)))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && c->HasUserStatus(u, CMODE_VOICE))
Allow = false;
if (Allow)
{
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 (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find(2) != Anope::string::npos)
{
check_ban(ci, u, TTB_BOLDS);
bot_kick(ci, u, _("Don't use bolds on this channel!"));
return;
}
/* Color kicker */
if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find(3) != Anope::string::npos)
{
check_ban(ci, u, TTB_COLORS);
bot_kick(ci, u, _("Don't use colors on this channel!"));
return;
}
/* Reverses kicker */
if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find(22) != Anope::string::npos)
{
check_ban(ci, u, TTB_REVERSES);
bot_kick(ci, u, _("Don't use reverses on this channel!"));
return;
}
/* Italics kicker */
if (ci->botflags.HasFlag(BS_KICK_ITALICS) && realbuf.find(29) != Anope::string::npos)
{
check_ban(ci, u, TTB_ITALICS);
bot_kick(ci, u, _("Don't use italics on this channel!"));
return;
}
/* Underlines kicker */
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find(31) != Anope::string::npos)
{
check_ban(ci, u, TTB_UNDERLINES);
bot_kick(ci, u, _("Don't use underlines on this channel!"));
return;
}
/* Caps kicker */
if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->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 >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent)
{
check_ban(ci, u, TTB_CAPS);
bot_kick(ci, u, _("Turn caps lock OFF!"));
return;
}
}
/* Bad words kicker */
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
bool mustkick = false;
/* Normalize the buffer */
Anope::string nbuf = normalizeBuffer(realbuf);
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
BadWord *bw = ci->GetBadWord(i);
if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
mustkick = true;
else if (bw->type == BW_SINGLE)
{
check_ban(c->ci, u, TTB_AMSGS);
bot_kick(c->ci, u, _("Don't use AMSGs!"));
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))
mustkick = true;
else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))))
mustkick = true;
else
{
if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
}
else if (bw->type == BW_START)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word;
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
else if (bw->type == BW_END)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
if (mustkick)
{
check_ban(ci, u, TTB_BADWORDS);
if (Config->BSGentleBWReason)
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;
}
}
return EVENT_CONTINUE;
UserData *ud = NULL;
/* Flood kicker */
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
ud = GetUserData(u, c);
if (ud)
{
if (Anope::CurTime - ud->last_start > ci->floodsecs)
{
ud->last_start = Anope::CurTime;
ud->lines = 0;
}
++ud->lines;
if (ud->lines >= ci->floodlines)
{
check_ban(ci, u, TTB_FLOOD);
bot_kick(ci, u, _("Stop flooding!"));
return;
}
}
}
/* Repeat kicker */
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (!ud)
ud = GetUserData(u, c);
if (ud)
{
if (!ud->lastline.empty() && !ud->lastline.equals_ci(realbuf))
{
ud->lastline = realbuf;
ud->times = 0;
}
else
{
if (ud->lastline.empty())
ud->lastline = realbuf;
++ud->times;
}
if (ud->times >= ci->repeattimes)
{
check_ban(ci, u, TTB_REPEAT);
bot_kick(ci, u, _("Stop repeating yourself!"));
return;
}
}
}
if (ud && ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *chan = (*it)->chan;
++it;
if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv(CA_NOKICK))
{
check_ban(chan->ci, u, TTB_AMSGS);
bot_kick(chan->ci, u, _("Don't use AMSGs!"));
}
}
}
if (ud)
ud->lasttarget = ci->name;
}
}
u->Extend("bs_kick_lastmsg", new ExtensibleItemRegular<Anope::string>(msg));
u->Extend("bs_kick_lasttime", new ExtensibleItemRegular<time_t>(Anope::CurTime));
u->Extend("bs_kick_lastchan", new ExtensibleItemRegular<Anope::string>(ci->name));
return EVENT_CONTINUE;
}
};
@@ -16,13 +16,13 @@
class CommandBSSet : public Command
{
public:
CommandBSSet() : Command("SET", 3, 3)
CommandBSSet(Module *creator) : Command(creator, "botserv/set", 3, 3)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Configures bot options"));
this->SetSyntax(_("\037(channel | bot)\037 \037option\037 \037settings\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
@@ -39,8 +39,8 @@ class CommandBSSet : public Command
if (!(bi = findbot(chan)))
{
source.Reply(_(BOT_DOES_NOT_EXIST), chan.c_str());
return MOD_CONT;
source.Reply(BOT_DOES_NOT_EXIST, chan.c_str());
return;
}
if (value.equals_ci("ON"))
@@ -54,16 +54,16 @@ class CommandBSSet : public Command
source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
}
else
SyntaxError(source, "SET PRIVATE", _("SET \037botname\037 PRIVATE {\037ON|\037}"));
return MOD_CONT;
this->OnSyntaxError(source, "PRIVATE");
return;
}
else if (!(ci = cs_findchan(chan)))
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET))
source.Reply(_(ACCESS_DENIED));
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_SET))
source.Reply(ACCESS_DENIED);
else
{
bool override = !check_access(u, ci, CA_SET);
bool override = !ci->AccessFor(u).HasPriv(CA_SET);
Log(override ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("DONTKICKOPS"))
@@ -79,7 +79,7 @@ class CommandBSSet : public Command
source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET DONTKICKOPS", _("SET \037channel\037 DONTKICKOPS {\037ON|\037}"));
this->OnSyntaxError(source, "DONTKICKOPS");
}
else if (option.equals_ci("DONTKICKVOICES"))
{
@@ -94,7 +94,7 @@ class CommandBSSet : public Command
source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET DONTKICKVOICES", _("SET \037channel\037 DONTKICKVOICES {\037ON|\037}"));
this->OnSyntaxError(source, "DONTKICKVOICE");
}
else if (option.equals_ci("FANTASY"))
{
@@ -109,7 +109,7 @@ class CommandBSSet : public Command
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET FANTASY", _("SET \037channel\037 FANTASY {\037ON|\037}"));
this->OnSyntaxError(source, "FANTASY");
}
else if (option.equals_ci("GREET"))
{
@@ -124,7 +124,7 @@ class CommandBSSet : public Command
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}"));
this->OnSyntaxError(source, "GREET");
}
else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
{
@@ -141,22 +141,7 @@ class CommandBSSet : public Command
source.Reply(_("No Bot mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET NOBOT", _("SET \037botname\037 NOBOT {\037ON|\037}"));
}
else if (option.equals_ci("SYMBIOSIS"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_SYMBIOSIS);
source.Reply(_("Symbiosis mode is now \002on\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_SYMBIOSIS);
source.Reply(_("Symbiosis mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET SYMBIOSIS", _("SET \037channel\037 SYMBIOSIS {\037ON|\037}"));
this->OnSyntaxError(source, "NOBOT");
}
else if (option.equals_ci("MSG"))
{
@@ -189,34 +174,33 @@ class CommandBSSet : public Command
source.Reply(_("Fantasy replies will be sent via NOTICE to channel ops on %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET MSG", _("SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|\037}"));
this->OnSyntaxError(source, "MSG");
}
else
source.Reply(_(UNKNOWN_OPTION), option.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(), this->name.c_str());
this->OnSyntaxError(source, "");
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
{
source.Reply(_("Syntax: \002SET \037(channel | bot)\037 \037option\037 \037parameters\037\002\n"
" \n"
"Configures bot options. \037option\037 can be one of:\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Configures bot options. \037option\037 can be one of:\n"
" \n"
" DONTKICKOPS To protect ops against bot kicks\n"
" DONTKICKVOICES To protect voices against bot kicks\n"
" GREET Enable greet messages\n"
" FANTASY Enable fantaisist commands\n"
" SYMBIOSIS Allow the bot to act as a real bot\n"
" MSG Configure how fantasy commands should be replied to\n"
" \n"
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
"on a specific option.\n"
"Note: access to this command is controlled by the\n"
"level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
"level SET."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
User *u = source.u;
if (u->IsServicesOper())
source.Reply(_("These options are reserved to Services Operators:\n"
@@ -260,13 +244,6 @@ class CommandBSSet : public Command
"When it is enabled, the bot will display greet\n"
"messages of users joining the channel, provided\n"
"they have enough access to the channel."));
else if (subcommand.equals_ci("SYMBIOSIS"))
source.Reply(_("Syntax: \002SET \037channel\037 SYMBIOSIS {\037ON|OFF\037}\n"
" \n"
"Enables or disables \002symbiosis\002 mode on a channel.\n"
"When it is enabled, the bot will do everything\n"
"normally done by %s on channels, such as MODEs,\n"
"KICKs, and even the entry message."), Config->s_ChanServ.c_str());
else if (subcommand.equals_ci("NOBOT"))
source.Reply(_("Syntax: \002SET \037channel\037 NOBOT {\037ON|OFF\037}\002\n"
" \n"
@@ -294,7 +271,24 @@ class CommandBSSet : public Command
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "SET", _("SET \037(channel | bot)\037 \037option\037 \037settings\037"));
if (subcommand.empty())
Command::OnSyntaxError(source, "");
else if (subcommand.equals_ci("PRIVATE"))
this->SendSyntax(source, "\037botname\037 PRIVATE {\037ON|OFF\037}");
else if (subcommand.equals_ci("DONTKICKOPS"))
this->SendSyntax(source, "\037channel\037 DONTKICKOPS {\037ON|OFF\037}");
else if (subcommand.equals_ci("DONTKICKVOICES"))
this->SendSyntax(source, "\037channel\037 DONTKICKVOICES {\037ON|OFF\037}");
else if (subcommand.equals_ci("FANTASY"))
this->SendSyntax(source, "\037channel\037 FANTASY {\037ON|OFF\037}");
else if (subcommand.equals_ci("GREET"))
this->SendSyntax(source, "\037channel\037 GREET {\037ON|OFF\037}");
else if (subcommand.equals_ci("MSG"))
this->SendSyntax(source, "\037channel\037 MSG {\037PRIVMSG|NOTICE|NOTICEOPS|OFF\037}");
else if (subcommand.equals_ci("NOBOT"))
this->SendSyntax(source, "\037channel\037 NOBOT {\037ON|OFF\037}");
else
this->OnSyntaxError(source, "");
}
};
@@ -303,12 +297,12 @@ class BSSet : public Module
CommandBSSet commandbsset;
public:
BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandbsset(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(BotServ, &commandbsset);
ModuleManager::RegisterService(&commandbsset);
}
};
+937
View File
@@ -0,0 +1,937 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
enum
{
ACCESS_INVALID = -10000,
ACCESS_FOUNDER = 10001
};
static struct AccessLevels
{
ChannelAccess priv;
int default_level;
Anope::string config_name;
Anope::string name;
Anope::string desc;
} defaultLevels[] = {
{ CA_ACCESS_CHANGE, 10, "level_change", "ACC-CHANGE", _("Allowed to modify the access list") },
{ CA_ACCESS_LIST, 1, "level_list", "ACC-LIST", _("Allowed to view the access list") },
{ CA_AKICK, 10, "level_akick", "AKICK", _("Allowed to use AKICK command") },
{ CA_ASSIGN, ACCESS_FOUNDER, "level_assign", "ASSIGN", _("Allowed to assign/unassign a bot") },
{ CA_AUTOHALFOP, 4, "level_autohalfop", "AUTOHALFOP", _("Automatic mode +h") },
{ CA_AUTOOP, 5, "level_autoop", "AUTOOP", _("Automatic channel operator status") },
{ CA_AUTOOWNER, 10000, "level_autoowner", "AUTOOWNER", _("Automatic mode +q") },
{ CA_AUTOPROTECT, 10, "level_autoprotect", "AUTOPROTECT", _("Automatic mode +a") },
{ CA_AUTOVOICE, 3, "level_autovoice", "AUTOVOICE", _("Automatic mode +v") },
{ CA_BADWORDS, 10, "level_badwords", "BADWORDS", _("Allowed to modify channel badwords list") },
{ CA_BAN, 4, "level_ban", "BAN", _("Allowed to use ban users") },
{ CA_FANTASIA, 3, "level_fantasia", "FANTASIA", _("Allowed to use fantaisist commands") },
{ CA_FOUNDER, ACCESS_FOUNDER, "level_founder", "FOUNDER", _("Allowed to issue commands restricted to channel founders") },
{ CA_GETKEY, 5, "level_getkey", "GETKEY", _("Allowed to use GETKEY command") },
{ CA_GREET, 5, "level_greet", "GREET", _("Greet message displayed") },
{ CA_HALFOP, 5, "level_halfop", "HALFOP", _("Allowed to (de)halfop users") },
{ CA_HALFOPME, 4, "level_halfopme", "HALFOPME", _("Allowed to (de)halfop him/herself") },
{ CA_INFO, 10000, "level_info", "INFO", _("Allowed to use INFO command with ALL option") },
{ CA_INVITE, 5, "level_invite", "INVITE", _("Allowed to use the INVITE command") },
{ CA_KICK, 4, "level_kick", "KICK", _("Allowed to use the KICK command") },
{ CA_MEMO, 10, "level_memo", "MEMO", _("Allowed to read channel memos") },
{ CA_MODE, 5, "level_mode", "MODE", _("Allowed to change channel modes") },
{ CA_NOKICK, 1, "level_nokick", "NOKICK", _("Never kicked by the bot's kickers") },
{ CA_OPDEOP, 5, "level_opdeop", "OPDEOP", _("Allowed to (de)op users") },
{ CA_OPDEOPME, 5, "level_opdeopme", "OPDEOPME", _("Allowed to (de)op him/herself") },
{ CA_OWNER, ACCESS_FOUNDER, "level_owner", "OWNER", _("Allowed to use (de)owner users") },
{ CA_OWNERME, 10000, "level_ownerme", "OWNERME", _("Allowed to (de)owner him/herself") },
{ CA_PROTECT, 10000, "level_protect", "PROTECT", _("Allowed to (de)protect users") },
{ CA_PROTECTME, 10, "level_protectme", "PROTECTME", _("Allowed to (de)protect him/herself"), },
{ CA_SAY, 5, "level_say", "SAY", _("Allowed to use SAY and ACT commands") },
{ CA_SIGNKICK, ACCESS_FOUNDER, "level_signkick", "SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used") },
{ CA_SET, 10000, "level_set", "SET", _("Allowed to set channel settings") },
{ CA_TOPIC, 5, "level_topic", "TOPIC", _("Allowed to change channel topics") },
{ CA_UNBAN, 4, "level_unban", "UNBAN", _("Allowed to unban users") },
{ CA_VOICE, 4, "level_voice", "VOICE", _("Allowed to (de)voice users") },
{ CA_VOICEME, 3, "level_voiceme", "VOICEME", _("Allowed to (de)voice him/herself") },
{ CA_SIZE, -1, "", "", "" }
};
static void reset_levels(ChannelInfo *ci)
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
ci->levels[defaultLevels[i].priv] = defaultLevels[i].default_level;
}
class AccessChanAccess : public ChanAccess
{
public:
int level;
AccessChanAccess(AccessProvider *p) : ChanAccess(p)
{
}
bool Matches(User *u, NickCore *nc)
{
if (u && this->mask.find_first_of("!@?*") != Anope::string::npos && (Anope::Match(u->nick, this->mask) || Anope::Match(u->GetMask(), this->mask)))
return true;
else if (nc && Anope::Match(nc->display, this->mask))
return true;
return false;
}
bool HasPriv(ChannelAccess priv)
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
if (defaultLevels[i].priv == priv)
return this->ci->levels[priv] != ACCESS_INVALID && DetermineLevel(this) >= this->ci->levels[priv];
return false;
}
Anope::string Serialize()
{
return stringify(this->level);
}
void Unserialize(const Anope::string &data)
{
this->level = convertTo<int>(data);
}
static int DetermineLevel(ChanAccess *access)
{
if (access->provider->name == "access/access")
{
AccessChanAccess *aaccess = debug_cast<AccessChanAccess *>(access);
return aaccess->level;
}
else
{
int highest = 1;
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
if (access->ci->levels[defaultLevels[i].priv] > highest && access->HasPriv(defaultLevels[i].priv))
highest = access->ci->levels[defaultLevels[i].priv];
if (highest >= ACCESS_FOUNDER)
highest = ACCESS_FOUNDER - 1;
return highest;
}
}
};
class AccessAccessProvider : public AccessProvider
{
public:
AccessAccessProvider(Module *o) : AccessProvider(o, "access/access")
{
}
ChanAccess *Create()
{
return new AccessChanAccess(this);
}
};
class AccessListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AccessListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AccessListCallback()
{
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
source.Reply(_(" %3d %4d %s"), Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str());
}
};
class AccessViewCallback : public AccessListCallback
{
public:
AccessViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
Anope::string timebuf;
if (ci->c)
for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
if (access->Matches((*cit)->user, (*cit)->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
if (access->last_seen == 0)
timebuf = "Never";
else
timebuf = do_strftime(access->last_seen, NULL, true);
}
source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str(), access->creator.c_str(), do_strftime(access->created, NULL, true).c_str(), timebuf.c_str());
}
};
class AccessDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool Denied;
bool override;
public:
AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false)
{
if (!ci->AccessFor(source.u).HasPriv(CA_ACCESS_CHANGE) && source.u->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.u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << 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)
{
if (!Number || Number > ci->GetAccessCount())
return;
User *u = source.u;
ChanAccess *access = ci->GetAccess(Number - 1);
AccessGroup u_access = ci->AccessFor(u);
ChanAccess *u_highest = u_access.Highest();
if (u_highest ? AccessChanAccess::DetermineLevel(u_highest) : 0 <= AccessChanAccess::DetermineLevel(access) && !u->HasPriv("chanserv/access/modify"))
{
Denied = true;
return;
}
++Deleted;
if (!Nicks.empty())
Nicks += ", " + access->mask;
else
Nicks = access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(Number - 1);
}
};
class CommandCSAccess : public Command
{
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string mask = params[2];
int level = ACCESS_INVALID;
try
{
level = convertTo<int>(params[3]);
}
catch (const ConvertException &) { }
if (!level)
{
source.Reply(_("Access level must be non-zero."));
return;
}
AccessGroup u_access = ci->AccessFor(u);
ChanAccess *highest = u_access.Highest();
int u_level = (highest ? AccessChanAccess::DetermineLevel(highest) : 0);
if (level >= u_level && !u_access.Founder && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(ACCESS_DENIED);
return;
}
else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
{
source.Reply(CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE) || (level >= u_level && !u_access.Founder);
if (mask.find_first_of("!*@") == Anope::string::npos && findnick(mask) == NULL)
mask += "!*@*";
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
ChanAccess *access = ci->GetAccess(i - 1);
if (mask.equals_ci(access->mask))
{
/* Don't allow lowering from a level >= u_level */
if (AccessChanAccess::DetermineLevel(access) >= u_level && !u_access.Founder && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(ACCESS_DENIED);
return;
}
ci->EraseAccess(i - 1);
break;
}
}
if (ci->GetAccessCount() >= Config->CSAccessMax)
{
source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
return;
}
service_reference<AccessProvider> provider("access/access");
if (!provider)
return;
AccessChanAccess *access = debug_cast<AccessChanAccess *>(provider->Create());
access->ci = ci;
access->mask = mask;
access->creator = u->nick;
access->level = level;
access->last_seen = 0;
access->created = Anope::CurTime;
ci->AddAccess(access);
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->mask.c_str(), ci->name.c_str(), level);
return;
}
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
const Anope::string &mask = params[2];
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)
{
AccessDelCallback list(source, ci, this, mask);
list.Process();
}
else
{
AccessGroup u_access = ci->AccessFor(u);
ChanAccess *highest = u_access.Highest();
int u_level = (highest ? AccessChanAccess::DetermineLevel(highest) : 0);
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
ChanAccess *access = ci->GetAccess(i - 1);
if (mask.equals_ci(access->mask))
{
int access_level = AccessChanAccess::DetermineLevel(access);
if (!access->mask.equals_ci(u->Account()->display) && !u_access.Founder && u_level <= access_level && !u->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(CA_ACCESS_CHANGE) && !access->mask.equals_ci(u->Account()->display);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(access);
}
return;
}
}
source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
}
return;
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessListCallback list(source, ci, nick);
list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
ChanAccess *access = ci->GetAccess(i);
if (!nick.empty() && !Anope::Match(access->mask, nick))
continue;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
AccessListCallback::DoList(source, ci, i, access);
}
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return;
}
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessViewCallback list(source, ci, nick);
list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
ChanAccess *access = ci->GetAccess(i);
if (!nick.empty() && !Anope::Match(access->mask, nick))
continue;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
AccessViewCallback::DoList(source, ci, i, access);
}
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return;
}
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else
{
ci->ClearAccess();
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
}
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\002"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &cmd = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
bool is_clear = cmd.equals_ci("CLEAR");
bool is_del = cmd.equals_ci("DEL");
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
has_access = true;
else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
has_access = true;
else if (is_del)
{
NickAlias *na = findnick(nick);
if (na && na->nc == u->Account())
has_access = true;
}
/* If LIST, we don't *require* any parameters, but we can take any.
* If DEL, we require a nick and no level.
* Else (ADD), we require a level (which implies a nick). */
if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
this->OnSyntaxError(source, cmd);
else if (!has_access)
source.Reply(ACCESS_DENIED);
else if (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)
{
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.owner->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"
"must be less than that of the user giving the command, and\n"
"if the \037mask\037 is already on the access list, the current\n"
"access level of that nick must be less than the access level\n"
"of the user giving the command. When a user joins the channel\n"
"the access they receive is from the highest level entry in the\n"
"access list."));
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(_("\002User access levels\002\n"
" \n"
"By default, the following access levels are defined:\n"
" \n"
" \002Founder\002 Full access to %s functions; automatic\n"
" opping upon entering channel. Note\n"
" that only one person may have founder\n"
" status (it cannot be given using the\n"
" \002ACCESS\002 command).\n"
" \002 10\002 Access to AKICK command; automatic opping.\n"
" \002 5\002 Automatic opping.\n"
" \002 3\002 Automatic voicing.\n"
" \002 0\002 No special privileges; can be opped by other\n"
" ops (unless \002secure-ops\002 is set).\n"
" \n"
"These levels may be changed, or new ones added, using the\n"
"\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n"
"information."), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
class CommandCSLevels : public Command
{
int levelinfo_maxwidth;
void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
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
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
if (what.equals_ci(l.name))
{
ci->levels[l.priv] = level;
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level));
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << l.name << " to " << level;
if (level == ACCESS_FOUNDER)
source.Reply(_("Level for %s on channel %s changed to founder only."), l.name.c_str(), ci->name.c_str());
else
source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), l.name.c_str(), ci->name.c_str(), level);
return;
}
}
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
return;
}
void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
const Anope::string &what = params[2];
/* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
if (!what.equals_ci("FOUNDER"))
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
if (what.equals_ci(l.name))
{
ci->levels[l.priv] = ACCESS_INVALID;
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, l.priv));
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << l.name;
source.Reply(_("\002%s\002 disabled on channel %s."), l.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->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return;
}
void DoList(CommandSource &source, ChannelInfo *ci)
{
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
if (!levelinfo_maxwidth)
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
int len = l.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
int j = ci->levels[l.priv];
if (j == ACCESS_INVALID)
source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, l.name.c_str());
else if (j == ACCESS_FOUNDER)
source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, l.name.c_str());
else
source.Reply(_(" %-*s %d"), levelinfo_maxwidth, l.name.c_str(), j);
}
return;
}
void DoReset(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
reset_levels(ci);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
return;
}
public:
CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4), levelinfo_maxwidth(0)
{
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)
{
const Anope::string &cmd = params[1];
const Anope::string &what = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
/* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
* one; else, we want none.
*/
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 (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
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)
{
if (subcommand.equals_ci("DESC"))
{
source.Reply(_("The following feature/function names are understood."));
if (!levelinfo_maxwidth)
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
int len = l.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
source.Reply(_(" %-*s %s"), levelinfo_maxwidth, l.name.c_str(), translate(source.u, l.desc.c_str()));
}
}
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).\n"
" \n"
"\002LEVELS LIST\002 shows the current levels for each function or\n"
"group of functions. \002LEVELS RESET\002 resets the levels to the\n"
"default levels of a newly-created channel (see\n"
"\002HELP ACCESS LEVELS\002).\n"
" \n"
"For a list of the features and functions whose levels can be\n"
"set, see \002HELP LEVELS DESC\002."), source.owner->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, CORE),
accessprovider(this), commandcsaccess(this), commandcslevels(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&accessprovider);
ModuleManager::RegisterService(&commandcsaccess);
ModuleManager::RegisterService(&commandcslevels);
Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCreateChan, I_OnGroupCheckPriv };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
this->OnReload();
}
void OnReload()
{
ConfigReader config;
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
if (value.equals_ci("founder"))
l.default_level = ACCESS_FOUNDER;
else if (value.equals_ci("disabled"))
l.default_level = ACCESS_INVALID;
else
l.default_level = config.ReadInteger("chanserv", l.config_name, 0, false);
}
}
void OnChanRegistered(ChannelInfo *ci)
{
reset_levels(ci);
}
void OnCreateChan(ChannelInfo *ci)
{
reset_levels(ci);
}
EventReturn OnGroupCheckPriv(const AccessGroup *group, ChannelAccess priv)
{
if (group->ci == NULL)
return EVENT_CONTINUE;
/* Special case. Allows a level of < 0 to match anyone, and a level of 0 to match anyone identified. */
int16 level = group->ci->levels[priv];
if (level < 0)
return EVENT_ALLOW;
else if (level == 0 && group->nc)
return EVENT_ALLOW;
return EVENT_CONTINUE;
}
};
MODULE_INIT(CSAccess)
@@ -13,11 +13,6 @@
#include "module.h"
/* Split a usermask up into its constitutent parts. Returned strings are
* malloc()'d, and should be free()'d when done with. Returns "*" for
* missing parts.
*/
static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope::string &user, Anope::string &host)
{
size_t ex = mask.find('!'), at = mask.find('@', ex == Anope::string::npos ? 0 : ex + 1);
@@ -55,69 +50,70 @@ class AkickListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AkickListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
AkickListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AkickListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s autokick list."), source.ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : NO_REASON);
}
};
class AkickViewCallback : public AkickListCallback
{
public:
AkickViewCallback(CommandSource &_source, const Anope::string &numlist) : AkickListCallback(_source, numlist)
AkickViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
Anope::string timebuf;
if (akick->addtime)
timebuf = do_strftime(akick->addtime);
else
timebuf = _(UNKNOWN);
timebuf = UNKNOWN;
source.Reply(_(CHAN_AKICK_VIEW_FORMAT), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
source.Reply(CHAN_AKICK_VIEW_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
if (akick->last_used)
source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str());
@@ -127,18 +123,18 @@ class AkickViewCallback : public AkickListCallback
class AkickDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
public:
AkickDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0)
AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0)
{
}
~AkickDelCallback()
{
User *u = source.u;
ChannelInfo *ci = source.ci;
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users";
if (!Deleted)
@@ -151,20 +147,19 @@ class AkickDelCallback : public NumberList
void HandleNumber(unsigned Number)
{
if (!Number || Number > source.ci->GetAkickCount())
if (!Number || Number > ci->GetAkickCount())
return;
++Deleted;
source.ci->EraseAkick(Number - 1);
ci->EraseAkick(Number - 1);
}
};
class CommandCSAKick : public Command
{
void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string mask = params[2];
Anope::string reason = params.size() > 3 ? params[3] : "";
@@ -180,32 +175,30 @@ class CommandCSAKick : public Command
mask = nick + "!" + user + "@" + host;
}
else
{
if (na->HasFlag(NS_FORBIDDEN))
{
source.Reply(_(NICK_X_FORBIDDEN), mask.c_str());
return;
}
nc = na->nc;
}
/* Check excepts BEFORE we get this far */
if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted_mask(ci, mask))
if (ci->c)
{
source.Reply(_(CHAN_EXCEPTED), mask.c_str(), ci->name.c_str());
return;
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = ci->c->GetModeList(CMODE_EXCEPT);
for (; modes.first != modes.second; ++modes.first)
{
if (Anope::Match(modes.first->second, mask))
{
source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
return;
}
}
}
/* Check whether target nick has equal/higher access
* or whether the mask matches a user with higher/equal access - Viper */
if (ci->HasFlag(CI_PEACE) && nc)
{
ChanAccess *nc_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0;
if (nc == ci->founder || nc_level >= u_level)
AccessGroup nc_access = ci->AccessFor(nc), u_access = ci->AccessFor(u);
if (nc == ci->GetFounder() || nc_access >= u_access)
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -217,13 +210,12 @@ class CommandCSAKick : public Command
{
User *u2 = it->second;
ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0;
AccessGroup nc_access = ci->AccessFor(nc), u_access = ci->AccessFor(u);
Entry entry_mask(CMODE_BEGIN, mask);
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && entry_mask.Matches(u2))
if ((ci->AccessFor(u2).HasPriv(CA_FOUNDER) || nc_access >= u_access) && entry_mask.Matches(u2))
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -232,19 +224,15 @@ class CommandCSAKick : public Command
* or higher access. - Viper */
for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it)
{
NickAlias *na2 = it->second;
na = it->second;
if (na2->HasFlag(NS_FORBIDDEN))
continue;
ChanAccess *na2_access = ci->GetAccess(na2->nc), *u_access = ci->GetAccess(u);
int16 na2_level = na2_access ? na2_access->level : 0, u_level = u_access ? u_access->level : 0;
if (na2->nc && (na2->nc == ci->founder || na2_level >= u_level))
AccessGroup nc_access = ci->AccessFor(na->nc), u_access = ci->AccessFor(u);
if (na->nc && (na->nc == ci->GetFounder() || nc_access >= u_access))
{
Anope::string buf = na2->nick + "!" + na2->last_usermask;
Anope::string buf = na->nick + "!" + na->last_usermask;
if (Anope::Match(buf, mask))
{
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
return;
}
}
@@ -272,20 +260,19 @@ class CommandCSAKick : public Command
else
akick = ci->AddAkick(u->nick, mask, reason);
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << ": " << reason;
FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
this->DoEnforce(source);
this->DoEnforce(source, ci);
}
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params[2];
AutoKick *akick;
@@ -300,7 +287,7 @@ class CommandCSAKick : public Command
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickDelCallback list(source, this, mask);
AkickDelCallback list(source, ci, this, mask);
list.Process();
}
else
@@ -322,7 +309,7 @@ class CommandCSAKick : public Command
return;
}
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << mask;
ci->EraseAkick(i);
@@ -331,14 +318,13 @@ class CommandCSAKick : public Command
}
}
void DoList(CommandSource &source, const std::vector<Anope::string> &params)
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
if (!ci->GetAkickCount())
@@ -349,7 +335,7 @@ class CommandCSAKick : public Command
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickListCallback list(source, mask);
AkickListCallback list(source, ci, mask);
list.Process();
}
else
@@ -374,7 +360,7 @@ class CommandCSAKick : public Command
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickListCallback::DoList(source, i, akick);
AkickListCallback::DoList(source, ci, i, akick);
}
if (!SentHeader)
@@ -382,14 +368,13 @@ class CommandCSAKick : public Command
}
}
void DoView(CommandSource &source, const std::vector<Anope::string> &params)
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW";
if (!ci->GetAkickCount())
@@ -400,7 +385,7 @@ class CommandCSAKick : public Command
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickViewCallback list(source, mask);
AkickViewCallback list(source, ci, mask);
list.Process();
}
else
@@ -425,7 +410,7 @@ class CommandCSAKick : public Command
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickViewCallback::DoList(source, i, akick);
AkickViewCallback::DoList(source, ci, i, akick);
}
if (!SentHeader)
@@ -433,16 +418,15 @@ class CommandCSAKick : public Command
}
}
void DoEnforce(CommandSource &source)
void DoEnforce(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
int count = 0;
if (!c)
{
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
return;
}
@@ -454,17 +438,16 @@ class CommandCSAKick : public Command
++count;
}
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, 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)
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
bool override = !check_access(u, ci, CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
ci->ClearAkick();
@@ -472,54 +455,61 @@ class CommandCSAKick : public Command
}
public:
CommandCSAKick() : Command("AKICK", 2, 4)
CommandCSAKick(Module *creator) : Command(creator, "chanserv/akick", 2, 4)
{
this->SetDesc(_("Maintain the AutoKick list"));
this->SetSyntax(_("\037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 ENFORCE"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string cmd = params[1];
Anope::string mask = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
this->OnSyntaxError(source, cmd);
else if (!check_access(u, ci, CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else if (!ci->AccessFor(u).HasPriv(CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
else if (cmd.equals_ci("ADD"))
this->DoAdd(source, params);
this->DoAdd(source, ci, params);
else if (cmd.equals_ci("DEL"))
this->DoDel(source, params);
this->DoDel(source, ci, params);
else if (cmd.equals_ci("LIST"))
this->DoList(source, params);
this->DoList(source, ci, params);
else if (cmd.equals_ci("VIEW"))
this->DoView(source, params);
this->DoView(source, ci, params);
else if (cmd.equals_ci("ENFORCE"))
this->DoEnforce(source);
this->DoEnforce(source, ci);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(source);
this->DoClear(source, ci);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002AKICK \037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]\002\n"
" \002AKICK \037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002AKICK \037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
" \002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
" \002AKICK \037channel\037 ENFORCE\002\n"
" \002AKICK \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002AutoKick list\002 for a channel. If a user\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Maintains the \002AutoKick list\002 for a channel. If a user\n"
"on the AutoKick list attempts to join the channel,\n"
"%s will ban that user from the channel, then kick\n"
"the user.\n"
@@ -532,7 +522,7 @@ class CommandCSAKick : public Command
"When akicking a \037registered nick\037 the nickserv account\n"
"will be added to the akick list instead of the mask.\n"
"All users within that nickgroup will then be akicked.\n"),
ChanServ->nick.c_str());
source.owner->nick.c_str());
source.Reply(_(
" \n"
"The \002AKICK DEL\002 command removes the given nick or mask\n"
@@ -552,14 +542,9 @@ class CommandCSAKick : public Command
"AKICK mask.\n"
" \n"
"The \002AKICK CLEAR\002 command clears all entries of the\n"
"akick list."), ChanServ->nick.c_str());
"akick list."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "AKICK", _("AKICK \037channel\037 {ADD | DEL | LIST | VIEW | ENFORCE | CLEAR} [\037nick-or-usermask\037] [\037reason\037]"));
}
};
class CSAKick : public Module
@@ -567,12 +552,12 @@ class CSAKick : public Module
CommandCSAKick commandcsakick;
public:
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsakick(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsakick);
ModuleManager::RegisterService(&commandcsakick);
}
};
@@ -18,8 +18,6 @@
#include "module.h"
#define AUTHOR "SGR"
/* ------------------------------------------------------------
* Name: cs_appendtopic
* Author: SGR <Alex_SGR@ntlworld.com>
@@ -41,56 +39,55 @@
/* DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */
/* ---------------------------------------------------------------------- */
static Module *me;
class CommandCSAppendTopic : public Command
{
public:
CommandCSAppendTopic() : Command("APPENDTOPIC", 2, 2)
CommandCSAppendTopic(Module *creator) : Command(creator, "chanserv/appendtopic", 2, 2)
{
this->SetDesc(_("Add text to a channels topic"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &newtopic = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(params[0]);;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
else if (!check_access(u, ci, CA_TOPIC))
source.Reply(_(ACCESS_DENIED));
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_TOPIC))
source.Reply(ACCESS_DENIED);
else
{
Anope::string topic;
if (!ci->last_topic.empty())
if (!c->ci->last_topic.empty())
{
topic = ci->last_topic + " " + newtopic;
ci->last_topic.clear();
topic = c->ci->last_topic + " " + newtopic;
c->ci->last_topic.clear();
}
else
topic = newtopic;
bool has_topiclock = ci->HasFlag(CI_TOPICLOCK);
ci->UnsetFlag(CI_TOPICLOCK);
bool has_topiclock = c->ci->HasFlag(CI_TOPICLOCK);
c->ci->UnsetFlag(CI_TOPICLOCK);
c->ChangeTopic(u->nick, topic, Anope::CurTime);
if (has_topiclock)
ci->SetFlag(CI_TOPICLOCK);
c->ci->SetFlag(CI_TOPICLOCK);
bool override = !check_access(u, ci, CA_TOPIC);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "changed topic to " << topic;
bool override = c->ci->AccessFor(u).HasPriv(CA_TOPIC);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, c->ci) << "changed topic to " << topic;
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
me->SendMessage(source, _("Syntax: APPENDTOPIC channel text"));
source.Reply(_("Syntax: APPENDTOPIC channel text"));
source.Reply(" ");
me->SendMessage(source, _("This command allows users to append text to a currently set\n"
source.Reply(("This command allows users to append text to a currently set\n"
"channel topic. When TOPICLOCK is on, the topic is updated and\n"
"the new, updated topic is locked."));
@@ -99,7 +96,7 @@ class CommandCSAppendTopic : public Command
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
me->SendMessage(source, _("Syntax: APPENDTOPIC channel text"));
source.Reply(_("Syntax: APPENDTOPIC channel text"));
}
};
@@ -108,14 +105,12 @@ class CSAppendTopic : public Module
CommandCSAppendTopic commandcsappendtopic;
public:
CSAppendTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSAppendTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsappendtopic(this)
{
me = this;
this->SetAuthor("SGR");
this->SetAuthor(AUTHOR);
this->SetType(SUPPORTED);
this->AddCommand(ChanServ, &commandcsappendtopic);
ModuleManager::RegisterService(&commandcsappendtopic);
}
};
@@ -16,42 +16,48 @@
class CommandCSBan : public Command
{
public:
CommandCSBan(const Anope::string &cname) : Command("BAN", 2, 3)
CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 3)
{
this->SetDesc(_("Bans a selected nick on a channel"));
this->SetSyntax(_("\037#channel\037 \037nick\037 [\037reason\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
AccessGroup u_access = ci->AccessFor(u), u2_access = ci->AccessFor(u2);
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME))
source.Reply(_(ACCESS_DENIED));
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
else if (!ci->AccessFor(u).HasPriv(CA_BAN))
source.Reply(ACCESS_DENIED);
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
/*
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
source.Reply(_(CHAN_EXCEPTED), u2->nick.c_str(), ci->name.c_str());
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
source.Reply(_(ACCESS_DENIED));
source.Reply(ACCESS_DENIED);
else
{
Anope::string mask;
@@ -64,32 +70,27 @@ class CommandCSBan : public Command
/* We still allow host banning while not allowing to kick */
if (!c->FindUser(u2))
return MOD_CONT;
return;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
c->Kick(whosends(ci), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
c->Kick(whosends(ci), u2, "%s", reason.c_str());
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002BAN \037#channel\037 \037nick\037 [\037reason\037]\002\n"
" \n"
"Bans a selected nick on a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Bans a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "BAN", _("BAN \037#channel\037 \037nick\037 [\037reason\037]"));
}
};
class CSBan : public Module
@@ -97,12 +98,11 @@ class CSBan : public Module
CommandCSBan commandcsban;
public:
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcsban("BAN")
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsban(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsban);
ModuleManager::RegisterService(&commandcsban);
}
};
@@ -16,25 +16,29 @@
class CommandCSClearUsers : public Command
{
public:
CommandCSClearUsers() : Command("CLEARUSERS", 1, 1)
CommandCSClearUsers(Module *creator) : Command(creator, "chanserv/clearusers", 1, 1)
{
this->SetDesc(_("Tells ChanServ to clear (kick) all users on a channel"));
this->SetDesc(_("Kicks all users on a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(chan);
Anope::string modebuf;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!check_access(u, ci, CA_FOUNDER))
source.Reply(_(ACCESS_DENIED));
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_FOUNDER))
{
source.Reply(ACCESS_DENIED);
return;
}
Anope::string buf = "CLEARUSERS command from " + u->nick + " (" + u->Account()->display + ")";
@@ -47,24 +51,19 @@ class CommandCSClearUsers : public Command
source.Reply(_("All users have been kicked from \2%s\2."), chan.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CLEARUSERS \037channel\037\002\n"
" \n"
"Tells %s to clear (kick) all users certain settings on a channel."
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Tells %s to clear (kick) all users certain settings on a channel."
" \n"
"By default, limited to those with founder access on the\n"
"channel."), ChanServ->nick.c_str());
"channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CLEAR", _("CLEARUSERS \037channel\037"));
}
};
class CSClearUsers : public Module
@@ -72,12 +71,12 @@ class CSClearUsers : public Module
CommandCSClearUsers commandcsclearusers;
public:
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsclearusers(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsclearusers);
ModuleManager::RegisterService(&commandcsclearusers);
}
};
@@ -16,41 +16,47 @@
class CommandCSClone : public Command
{
public:
CommandCSClone() : Command("CLONE", 2, 3)
CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3)
{
this->SetDesc(_("Copy all settings from one channel to another"));
this->SetSyntax(_("\037channel\037 \037target\037 [\037what\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &channel = params[0];
const Anope::string &target = params[1];
Anope::string what = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_SET))
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
ChannelInfo *target_ci = cs_findchan(target);
if (!target_ci)
{
source.Reply(_(CHAN_X_NOT_REGISTERED), target.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
return;
}
if (!IsFounder(u, ci) || !IsFounder(u, target_ci))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return MOD_CONT;
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return;
}
if (what.equals_ci("ALL"))
@@ -59,7 +65,7 @@ public:
if (what.empty())
{
delete target_ci;
target_ci = new ChannelInfo(ci);
target_ci = new ChannelInfo(*ci);
target_ci->name = target;
RegisteredChannelList[target_ci->name] = target_ci;
target_ci->c = findchan(target_ci->name);
@@ -79,7 +85,7 @@ public:
target_ci->c->RemoveMode(NULL, cm, u->nick);
}
/* Mark the channel as persistant */
/* Mark the channel as persistent */
if (target_ci->c->HasMode(CMODE_PERM))
target_ci->SetFlag(CI_PERSIST);
/* Persist may be in def cflags, set it here */
@@ -87,7 +93,7 @@ public:
target_ci->c->SetMode(NULL, CMODE_PERM);
if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL)
target_ci->bi->Join(target_ci->c);
target_ci->bi->Join(target_ci->c, &Config->BotModeList);
}
if (target_ci->c && !target_ci->c->topic.empty())
@@ -97,7 +103,7 @@ public:
target_ci->last_topic_time = target_ci->c->topic_time;
}
else
target_ci->last_topic_setter = Config->s_ChanServ;
target_ci->last_topic_setter = source.owner->nick;
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci));
@@ -105,11 +111,20 @@ public:
}
else if (what.equals_ci("ACCESS"))
{
target_ci->ClearAccess();
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanAccess *access = ci->GetAccess(i);
target_ci->AddAccess(access->GetMask(), access->level, access->creator, access->last_seen);
ChanAccess *taccess = ci->GetAccess(i);
AccessProvider *provider = taccess->provider;
ChanAccess *newaccess = provider->Create();
newaccess->ci = target_ci;
newaccess->mask = taccess->mask;
newaccess->creator = taccess->creator;
newaccess->last_seen = taccess->last_seen;
newaccess->created = taccess->created;
newaccess->Unserialize(taccess->Serialize());
target_ci->AddAccess(newaccess);
}
source.Reply(_("All access entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
@@ -142,29 +157,24 @@ public:
else
{
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name;
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CLONE \037channel\037 \037target\037 [all | access | akick | badwords]\002\n"
" \n"
"Copies all settings, access, akicks, etc from channel to the\n"
"target channel. If access, akick, or badwords is specified then only\n"
"the respective settings are transferred. You must have founder level\n"
"access to \037channel\037 and \037target\037."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Copies all settings, access, akicks, etc from channel to the\n"
"target channel. If \037what\037 is access, akick, or badwords\n"
"then only the respective settings are transferred.\n"
"You must be the founder of \037channel\037 and \037target\037."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CLONE", _("CLONE \037channel\037 \037target\037"));
}
};
class CSClone : public Module
@@ -172,12 +182,11 @@ class CSClone : public Module
CommandCSClone commandcsclone;
public:
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsclone(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsclone);
ModuleManager::RegisterService(&commandcsclone);
}
};
@@ -16,59 +16,48 @@
class CommandCSDrop : public Command
{
public:
CommandCSDrop() : Command("DROP", 1, 1)
CommandCSDrop(Module *creator) : Command(creator, "chanserv/drop", 1, 1)
{
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetDesc(_("Cancel the registration of a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
return MOD_CONT;
return;
}
ci = cs_findchan(chan);
if (ci->HasFlag(CI_FORBIDDEN) && !u->HasCommand("chanserv/drop"))
ChannelInfo *ci = cs_findchan(chan);
if (ci == NULL)
{
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop"))
{
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_SUSPENDED, chan.c_str());
return;
}
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(ACCESS_DENIED);
return;
}
if (ci->c && ModeManager::FindChannelModeByName(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
if (ircd->chansqline && ci->HasFlag(CI_FORBIDDEN))
{
XLine x(ci->name);
ircdproto->SendSQLineDel(&x);
}
bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->founder ? ci->founder->display : "none");
if (override)
ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "none");
delete ci;
@@ -76,30 +65,23 @@ class CommandCSDrop : public Command
FOREACH_MOD(I_OnChanDrop, OnChanDrop(chan));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
this->SendSyntax(source);
source.Reply(" ");
if (u->IsServicesOper())
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Only \002Services Operators\002\n"
source.Reply(_("Unregisters the named channel. Only \002Services Operators\002\n"
"can drop a channel for which they have not identified."));
else
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Can only be used by\n"
source.Reply(_("Unregisters the named channel. Can only be used by\n"
"\002channel founder\002."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DROP", _("DROP \037channel\037"));
}
};
class CSDrop : public Module
@@ -107,12 +89,11 @@ class CSDrop : public Module
CommandCSDrop commandcsdrop;
public:
CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsdrop(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsdrop);
ModuleManager::RegisterService(&commandcsdrop);
}
};
@@ -15,8 +15,6 @@
#include "module.h"
static Module *me;
class CommandCSEnforce : public Command
{
private:
@@ -71,31 +69,24 @@ class CommandCSEnforce : public Command
void DoRestricted(Channel *c)
{
ChannelInfo *ci;
int16 old_nojoin_level;
Anope::string mask;
if (!(ci = c->ci))
ChannelInfo *ci = c->ci;
if (ci == NULL)
return;
old_nojoin_level = ci->levels[CA_NOJOIN];
if (ci->levels[CA_NOJOIN] < 0)
ci->levels[CA_NOJOIN] = 0;
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
UserContainer *uc = *it++;
User *user = uc->user;
if (check_access(uc->user, ci, CA_NOJOIN))
if (ci->AccessFor(user).empty())
{
get_idealban(ci, uc->user, mask);
Anope::string reason = GetString(uc->user->Account(), CHAN_NOT_ALLOWED_TO_JOIN);
Anope::string mask;
get_idealban(ci, user, mask);
Anope::string reason = translate(user, CHAN_NOT_ALLOWED_TO_JOIN);
c->SetMode(NULL, CMODE_BAN, mask);
c->Kick(NULL, uc->user, "%s", reason.c_str());
c->Kick(NULL, user, "%s", reason.c_str());
}
}
ci->levels[CA_NOJOIN] = old_nojoin_level;
}
void DoCModeR(Channel *c)
@@ -113,7 +104,7 @@ class CommandCSEnforce : public Command
if (!uc->user->IsIdentified())
{
get_idealban(ci, uc->user, mask);
Anope::string reason = GetString(uc->user->Account(), CHAN_NOT_ALLOWED_TO_JOIN);
Anope::string reason = translate(uc->user, CHAN_NOT_ALLOWED_TO_JOIN);
if (!c->HasMode(CMODE_REGISTEREDONLY))
c->SetMode(NULL, CMODE_BAN, mask);
c->Kick(NULL, uc->user, "%s", reason.c_str());
@@ -121,62 +112,64 @@ class CommandCSEnforce : public Command
}
}
public:
CommandCSEnforce() : Command("ENFORCE", 1, 2)
CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 1, 2)
{
this->SetDesc(_("Enforce various channel modes and set options"));
this->SetSyntax(_("\037channel\037 [\037what\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &what = params.size() > 1 ? params[1] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(params[0]);
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
else if (!check_access(u, ci, CA_AKICK))
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_AKICK))
source.Reply(ACCESS_DENIED);
else
{
if (what.empty() || what.equals_ci("SET"))
{
this->DoSet(c);
me->SendMessage(source, _("Enforced %s"), !what.empty() ? what.c_str() : "SET");
source.Reply(_("Enforced %s"), !what.empty() ? what.c_str() : "SET");
}
else if (what.equals_ci("MODES"))
{
this->DoModes(c);
me->SendMessage(source, _("Enforced %s"), what.c_str());
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("SECUREOPS"))
{
this->DoSecureOps(c);
me->SendMessage(source, _("Enforced %s"), what.c_str());
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("RESTRICTED"))
{
this->DoRestricted(c);
me->SendMessage(source, _("Enforced %s"), what.c_str());
source.Reply(_("Enforced %s"), what.c_str());
}
else if (what.equals_ci("+R"))
{
this->DoCModeR(c);
me->SendMessage(source, _("Enforced %s"), what.c_str());
source.Reply(_("Enforced %s"), what.c_str());
}
else
this->OnSyntaxError(source, "");
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
me->SendMessage(source, _("Syntax: \002ENFORCE \037channel\037 [\037what\037]\002"));
me->SendMessage(source, " ");
me->SendMessage(source, _("Enforce various channel modes and set options. The \037channel\037\n"
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 SET, SECUREOPS, RESTRICTED, MODES,\n"
@@ -187,14 +180,14 @@ class CommandCSEnforce : public Command
"SECUREOPS to enforce the SECUREOPS option, even if it is not\n"
"enabled. Use RESTRICTED to enfore the RESTRICTED option, also\n"
"if it's not enabled."));
me->SendMessage(source, " ");
source.Reply(" ");
if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
me->SendMessage(source, _("If \037what\037 is MODES, it will enforce channelmode +R if it is\n"
source.Reply(_("If \037what\037 is MODES, it will enforce channelmode +R if it is\n"
"set. If +R is specified for \037what\037, the +R channelmode will\n"
"also be enforced, but even if it is not set. If it is not set,\n"
"users will be banned to ensure they don't just rejoin."));
else
me->SendMessage(source, _("If \037what\037 is MODES, nothing will be enforced, since it would\n"
source.Reply(_("If \037what\037 is MODES, nothing will be enforced, since it would\n"
"enforce modes that the current ircd does not support. If +R is\n"
"specified for \037what\037, an equalivant of channelmode +R on\n"
"other ircds will be enforced. All users that are in the channel\n"
@@ -203,11 +196,6 @@ class CommandCSEnforce : public Command
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
me->SendMessage(source, _("Syntax: \002ENFORCE \037channel\037 [\037what\037]\002"));
}
};
class CSEnforce : public Module
@@ -215,14 +203,12 @@ class CSEnforce : public Module
CommandCSEnforce commandcsenforce;
public:
CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsenforce(this)
{
me = this;
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
this->AddCommand(ChanServ, &commandcsenforce);
ModuleManager::RegisterService(&commandcsenforce);
}
};
@@ -40,7 +40,7 @@ class CommandEntryMessage : public Command
{
source.Reply(_("Entry message list for \2%s\2:"), ci->name.c_str());
for (unsigned i = 0; i < messages.size(); ++i)
source.Reply(_(CHAN_LIST_ENTRY), i + 1, messages[i].message.c_str(), messages[i].creator.c_str(), do_strftime(messages[i].when).c_str());
source.Reply(CHAN_LIST_ENTRY, i + 1, messages[i].message.c_str(), messages[i].creator.c_str(), do_strftime(messages[i].when).c_str());
source.Reply(_("End of entry message list."));
}
else
@@ -72,10 +72,13 @@ class CommandEntryMessage : public Command
try
{
unsigned i = convertTo<unsigned>(message);
if (i <= messages.size())
if (i > 0 && i <= messages.size())
{
messages.erase(messages.begin() + i - 1);
ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
if (!messages.empty())
ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
else
ci->Shrink("cs_entrymsg");
source.Reply(_("Entry message \2%i\2 for \2%s\2 deleted."), i, ci->name.c_str());
}
else
@@ -97,17 +100,24 @@ class CommandEntryMessage : public Command
}
public:
CommandEntryMessage(const Anope::string &cname) : Command(cname, 2, 3)
CommandEntryMessage(Module *creator) : Command(creator, "chanserv/entrymsg", 2, 3)
{
this->SetDesc(_("Manage the channel's entry messages"));
this->SetSyntax(_("\037channel\037 {ADD|DEL|LIST|CLEAR} [\037message\037|\037num\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
if (ci && (IsFounder(u, ci) || u->HasCommand("chanserv/entrymsg")))
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (IsFounder(u, ci) || u->HasCommand("chanserv/entrymsg"))
{
bool success = true;
if (params[1].equals_ci("LIST"))
@@ -132,23 +142,16 @@ class CommandEntryMessage : public Command
Log(IsFounder(u, ci) ? LOG_COMMAND : LOG_OVERRIDE, u, this, ci) << params[1];
}
else
{
source.Reply(_(ACCESS_DENIED));
}
source.Reply(ACCESS_DENIED);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "ENTRYMSG", _("ENTRYMSG \037channel\037 {ADD|DEL|LIST|CLEAR} [\037message\037|\037num\037]"));
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002ENTRYMSG \037channel\037 {ADD|DEL|LIST|CLEAR} [\037message\037|\037num\037]\002\n"
" \n"
"Controls what messages will be sent to users when they join the channel."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Controls what messages will be sent to users when they join the channel."));
return true;
}
};
@@ -158,17 +161,16 @@ class CSEntryMessage : public Module
CommandEntryMessage commandentrymsg;
public:
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandentrymsg("ENTRYMSG")
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandentrymsg(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
ModuleManager::Attach(i, this, 4);
this->AddCommand(ChanServ, &commandentrymsg);
this->OnReload(false);
Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::RegisterService(&commandentrymsg);
this->OnReload();
}
void OnJoinChannel(User *u, Channel *c)
@@ -179,11 +181,11 @@ class CSEntryMessage : public Module
if (c->ci->GetExtRegular("cs_entrymsg", messages))
for (unsigned i = 0; i < messages.size(); ++i)
u->SendMessage(whosends(c->ci), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
}
}
void OnReload(bool)
void OnReload()
{
ConfigReader config;
EntryMsg::MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
+455
View File
@@ -0,0 +1,455 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
static struct FlagLevels
{
ChannelAccess priv;
char default_char;
Anope::string config_name;
Anope::string desc;
} flagLevels[] = {
{ CA_ACCESS_CHANGE, 'f', "flag_change", _("Allowed to modify the access list") },
{ CA_ACCESS_LIST, 'l', "flag_list", _("Allowed to view the access list") },
{ CA_AKICK, 'K', "flag_akick", _("Allowed to use AKICK command") },
{ CA_ASSIGN, 's', "flag_assign", _("Allowed to assign/unassign a bot") },
{ CA_AUTOHALFOP, 'H', "flag_autohalfop", _("Automatic mode +h") },
{ CA_AUTOOP, 'O', "flag_autoop", _("Automatic channel operator status") },
{ CA_AUTOOWNER, 'Q', "flag_autoowner", _("Automatic mode +q") },
{ CA_AUTOPROTECT, 'A', "flag_autoprotect", _("Automatic mode +a") },
{ CA_AUTOVOICE, 'V', "flag_autovoice", _("Automatic mode +v") },
{ CA_BADWORDS, 'k', "flag_badwords", _("Allowed to modify channel badwords list") },
{ CA_BAN, 'b', "flag_ban", _("Allowed to use ban users") },
{ CA_FANTASIA, 'c', "flag_fantasia", _("Allowed to use fantasy commands") },
{ CA_FOUNDER, 'F', "flag_founder", _("Allowed to issue commands restricted to channel founders") },
{ CA_GETKEY, 'G', "flag_getkey", _("Allowed to use GETKEY command") },
{ CA_GREET, 'g', "flag_greet", _("Greet message displayed") },
{ CA_HALFOP, 'h', "flag_halfop", _("Allowed to (de)halfop users") },
{ CA_HALFOPME, 'h', "flag_halfopme", _("Allowed to (de)halfop him/herself") },
{ CA_INFO, 'I', "flag_info", _("Allowed to use INFO command with ALL option") },
{ CA_INVITE, 'i', "flag_invite", _("Allowed to use the INVITE command") },
{ CA_KICK, 'k', "flag_kick", _("Allowed to use the KICK command") },
{ CA_MEMO, 'm', "flag_memo", _("Allowed to read channel memos") },
{ CA_MODE, 's', "flag_mode", _("Allowed to change channel modes") },
{ CA_NOKICK, 'N', "flag_nokick", _("Prevents users being kicked by Services") },
{ CA_OPDEOP, 'o', "flag_opdeop", _("Allowed to (de)op users") },
{ CA_OPDEOPME, 'o', "flag_opdeopme", _("Allowed to (de)op him/herself") },
{ CA_OWNER, 'q', "flag_owner", _("Allowed to use (de)owner users") },
{ CA_OWNERME, 'q', "flag_ownerme", _("Allowed to (de)owner him/herself") },
{ CA_PROTECT, 'a', "flag_protect", _("Allowed to (de)protect users") },
{ CA_PROTECTME, 'a', "flag_protectme", _("Allowed to (de)protect him/herself"), },
{ CA_SAY, 'B', "flag_say", _("Allowed to use SAY and ACT commands") },
{ CA_SET, 's', "flag_set", _("Allowed to set channel settings") },
{ CA_SIGNKICK, 'K', "flag_signkick", _("Prevents kicks from being signed") },
{ CA_TOPIC, 't', "flag_topic", _("Allowed to change channel topics") },
{ CA_UNBAN, 'u', "flag_unban", _("Allowed to unban users") },
{ CA_VOICE, 'v', "flag_voice", _("Allowed to (de)voice users") },
{ CA_VOICEME, 'v', "flag_voiceme", _("Allowed to (de)voice him/herself") },
{ CA_SIZE, -1, "", "" }
};
class FlagsChanAccess : public ChanAccess
{
public:
std::set<char> flags;
FlagsChanAccess(AccessProvider *p) : ChanAccess(p)
{
}
bool Matches(User *u, NickCore *nc)
{
if (u && this->mask.find_first_of("!@?*") != Anope::string::npos && (Anope::Match(u->nick, this->mask) || Anope::Match(u->GetMask(), this->mask)))
return true;
else if (nc && Anope::Match(nc->display, this->mask))
return true;
return false;
}
bool HasPriv(ChannelAccess priv)
{
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
if (flagLevels[i].priv == priv)
return this->flags.count(flagLevels[i].default_char);
return false;
}
Anope::string Serialize()
{
return Anope::string(this->flags.begin(), this->flags.end());
}
void Unserialize(const Anope::string &data)
{
for (unsigned i = data.length(); i > 0; --i)
this->flags.insert(data[i - 1]);
}
static Anope::string DetermineFlags(ChanAccess *access)
{
if (access->provider->name == "access/flags")
return access->Serialize();
std::set<char> buffer;
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
{
FlagLevels &l = flagLevels[i];
if (access->HasPriv(l.priv))
buffer.insert(l.default_char);
}
return Anope::string(buffer.begin(), buffer.end());
}
};
class FlagsAccessProvider : public AccessProvider
{
public:
FlagsAccessProvider(Module *o) : AccessProvider(o, "access/flags")
{
}
ChanAccess *Create()
{
return new FlagsChanAccess(this);
}
};
class CommandCSFlags : public Command
{
void DoModify(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string mask = params.size() > 2 ? params[2] : "";
Anope::string flags = params.size() > 3 ? params[3] : "";
if (flags.empty())
{
this->OnSyntaxError(source, "");
return;
}
AccessGroup u_access = ci->AccessFor(u);
if (mask.find_first_of("!*@") == Anope::string::npos && findnick(mask) == NULL)
mask += "!*@*";
ChanAccess *current = NULL;
std::set<char> current_flags;
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
ChanAccess *access = ci->GetAccess(i - 1);
if (mask.equals_ci(access->mask))
{
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;
}
}
if (ci->GetAccessCount() >= Config->CSAccessMax)
{
source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
return;
}
bool override = false;
int add = -1;
for (size_t i = 0; i < flags.length(); ++i)
{
char f = flags[i];
switch (f)
{
case '+':
add = 1;
break;
case '-':
add = 0;
break;
case '*':
if (add == -1)
break;
for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
{
FlagLevels &l = flagLevels[j];
if (!u_access.HasPriv(l.priv))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
else
continue;
}
if (add == 1)
current_flags.insert(l.default_char);
else if (add == 0)
current_flags.erase(l.default_char);
}
break;
default:
if (add == -1)
break;
for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
{
FlagLevels &l = flagLevels[j];
if (f != l.default_char)
continue;
else if (!u_access.HasPriv(l.priv))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
else
{
source.Reply(_("You can not set the \002%c\002 flag."), f);
continue;
}
}
if (add == 1)
current_flags.insert(f);
else if (add == 0)
current_flags.erase(f);
break;
}
}
}
if (current_flags.empty())
{
if (current != NULL)
{
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, current));
ci->EraseAccess(current);
source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str());
}
else
{
source.Reply(_("Insufficient flags given"));
}
return;
}
service_reference<AccessProvider> provider("access/flags");
if (!provider)
return;
FlagsChanAccess *access = debug_cast<FlagsChanAccess *>(provider->Create());
access->ci = ci;
access->mask = mask;
access->creator = u->nick;
access->last_seen = current ? current->last_seen : 0;
access->created = Anope::CurTime;
access->flags = current_flags;
if (current != NULL)
ci->EraseAccess(current);
ci->AddAccess(access);
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "MODIFY " << mask << " with flags " << access->Serialize();
source.Reply(_("Access for \002%s\002 on %s set to +\002%s\002"), access->mask.c_str(), ci->name.c_str(), access->Serialize().c_str());
return;
}
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());
else
{
unsigned total = 0;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
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;
}
if (++total == 1)
{
source.Reply(_("Flags list for %s"), ci->name.c_str());
}
source.Reply(_(" %3d %-10s +%-10s [last modified on %s by %s]"), i + 1, access->mask.c_str(), FlagsChanAccess::DetermineFlags(access).c_str(), do_strftime(access->created, source.u->Account(), true).c_str(), access->creator.c_str());
}
if (total == 0)
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else if (total == ci->GetAccessCount())
source.Reply(_("End of access list."));
else
source.Reply(_("End of access list - %d/%d entries shown."), total, ci->GetAccessCount());
}
}
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else
{
ci->ClearAccess();
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
}
return;
}
public:
CommandCSFlags(Module *creator) : Command(creator, "chanserv/flags", 2, 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\002"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &cmd = params[1];
User *u = source.u;
ChannelInfo *ci = cs_findchan(chan);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
bool is_list = cmd.equals_ci("LIST");
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
has_access = true;
else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
has_access = true;
if (!has_access)
source.Reply(ACCESS_DENIED);
else if (readonly && !is_list)
source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
else if (cmd.equals_ci("MODIFY"))
this->DoModify(source, ci, params);
else if (cmd.equals_ci("LIST"))
this->DoList(source, ci, params);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(source, ci);
else
this->OnSyntaxError(source, cmd);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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 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 up what you already have."));
source.Reply(" ");
source.Reply(_("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."));
source.Reply(" ");
source.Reply(_("The CLEAR command clears the channel access list, which requires channel founder."));
source.Reply(" ");
source.Reply(_("The available flags are:"));
std::multimap<char, FlagLevels *, std::less<ci::string> > levels;
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
levels.insert(std::make_pair(flagLevels[i].default_char, &flagLevels[i]));
for (std::multimap<char, FlagLevels *, std::less<ci::string> >::iterator it = levels.begin(), it_end = levels.end(); it != it_end; ++it)
{
FlagLevels *l = it->second;
source.Reply(" %c - %s", l->default_char, translate(source.u->Account(), l->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, CORE),
accessprovider(this), commandcsflags(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&accessprovider);
ModuleManager::RegisterService(&commandcsflags);
Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, 1);
this->OnReload();
}
void OnReload()
{
ConfigReader config;
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
{
FlagLevels &l = flagLevels[i];
const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
if (value.empty())
continue;
l.default_char = value[0];
}
}
};
MODULE_INIT(CSFlags)
@@ -16,50 +16,52 @@
class CommandCSGetKey : public Command
{
public:
CommandCSGetKey() : Command("GETKEY", 1, 1)
CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
{
this->SetDesc(_("Returns the key of the given channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
{
source.Reply(ACCESS_DENIED);
return;
}
Anope::string key;
if (!ci->c || !ci->c->GetParam(CMODE_KEY, key))
{
source.Reply(_("The channel \002%s\002 has no key."), chan.c_str());
return MOD_CONT;
return;
}
bool override = !check_access(u, ci, CA_GETKEY);
bool override = !ci->AccessFor(u).HasPriv(CA_GETKEY);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002GETKEY \037channel\037\002\n"
" \n"
"Returns the key of the given channel."));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Returns the key of the given channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "GETKEY", _("GETKEY \037channel\037"));
}
};
class CSGetKey : public Module
@@ -67,12 +69,11 @@ class CSGetKey : public Module
CommandCSGetKey commandcsgetkey;
public:
CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsgetkey(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsgetkey);
ModuleManager::RegisterService(&commandcsgetkey);
}
};
@@ -27,45 +27,41 @@ class CommandCSInfo : public Command
}
public:
CommandCSInfo() : Command("INFO", 1, 2)
CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
this->SetDesc(_("Lists information about the named registered channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex");
bool show_all = false;
if (ci->HasFlag(CI_FORBIDDEN))
{
if (u->HasMode(UMODE_OPER) && !ci->forbidby.empty())
source.Reply(_(CHAN_X_FORBIDDEN_OPER), chan.c_str(), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
else
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
/* Should we show all fields? Only for sadmins and identified users */
if (has_auspex || check_access(u, ci, CA_INFO))
if (has_auspex || ci->AccessFor(u).HasPriv(CA_INFO))
show_all = true;
source.Reply(_(CHAN_INFO_HEADER), chan.c_str());
source.Reply(_(" Founder: %s"), ci->founder->display.c_str());
source.Reply(CHAN_INFO_HEADER, chan.c_str());
if (ci->GetFounder())
source.Reply(_(" Founder: %s"), ci->GetFounder()->display.c_str());
if (show_all && ci->successor)
source.Reply(_(" Successor: %s"), ci->successor->display.c_str());
source.Reply(_(" Description: %s"), ci->desc.c_str());
if (!ci->desc.empty())
source.Reply(_(" Description: %s"), ci->desc.c_str());
source.Reply(_(" Registered: %s"), do_strftime(ci->time_registered).c_str());
source.Reply(_(" Last used: %s"), do_strftime(ci->last_used).c_str());
@@ -94,40 +90,39 @@ class CommandCSInfo : public Command
else
CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, _("Signed kicks"), ci, u->Account());
CheckOptStr(optbuf, CI_TOPICLOCK, _("Topic Lock"), ci, u->Account());
CheckOptStr(optbuf, CI_XOP, _("xOP lists system"), ci, u->Account());
CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, u->Account());
CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, u->Account());
source.Reply(_(NICK_INFO_OPTIONS), optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(_(" Mode lock: %s"), get_mlock_modes(ci, 1).c_str());
source.Reply(_(" Options: %s"), optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(_(" Mode lock: %s"), ci->GetMLockAsString(true).c_str());
if (!ci->HasFlag(CI_NO_EXPIRE))
source.Reply(_(" Expires on: %s"), do_strftime(ci->last_used + Config->CSExpire).c_str());
}
if (ci->HasFlag(CI_SUSPENDED))
source.Reply(_(" Suspended: [%s] %s"), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
{
Anope::string by, reason;
ci->GetExtRegular("suspend_by", by);
ci->GetExtRegular("suspend_reason", reason);
source.Reply(_(" Suspended: [%s] %s"), by.c_str(), !reason.empty() ? reason.c_str() : NO_REASON);
}
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INFO \037channel\037\002\n"
" \n"
"Lists information about the named registered channel,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists information about the named registered channel,\n"
"including its founder, time of registration, last time\n"
"used, description, and mode lock, if any. If \002ALL\002 is \n"
"specified, the entry message and successor will also \n"
"be displayed."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INFO", _("INFO \037channel\037"));
}
};
class CSInfo : public Module
@@ -135,12 +130,12 @@ class CSInfo : public Module
CommandCSInfo commandcsinfo;
public:
CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsinfo(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsinfo);
ModuleManager::RegisterService(&commandcsinfo);
}
};
@@ -16,31 +16,36 @@
class CommandCSInvite : public Command
{
public:
CommandCSInvite() : Command("INVITE", 1, 3)
CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
{
this->SetDesc(_("Tells ChanServ to invite you into a channel"));
this->SetDesc(_("Invites you into a channel"));
this->SetSyntax(_("\037channel\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Channel *c = findchan(chan);
if (!(c = findchan(chan)))
if (!c)
{
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
return MOD_CONT;
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
ci = c->ci;
if (!check_access(u, ci, CA_INVITE))
ChannelInfo *ci = c->ci;
if (!ci)
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
if (!ci->AccessFor(u).HasPriv(CA_INVITE))
{
source.Reply(ACCESS_DENIED);
return;
}
User *u2;
@@ -50,8 +55,8 @@ class CommandCSInvite : public Command
{
if (!(u2 = finduser(params[1])))
{
source.Reply(_(NICK_X_NOT_IN_USE), params[1].c_str());
return MOD_CONT;
source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
return;
}
}
@@ -62,28 +67,23 @@ class CommandCSInvite : public Command
source.Reply(_("You are already in \002%s\002! "), c->name.c_str());
else
{
ircdproto->SendInvite(whosends(ci), chan, u2->nick);
ircdproto->SendInvite(ci->WhoSends(), chan, u2->nick);
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
u2->SendMessage(whosends(ci), _("You have been invited to \002%s\002."), c->name.c_str());
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002INVITE \037channel\037\002\n"
" \n"
"Tells %s to invite you into the given channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Tells %s to invite you into the given channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."), ChanServ->nick.c_str());
"on the channel."), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "INVITE", _("INVITE \037channel\037"));
}
};
class CSInvite : public Module
@@ -91,12 +91,11 @@ class CSInvite : public Module
CommandCSInvite commandcsinvite;
public:
CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsinvite(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsinvite);
ModuleManager::RegisterService(&commandcsinvite);
}
};
+91
View File
@@ -0,0 +1,91 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSKick : public Command
{
public:
CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
{
this->SetDesc(_("Kicks a selected nick from a channel"));
this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
Channel *c = findchan(params[0]);
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
AccessGroup u_access = ci->AccessFor(u), u2_access = ci->AccessFor(u2);
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!ci)
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
else if (!ci->AccessFor(u).HasPriv(CA_KICK))
source.Reply(ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_access >= u_access)
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
{
// XXX
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
ci->c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
ci->c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Kicks a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
};
class CSKick : public Module
{
CommandCSKick commandcskick;
public:
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcskick(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcskick);
}
};
MODULE_INIT(CSKick)
@@ -12,33 +12,26 @@
/*************************************************************************/
#include "module.h"
#include "hashcomp.h"
class CommandCSList : public Command
{
public:
CommandCSList() : Command("LIST", 1, 2)
CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Lists all registered channels matching the given pattern"));
this->SetSyntax(_("\037pattern\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
Anope::string pattern = params[0];
unsigned nchans;
char buf[BUFSIZE];
bool is_servadmin = u->HasCommand("chanserv/list");
int count = 0, from = 0, to = 0;
bool forbidden = false, suspended = false, channoexpire = false;
if (Config->CSListOpersOnly && !u->HasMode(UMODE_OPER))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
bool suspended = false, channoexpire = false;
if (pattern[0] == '#')
{
@@ -52,10 +45,10 @@ class CommandCSList : public Command
}
catch (const ConvertException &)
{
source.Reply(_(LIST_INCORRECT_RANGE));
source.Reply(LIST_INCORRECT_RANGE);
source.Reply(_("To search for channels starting with #, search for the channel\n"
"name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
return MOD_CONT;
return;
}
pattern = "*";
@@ -69,8 +62,6 @@ class CommandCSList : public Command
spacesepstream keywords(params[1]);
while (keywords.GetToken(keyword))
{
if (keyword.equals_ci("FORBIDDEN"))
forbidden = true;
if (keyword.equals_ci("SUSPENDED"))
suspended = true;
if (keyword.equals_ci("NOEXPIRE"))
@@ -80,15 +71,13 @@ class CommandCSList : public Command
Anope::string spattern = "#" + pattern;
source.Reply(_(LIST_HEADER), pattern.c_str());
source.Reply(LIST_HEADER, pattern.c_str());
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
{
ChannelInfo *ci = it->second;
if (!is_servadmin && (ci->HasFlag(CI_PRIVATE) || ci->HasFlag(CI_FORBIDDEN) || ci->HasFlag(CI_SUSPENDED)))
continue;
if (forbidden && !ci->HasFlag(CI_FORBIDDEN))
if (!is_servadmin && (ci->HasFlag(CI_PRIVATE) || ci->HasFlag(CI_SUSPENDED)))
continue;
else if (suspended && !ci->HasFlag(CI_SUSPENDED))
continue;
@@ -103,38 +92,32 @@ class CommandCSList : public Command
if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE)))
noexpire_char = '!';
if (ci->HasFlag(CI_FORBIDDEN))
snprintf(buf, sizeof(buf), "%-20s [Forbidden]", ci->name.c_str());
else if (ci->HasFlag(CI_SUSPENDED))
snprintf(buf, sizeof(buf), "%-20s [Suspended]", ci->name.c_str());
Anope::string buf;
if (ci->HasFlag(CI_SUSPENDED))
buf = Anope::printf("%-20s [Suspended]", ci->name.c_str());
else
snprintf(buf, sizeof(buf), "%-20s %s", ci->name.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
buf = Anope::printf("%-20s %s", ci->name.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
source.Reply(" %c%s", noexpire_char, buf);
source.Reply(" %c%s", noexpire_char, buf.c_str());
}
++count;
}
}
source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002LIST \037pattern\037\002\n"
" \n"
"Lists all registered channels matching the given pattern.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists all registered channels matching the given pattern.\n"
"(Channels with the \002PRIVATE\002 option set are not listed.)\n"
"Note that a preceding '#' specifies a range, channel names\n"
"are to be written without '#'."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX));
}
};
class CSList : public Module
@@ -142,12 +125,11 @@ class CSList : public Module
CommandCSList commandcslist;
public:
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcslist(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcslist);
ModuleManager::RegisterService(&commandcslist);
}
};
@@ -20,15 +20,15 @@ class CommandCSMode : public Command
switch (mode)
{
case CMODE_OWNER:
return check_access(u, ci, CA_OWNER);
return ci->AccessFor(u).HasPriv(CA_OWNER);
case CMODE_PROTECT:
return check_access(u, ci, CA_PROTECT);
return ci->AccessFor(u).HasPriv(CA_PROTECT);
case CMODE_OP:
return check_access(u, ci, CA_OPDEOP);
return ci->AccessFor(u).HasPriv(CA_OPDEOP);
case CMODE_HALFOP:
return check_access(u, ci, CA_HALFOP);
return ci->AccessFor(u).HasPriv(CA_HALFOP);
case CMODE_VOICE:
return check_access(u, ci, CA_VOICE);
return ci->AccessFor(u).HasPriv(CA_VOICE);
default:
break;
}
@@ -36,10 +36,9 @@ class CommandCSMode : public Command
return false;
}
void DoLock(CommandSource &source, const std::vector<Anope::string> &params)
void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &subcommand = params[2];
const Anope::string &param = params.size() > 3 ? params[3] : "";
@@ -158,10 +157,9 @@ class CommandCSMode : public Command
this->OnSyntaxError(source, subcommand);
}
void DoSet(CommandSource &source, const std::vector<Anope::string> &params)
void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
spacesepstream sep(params.size() > 3 ? params[3] : "");
Anope::string modes = params[2], param;
@@ -230,8 +228,7 @@ class CommandCSMode : public Command
break;
}
ChanAccess *u_access = ci->GetAccess(u);
int16 u_level = u_access ? u_access->level : 0;
AccessGroup u_access = ci->AccessFor(u);
if (str_is_wildcard(param))
{
@@ -239,10 +236,9 @@ class CommandCSMode : public Command
{
UserContainer *uc = *it;
ChanAccess *targ_access = ci->GetAccess(uc->user);
int16 t_level = targ_access ? targ_access->level : 0;
AccessGroup targ_access = ci->AccessFor(uc->user);
if (t_level > u_level)
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
continue;
@@ -262,9 +258,8 @@ class CommandCSMode : public Command
User *target = finduser(param);
if (target != NULL)
{
ChanAccess *targ_access = ci->GetAccess(target);
int16 t_level = targ_access ? targ_access->level : 0;
if (t_level > u_level)
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
@@ -300,38 +295,39 @@ class CommandCSMode : public Command
}
public:
CommandCSMode() : Command("MODE", 3, 4)
CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 3, 4)
{
this->SetDesc(_("Control modes and mode locks on a channel"));
this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]"));
this->SetSyntax(_("\037channel\037 SET \037modes\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &subcommand = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
ChannelInfo *ci = cs_findchan(params[0]);
if (!ci || !ci->c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/mode"))
source.Reply(_(ACCESS_DENIED));
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!ci->AccessFor(u).HasPriv(CA_MODE) && !u->HasCommand("chanserv/mode"))
source.Reply(ACCESS_DENIED);
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, params);
this->DoLock(source, ci, params);
else if (subcommand.equals_ci("SET"))
this->DoSet(source, params);
this->DoSet(source, ci, params);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002MODE \037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]\002\n"
" \002MODE \037channel\037 SET \037modes\037\002\n"
" \n"
"Mainly controls mode locks and mode access (which is different from channel access)\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Mainly controls mode locks and mode access (which is different from channel access)\n"
"on a channel.\n"
" \n"
"The \002MODE LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
@@ -349,11 +345,6 @@ class CommandCSMode : public Command
" Clears all extended bans that start with ~c:"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "MODE", _("MODE \037channel\037 {LOCK|SET} [\037modes\037 | {ADD|DEL|LIST} [\037what\037]]"));
}
};
class CSMode : public Module
@@ -361,12 +352,12 @@ class CSMode : public Module
CommandCSMode commandcsmode;
public:
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsmode(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsmode);
ModuleManager::RegisterService(&commandcsmode);
}
};
@@ -13,9 +13,46 @@
#include "module.h"
class CommandModeBase : public Command
{
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself, ChannelInfoFlag notice)
{
User *u = source.u;
User *u2 = finduser(nick);
Channel *c = findchan(chan);
ChannelInfo *ci = c ? c->ci : NULL;
bool is_same = u == u2;
AccessGroup u_access = ci ? ci->AccessFor(u) : AccessGroup(), u2_access = ci && u2 ? ci->AccessFor(u2) : AccessGroup();
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!ci)
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
else if (is_same ? !ci->AccessFor(u).HasPriv(levelself) : !ci->AccessFor(u).HasPriv(level))
source.Reply(ACCESS_DENIED);
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
else if (!set && u2->IsProtected() && !is_same)
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else
{
if (set)
c->SetMode(NULL, cm, u2->nick);
else
c->RemoveMode(NULL, cm, u2->nick);
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
ircdproto->SendMessage(ci->WhoSends(), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
}
}
protected:
/** do_util: not a command, but does the job of others
* @param source The source of the command
@@ -28,7 +65,7 @@ class CommandModeBase : public Command
* @param levelself The access level required to set this mode on yourself
* @param notice Flag required on a channel to send a notice
*/
CommandReturn do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself, ChannelInfoFlag notice)
{
User *u = source.u;
@@ -38,62 +75,25 @@ class CommandModeBase : public Command
else
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself, notice);
return MOD_CONT;
return;
}
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
{
User *u = source.u;
User *u2 = finduser(nick);
Channel *c = findchan(chan);
ChannelInfo *ci = c ? c->ci : NULL;
bool is_same = u == u2;
ChanAccess *u_access = ci ? ci->GetAccess(u) : NULL, *u2_access = ci && u2 ? ci->GetAccess(u2) : NULL;
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!ci)
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str());
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
source.Reply(_(ACCESS_DENIED));
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
else if (!set && u2->IsProtected() && !is_same)
source.Reply(_(ACCESS_DENIED));
else if (!c->FindUser(u2))
source.Reply(_(NICK_X_NOT_ON_CHAN), u2->nick.c_str(), c->name.c_str());
else
{
if (set)
c->SetMode(NULL, cm, u2->nick);
else
c->RemoveMode(NULL, cm, u2->nick);
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
}
}
public:
CommandModeBase(const Anope::string &cname) : Command(cname, 0, 2) { }
CommandModeBase(Module *creator, const Anope::string &cname) : Command(creator, cname, 0, 2)
{
this->SetSyntax(_("[\037#channel\037] [\037nick\037]"));
}
};
class CommandCSOp : public CommandModeBase
{
public:
CommandCSOp() : CommandModeBase("OP")
CommandCSOp(Module *creator) : CommandModeBase(creator, "chanserv/op")
{
this->SetDesc(_("Gives Op status to a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
@@ -102,9 +102,9 @@ class CommandCSOp : public CommandModeBase
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002OP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Ops a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Ops a selected nick on a channel. If nick is not given,\n"
"it will op you. If channel is not given, it will op you\n"
"on every channel.\n"
" \n"
@@ -112,22 +112,17 @@ class CommandCSOp : public CommandModeBase
"and above on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "OP", _("OP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeOp : public CommandModeBase
{
public:
CommandCSDeOp() : CommandModeBase("DEOP")
CommandCSDeOp(Module *creator) : CommandModeBase(creator, "chanserv/deop")
{
this->SetDesc(_("Deops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
@@ -136,32 +131,27 @@ class CommandCSDeOp : public CommandModeBase
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Deops a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply("Deops a selected nick on a channel. If nick is not given,\n"
"it will deop you. If channel is not given, it will deop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
"and above on the channel.");
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEOP", _("DEOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSVoice : public CommandModeBase
{
public:
CommandCSVoice() : CommandModeBase("VOICE")
CommandCSVoice(Module *creator) : CommandModeBase(creator, "chanserv/voice")
{
this->SetDesc(_("Voices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
@@ -170,9 +160,9 @@ class CommandCSVoice : public CommandModeBase
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002VOICE [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Voices a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Voices a selected nick on a channel. If nick is not given,\n"
"it will voice you. If channel is not given, it will voice you\n"
"on every channel.\n"
" \n"
@@ -181,22 +171,17 @@ class CommandCSVoice : public CommandModeBase
"and above for self voicing."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "VOICE", _("VOICE [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeVoice : public CommandModeBase
{
public:
CommandCSDeVoice() : CommandModeBase("DEVOICE")
CommandCSDeVoice(Module *creator) : CommandModeBase(creator, "chanserv/devoice")
{
this->SetDesc(_("Devoices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
@@ -205,9 +190,9 @@ class CommandCSDeVoice : public CommandModeBase
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEVOICE [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Devoices a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Devoices a selected nick on a channel. If nick is not given,\n"
"it will devoice you. If channel is not given, it will devoice\n"
"you on every channel.\n"
" \n"
@@ -216,36 +201,31 @@ class CommandCSDeVoice : public CommandModeBase
"and above for self devoicing."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEVOICE", _("DEVOICE [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSHalfOp : public CommandModeBase
{
public:
CommandCSHalfOp() : CommandModeBase("HALFOP")
CommandCSHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/halfop")
{
this->SetDesc(_("Halfops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002HALFOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Halfops a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Halfops a selected nick on a channel. If nick is not given,\n"
"it will halfop you. If channel is not given, it will halfop\n"
"you on every channel.\n"
" \n"
@@ -253,36 +233,31 @@ class CommandCSHalfOp : public CommandModeBase
"and above on the channel, or to HOPs or those with level 4 \n"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "HALFOP", _("HALFOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeHalfOp : public CommandModeBase
{
public:
CommandCSDeHalfOp() : CommandModeBase("DEHALFOP")
CommandCSDeHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/dehalfop")
{
this->SetDesc(_("Dehalfops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEHALFOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Dehalfops a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Dehalfops a selected nick on a channel. If nick is not given,\n"
"it will dehalfop you. If channel is not given, it will dehalfop\n"
"you on every channel.\n"
" \n"
@@ -291,36 +266,31 @@ class CommandCSDeHalfOp : public CommandModeBase
"and above for self dehalfopping."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEHALFOP", _("DEHALFOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSProtect : public CommandModeBase
{
public:
CommandCSProtect() : CommandModeBase("PROTECT")
CommandCSProtect(Module *creator) : CommandModeBase(creator, "chanserv/protect")
{
this->SetDesc(_("Protects a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002PROTECT [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Protects a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Protects a selected nick on a channel. If nick is not given,\n"
"it will protect you. If channel is not given, it will protect\n"
"you on every channel.\n"
" \n"
@@ -328,119 +298,99 @@ class CommandCSProtect : public CommandModeBase
"level 10 and above on the channel for self protecting."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "PROTECT", _("PROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeProtect : public CommandModeBase
{
public:
CommandCSDeProtect() : CommandModeBase("DEPROTECT")
CommandCSDeProtect(Module *creator) : CommandModeBase(creator, "chanserv/deprotect")
{
this->SetDesc(_("Deprotects a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEPROTECT [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Deprotects a selected nick on a channel. If nick is not given,\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deprotects a selected nick on a channel. If nick is not given,\n"
"it will deprotect you. If channel is not given, it will deprotect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with \n"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEPROTECT", _("DEROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSOwner : public CommandModeBase
{
public:
CommandCSOwner() : CommandModeBase("OWNER")
CommandCSOwner(Module *creator) : CommandModeBase(module, "chanserv/owner")
{
this->SetDesc(_("Gives you owner status on channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002OWNER [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Gives the selected nick owner status on \002channel\002. If nick is not\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Gives the selected nick owner status on \002channel\002. If nick is not\n"
"given, it will give you owner. If channel is not given, it will\n"
"give you owner on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "OWNER", _("OWNER [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeOwner : public CommandModeBase
{
public:
CommandCSDeOwner() : CommandModeBase("DEOWNER")
CommandCSDeOwner(Module *creator) : CommandModeBase(creator, "chanserv/deowner")
{
this->SetDesc(_("Removes your owner status on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEOWNER [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Removes owner status from the selected nick on \002channel\002. If nick\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Removes owner status from the selected nick on \002channel\002. If nick\n"
"is not given, it will deowner you. If channel is not given, it will\n"
"deowner you on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEOWNER", _("DEOWNER [\037#channel\037] [\037nick\037]\002"));
}
};
class CSModes : public Module
@@ -457,52 +407,24 @@ class CSModes : public Module
CommandCSDeVoice commandcsdevoice;
public:
CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsowner(this), commandcsdeowner(this), commandcsprotect(this), commandcsdeprotect(this),
commandcsop(this), commandcsdeop(this), commandcshalfop(this), commandcsdehalfop(this),
commandcsvoice(this), commandcsdevoice(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsop);
this->AddCommand(ChanServ, &commandcsdeop);
this->AddCommand(ChanServ, &commandcsvoice);
this->AddCommand(ChanServ, &commandcsdevoice);
if (Me && Me->IsSynced())
OnUplinkSync(NULL);
Implementation i[] = {I_OnUplinkSync, I_OnServerDisconnect};
ModuleManager::Attach(i, this, 2);
}
void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
{
this->AddCommand(ChanServ, &commandcsowner);
this->AddCommand(ChanServ, &commandcsdeowner);
}
if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
{
this->AddCommand(ChanServ, &commandcsprotect);
this->AddCommand(ChanServ, &commandcsdeprotect);
}
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
{
this->AddCommand(ChanServ, &commandcshalfop);
this->AddCommand(ChanServ, &commandcsdehalfop);
}
}
void OnServerDisconnect()
{
this->DelCommand(ChanServ, &commandcsowner);
this->DelCommand(ChanServ, &commandcsdeowner);
this->DelCommand(ChanServ, &commandcsprotect);
this->DelCommand(ChanServ, &commandcsdeprotect);
this->DelCommand(ChanServ, &commandcshalfop);
this->DelCommand(ChanServ, &commandcsdehalfop);
ModuleManager::RegisterService(&commandcsop);
ModuleManager::RegisterService(&commandcsdeop);
ModuleManager::RegisterService(&commandcsvoice);
ModuleManager::RegisterService(&commandcsdevoice);
ModuleManager::RegisterService(&commandcsowner);
ModuleManager::RegisterService(&commandcsdeowner);
ModuleManager::RegisterService(&commandcsprotect);
ModuleManager::RegisterService(&commandcsdeprotect);
ModuleManager::RegisterService(&commandcshalfop);
ModuleManager::RegisterService(&commandcsdehalfop);
}
};
@@ -16,20 +16,20 @@
class CommandCSRegister : public Command
{
public:
CommandCSRegister() : Command("REGISTER", 2, 2)
CommandCSRegister(Module *creator) : Command(creator, "chanserv/register", 1, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
this->SetDesc(_("Register a channel"));
this->SetSyntax(_("\037channel\037 [\037description\037]"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
const Anope::string &chdesc = params[1];
const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = findchan(chan);
Channel *c = findchan(params[0]);
ChannelInfo *ci = cs_findchan(params[0]);
if (readonly)
source.Reply(_("Sorry, channel registration is temporarily disabled."));
@@ -38,20 +38,24 @@ class CommandCSRegister : public Command
else if (chan[0] == '&')
source.Reply(_("Local channels cannot be registered."));
else if (chan[0] != '#')
source.Reply(_(CHAN_SYMBOL_REQUIRED));
source.Reply(CHAN_SYMBOL_REQUIRED);
else if (!ircdproto->IsChannelValid(chan))
source.Reply(_(CHAN_X_INVALID), chan.c_str());
source.Reply(CHAN_X_INVALID, chan.c_str());
else if (ci)
source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
else if (c && !c->HasUserStatus(u, CMODE_OP))
source.Reply(_("You must be a channel operator to register the channel."));
else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
else
{
ci = new ChannelInfo(chan);
ci->founder = u->Account();
ci->desc = chdesc;
ci->SetFounder(u->Account());
if (!chdesc.empty())
ci->desc = chdesc;
for (ChannelInfo::ModeList::iterator it = ci->mode_locks.begin(), it_end = ci->mode_locks.end(); it != it_end; ++it)
it->second.setter = u->nick;
if (c && !c->topic.empty())
{
@@ -60,10 +64,9 @@ class CommandCSRegister : public Command
ci->last_topic_time = c->topic_time;
}
else
ci->last_topic_setter = Config->s_ChanServ;
ci->last_topic_setter = source.owner->nick;
ci->bi = NULL;
++ci->founder->channelcount;
Log(LOG_COMMAND, u, this, ci);
source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str());
@@ -82,7 +85,7 @@ class CommandCSRegister : public Command
c->RemoveMode(NULL, cm, u->nick);
}
/* Mark the channel as persistant */
/* Mark the channel as persistent */
if (c->HasMode(CMODE_PERM))
ci->SetFlag(CI_PERSIST);
/* Persist may be in def cflags, set it here */
@@ -92,17 +95,17 @@ class CommandCSRegister : public Command
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci));
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002REGISTER \037channel\037 \037description\037\002\n"
" \n"
"Registers a channel in the %s database. In order\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Registers a channel in the %s database. In order\n"
"to use this command, you must first be a channel operator\n"
"on the channel you're trying to register.\n"
"The description, which \002must\002 be included, is a\n"
"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"
@@ -117,27 +120,78 @@ class CommandCSRegister : public Command
"NOTICE: In order to register a channel, you must have\n"
"first registered your nickname. If you haven't,\n"
"\002%s%s HELP\002 for information on how to do so."),
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
source.owner->nick.c_str(), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
class ExpireCallback : public CallBack
{
public:
ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
void Tick(time_t)
{
SyntaxError(source, "REGISTER", _("REGISTER \037channel\037 \037description\037"));
if (!Config->CSExpire || noexpire || readonly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; )
{
ChannelInfo *ci = it->second;
++it;
bool expire = false;
if (ci->HasFlag(CI_SUSPENDED))
{
if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire)
expire = true;
}
else if (!ci->c && Config->CSExpire && Anope::CurTime - ci->last_used >= Config->CSExpire)
expire = true;
if (ci->HasFlag(CI_NO_EXPIRE))
expire = false;
if (expire)
{
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
if (MOD_RESULT == EVENT_STOP)
continue;
Anope::string extra;
if (ci->HasFlag(CI_SUSPENDED))
extra = "suspended ";
Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci));
delete ci;
}
}
}
};
class CSRegister : public Module
{
CommandCSRegister commandcsregister;
ExpireCallback ecb;
public:
CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsregister(this), ecb(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsregister);
ModuleManager::RegisterService(&commandcsregister);
ModuleManager::Attach(I_OnDelChan, this);
}
void OnDelChan(ChannelInfo *ci)
{
if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
if (ci->c && ci->HasFlag(CI_PERSIST))
ci->c->RemoveMode(NULL, CMODE_PERM, "", false);
}
};
+74
View File
@@ -0,0 +1,74 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSSASet : public Command
{
public:
CommandCSSASet(Module *creator) : Command(creator, "chanserv/saset", 2, 3)
{
this->SetDesc(_("Forcefully set channel options and information"));
this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
this->OnSyntaxError(source, "");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows Services Operators to forcefully change settings\n"
"on channels.\n"
" \n"
"Available options:"));
Anope::string this_name = source.command;
for (BotInfo::command_map::iterator it = source.owner->commands.begin(), it_end = source.owner->commands.end(); it != it_end; ++it)
{
const Anope::string &c_name = it->first;
CommandInfo &info = it->second;
if (c_name.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(info.name);
if (command)
{
source.command = it->first;
command->OnServHelp(source);
}
}
}
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
class CSSASet : public Module
{
CommandCSSASet commandcssaset;
public:
CSSASet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssaset(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssaset);
}
};
MODULE_INIT(CSSASet)
@@ -16,16 +16,27 @@
class CommandCSSASetNoexpire : public Command
{
public:
CommandCSSASetNoexpire() : Command("NOEXPIRE", 2, 2, "chanserv/saset/noexpire")
CommandCSSASetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2)
{
this->SetDesc(_("Prevent the channel from expiring"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSASetNoexpire");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -40,22 +51,17 @@ class CommandCSSASetNoexpire : public Command
else
this->OnSyntaxError(source, "NOEXPIRE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002SET \037channel\037 NOEXPIRE {ON | OFF}\002\n"
" \n"
"Sets whether the given channel will expire. Setting this\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Sets whether the given channel will expire. Setting this\n"
"to ON prevents the channel from expiring."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET NOEXPIRE", _("SET \037channel\037 NOEXPIRE {ON | OFF}"));
}
};
class CSSetNoexpire : public Module
@@ -63,21 +69,12 @@ class CSSetNoexpire : public Module
CommandCSSASetNoexpire commandcssasetnoexpire;
public:
CSSetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSSetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssasetnoexpire(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Command *c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetnoexpire);
}
~CSSetNoexpire()
{
Command *c = FindCommand(ChanServ, "SASET");
if (c)
c->DelSubcommand(&commandcssasetnoexpire);
ModuleManager::RegisterService(&commandcssasetnoexpire);
}
};
+429
View File
@@ -0,0 +1,429 @@
/* cs_seen: provides a seen command by tracking all users
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
enum TypeInfo
{
NEW, NICK_TO, NICK_FROM, JOIN, PART, QUIT, KICK
};
struct SeenInfo
{
Anope::string vhost;
TypeInfo type;
Anope::string nick2; // for nickchanges and kicks
Anope::string channel; // for join/part/kick
Anope::string message; // for part/kick/quit
time_t last; // the time when the user was last seen
};
class ModuleConfigClass
{
public:
time_t purgetime;
time_t expiretimeout;
};
ModuleConfigClass ModuleConfig;
typedef Anope::insensitive_map<SeenInfo *> database_map;
database_map database;
static SeenInfo *FindInfo(const Anope::string &nick)
{
database_map::iterator iter = database.find(nick);
if (iter != database.end())
return iter->second;
return NULL;
}
static bool ShouldHide(const Anope::string &channel, User *u)
{
Channel *targetchan = findchan(channel);
ChannelInfo *targetchan_ci = targetchan ? targetchan->ci : cs_findchan(channel);
if (targetchan && targetchan->HasMode(CMODE_SECRET))
return true;
else if (targetchan_ci && targetchan_ci->HasFlag(CI_PRIVATE))
return true;
else if (u && u->HasMode(UMODE_PRIV))
return true;
return false;
}
class CommandOSSeen : public Command
{
public:
CommandOSSeen(Module *creator) : Command(creator, "operserv/seen", 1, 2)
{
this->SetDesc(_("Statistics and maintenance for seen data"));
this->SetSyntax(_("\037STATS\037"));
this->SetSyntax(_("\037CLEAR\037 \037time\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
if (params[0].equals_ci("STATS"))
{
size_t mem_counter;
mem_counter = sizeof(database_map);
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end; ++it)
{
mem_counter += (5 * sizeof(Anope::string)) + sizeof(TypeInfo) + sizeof(time_t);
mem_counter += it->first.capacity();
mem_counter += it->second->vhost.capacity();
mem_counter += it->second->nick2.capacity();
mem_counter += it->second->channel.capacity();
mem_counter += it->second->message.capacity();
}
source.Reply(_("%lu nicks are stored in the database, using %.2Lf kB of memory"), database.size(), static_cast<long double>(mem_counter) / 1024);
}
else if (params[0].equals_ci("CLEAR"))
{
time_t time = 0;
if ((params.size() < 2) || (0 >= (time = dotime(params[1]))))
{
this->OnSyntaxError(source, params[0]);
return;
}
time = Anope::CurTime - time;
database_map::iterator buf;
size_t counter = 0;
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
{
buf = it;
++it;
if (time < buf->second->last)
{
Log(LOG_DEBUG) << buf->first << " was last seen " << do_strftime(buf->second->last) << ", deleting entry";
database.erase(buf);
counter++;
}
}
Log(LOG_ADMIN, source.u, this) << "CLEAR and removed " << counter << " nicks that were added after " << do_strftime(time, NULL, true);
source.Reply(_("Database cleared, removed %lu nicks that were added after %s"), counter, do_strftime(time, source.u->Account(), true).c_str());
}
else
this->SendSyntax(source);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("The \002STATS\002 command prints out statistics about stored nicks and memory usage."));
source.Reply(_("The \002CLEAR\002 command lets you clean the database by removing all entries from the\n"
"entries from the database that were added within \037time\037.\n"
" \n"
"Example:\n"
"%s CLEAR 30m\n"
"will remove all entries that were added within the last 30 minutes."), source.command.c_str());
return true;
}
};
class CommandSeen : public Command
{
public:
CommandSeen(Module *creator) : Command(creator, "chanserv/seen", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Tells you about the last time a user was seen"));
this->SetSyntax(_("\037nick\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &target = params[0];
User *u = source.u;
if (target.length() > Config->NickLen)
{
source.Reply(_("Nick too long, max length is %u chars"), Config->NickLen);
return;
}
if (findbot(target) != NULL)
{
source.Reply(_("%s is a client on services."), target.c_str());
return;
}
if (target.equals_ci(u->nick))
{
source.Reply(_("You might see yourself in the mirror, %s."), u->nick.c_str());
return;
}
SeenInfo *info = FindInfo(target);
if (!info)
{
source.Reply(_("Sorry, I have not seen %s."), target.c_str());
return;
}
User *u2 = finduser(target);
Anope::string onlinestatus;
if (u2)
onlinestatus = ".";
else
onlinestatus = Anope::printf(_(" but %s mysteriously dematerialized."), target.c_str());
Anope::string timebuf = duration(Anope::CurTime - info->last, u->Account());
Anope::string timebuf2 = do_strftime(info->last, u->Account(), true);
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());
}
else if (info->type == NICK_TO)
{
u2 = finduser(info->nick2);
if (u2)
onlinestatus = Anope::printf( _(". %s is still online."), u2->nick.c_str());
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());
}
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());
}
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());
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());
}
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());
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());
}
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());
}
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());
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());
}
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
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."));
return true;
}
};
class DataBasePurger : public CallBack
{
public:
DataBasePurger(Module *owner) : CallBack(owner, 300, Anope::CurTime, true) { }
void Tick(time_t)
{
size_t previous_size = database.size();
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
{
database_map::iterator cur = it;
++it;
if ((Anope::CurTime - cur->second->last) > ModuleConfig.purgetime)
{
Log(LOG_DEBUG) << cur->first << " was last seen " << do_strftime(cur->second->last) << ", purging entry";
delete cur->second;
database.erase(cur);
}
}
Log(LOG_DEBUG) << "cs_seen: Purged Database, checked " << previous_size << " nicks and removed " << (previous_size - database.size()) << " old entries.";
}
};
class CSSeen : public Module
{
CommandSeen commandseen;
CommandOSSeen commandosseen;
DataBasePurger purger;
public:
CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandseen(this), commandosseen(this), purger(this)
{
this->SetAuthor("Anope");
Implementation eventlist[] = { I_OnReload,
I_OnUserConnect,
I_OnUserNickChange,
I_OnUserQuit,
I_OnJoinChannel,
I_OnPartChannel,
I_OnUserKicked,
I_OnDatabaseRead,
I_OnDatabaseWrite };
ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
ModuleManager::RegisterService(&commandseen);
ModuleManager::RegisterService(&commandosseen);
OnReload();
}
void OnReload()
{
ConfigReader config;
ModuleConfig.purgetime = dotime(config.ReadValue("cs_seen", "purgetime", "30d", 0));
ModuleConfig.expiretimeout = dotime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0));
if (purger.GetSecs() != ModuleConfig.expiretimeout)
purger.SetSecs(ModuleConfig.expiretimeout);
}
void OnUserConnect(User *u)
{
UpdateUser(u, NEW, u->nick, "", "", "");
}
void OnUserNickChange(User *u, const Anope::string &oldnick)
{
UpdateUser(u, NICK_TO, oldnick, u->nick, "", "");
UpdateUser(u, NICK_FROM, u->nick, oldnick, "", "");
}
void OnUserQuit(User *u, const Anope::string &msg)
{
UpdateUser(u, QUIT, u->nick, "", "", msg);
}
void OnJoinChannel(User *u, Channel *c)
{
UpdateUser(u, JOIN, u->nick, "", c->name, "");
}
void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg)
{
UpdateUser(u, PART, u->nick, "", channel, msg);
}
void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &msg)
{
UpdateUser(target, KICK, target->nick, source, c->name, msg);
}
void UpdateUser(const User *u, const TypeInfo Type, const Anope::string &nick, const Anope::string &nick2, const Anope::string &channel, const Anope::string &message)
{
SeenInfo *info = FindInfo(nick);
if (!info)
{
info = new SeenInfo;
database.insert(std::pair<Anope::string, SeenInfo *>(nick, info));
}
info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost();
info->type = Type;
info->last = Anope::CurTime;
info->nick2 = nick2;
info->channel = channel;
info->message = message;
}
EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
{
if (params[0].equals_ci("SEEN") && (params.size() >= 5))
{
SeenInfo *info = new SeenInfo;
database.insert(std::pair<Anope::string, SeenInfo *>(params[1], info));
info->vhost = params[2];
info->last = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : 0 ;
if (params[4].equals_ci("NEW"))
{
info->type = NEW;
}
else if (params[4].equals_ci("NICK_TO") && params.size() == 6)
{
info->type = NICK_TO;
info->nick2 = params[5];
}
else if (params[4].equals_ci("NICK_FROM") && params.size() == 6)
{
info->type = NICK_FROM;
info->nick2 = params[5];
}
else if (params[4].equals_ci("JOIN") && params.size() == 6)
{
info->type = JOIN;
info->channel = params[5];
}
else if (params[4].equals_ci("PART") && params.size() == 7)
{
info->type = PART;
info->channel = params[5];
info->message = params[6];
}
else if (params[4].equals_ci("QUIT") && params.size() == 6)
{
info->type = QUIT;
info->message = params[5];
}
else if (params[4].equals_ci("KICK") && params.size() == 8)
{
info->type = KICK;
info->nick2 = params[5];
info->channel = params[6];
info->message = params[7];
}
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
void OnDatabaseWrite(void (*Write)(const Anope::string &))
{
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end; ++it)
{
std::stringstream buf;
buf << "SEEN " << it->first.c_str() << " " << it->second->vhost << " " << it->second->last << " ";
switch (it->second->type)
{
case NEW:
buf << "NEW"; break;
case NICK_TO:
buf << "NICK_TO " << it->second->nick2; break;
case NICK_FROM:
buf << "NICK_FROM " << it->second->nick2; break;
case JOIN:
buf << "JOIN " << it->second->channel; break;
case PART:
buf << "PART " << it->second->channel << " :" << it->second->message; break;
case QUIT:
buf << "QUIT :" << it->second->message; break;
case KICK:
buf << "KICK " << it->second->nick2 << " " << it->second->channel << " :" << it->second->message; break;
}
Write(buf.str());
}
}
};
MODULE_INIT(CSSeen)
+74
View File
@@ -0,0 +1,74 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
this->OnSyntaxError(source, "");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Allows the channel founder to set various channel options\n"
"and other information.\n"
" \n"
"Available options:"));
Anope::string this_name = source.command;
for (BotInfo::command_map::iterator it = source.owner->commands.begin(), it_end = source.owner->commands.end(); it != it_end; ++it)
{
const Anope::string &c_name = it->first;
CommandInfo &info = it->second;
if (c_name.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(info.name);
if (command)
{
source.command = it->first;
command->OnServHelp(source);
}
}
}
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
class CSSet : public Module
{
CommandCSSet commandcsset;
public:
CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsset(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsset);
}
};
MODULE_INIT(CSSet)
@@ -16,20 +16,34 @@
class CommandCSSetBanType : public Command
{
public:
CommandCSSetBanType(const Anope::string &cpermission = "") : Command("BANTYPE", 2, 2, cpermission)
CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2)
{
this->SetDesc(_("Set how Services make bans on the channel"));
this->SetSyntax(_("\037channel\037 \037bantype\037"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetBanType");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
try
{
ci->bantype = convertTo<int16>(params[1]);
int16 new_type = convertTo<int16>(params[1]);
if (new_type < 0 || new_type > 3)
throw ConvertException("Invalid range");
ci->bantype = new_type;
source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
}
catch (const ConvertException &)
@@ -37,14 +51,14 @@ class CommandCSSetBanType : public Command
source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
}
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 BANTYPE \037bantype\037\002\n"
" \n"
"Sets the ban type that will be used by services whenever\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Sets the ban type that will be used by services whenever\n"
"they need to ban someone from your channel.\n"
" \n"
"bantype is a number between 0 and 3 that means:\n"
@@ -55,26 +69,14 @@ class CommandCSSetBanType : public Command
"3: ban in the form *!*user@*.domain"), this->name.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
class CommandCSSASetBanType : public CommandCSSetBanType
{
public:
CommandCSSASetBanType() : CommandCSSetBanType("chanserv/saset/bantype")
CommandCSSASetBanType(Module *creator) : CommandCSSetBanType(creator, "chanserv/saset/bantype")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
class CSSetBanType : public Module
@@ -83,29 +85,13 @@ class CSSetBanType : public Module
CommandCSSASetBanType commandcssasetbantype;
public:
CSSetBanType(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSSetBanType(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetbantype(this), commandcssasetbantype(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(this, &commandcssetbantype);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetbantype);
}
~CSSetBanType()
{
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->DelSubcommand(&commandcssetbantype);
c = FindCommand(ChanServ, "SASET");
if (c)
c->DelSubcommand(&commandcssasetbantype);
ModuleManager::RegisterService(&commandcssetbantype);
ModuleManager::RegisterService(&commandcssasetbantype);
}
};
+89
View File
@@ -0,0 +1,89 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params.size() > 1)
{
ci->desc = params[1];
source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
}
else
{
ci->desc.clear();
source.Reply(_("Description of %s unset."), ci->name.c_str());
}
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
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 CommandCSSASetDescription : public CommandCSSetDescription
{
public:
CommandCSSASetDescription(Module *creator) : CommandCSSetDescription(creator, "chanserv/saset/description")
{
}
};
class CSSetDescription : public Module
{
CommandCSSetDescription commandcssetdescription;
CommandCSSASetDescription commandcssasetdescription;
public:
CSSetDescription(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetdescription(this), commandcssasetdescription(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetdescription);
ModuleManager::RegisterService(&commandcssasetdescription);
}
};
MODULE_INIT(CSSetDescription)
+105
View File
@@ -0,0 +1,105 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (source.permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER)))
{
source.Reply(ACCESS_DENIED);
return;
}
NickAlias *na = findnick(params[1]);
if (!na)
{
source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
return;
}
NickCore *nc = na->nc;
if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
return;
}
Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << "to change the founder to " << nc->display;
ci->SetFounder(nc);
source.Reply(_("Founder of %s changed to \002%s\002."), ci->name.c_str(), na->nick.c_str());
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
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 CommandCSSASetFounder : public CommandCSSetFounder
{
public:
CommandCSSASetFounder(Module *creator) : CommandCSSetFounder(creator, "chanserv/saset/founder")
{
}
};
class CSSetFounder : public Module
{
CommandCSSetFounder commandcssetfounder;
CommandCSSASetFounder commandcssasetfounder;
public:
CSSetFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetfounder(this), commandcssasetfounder(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetfounder);
ModuleManager::RegisterService(&commandcssasetfounder);
}
};
MODULE_INIT(CSSetFounder)
@@ -16,16 +16,27 @@
class CommandCSSetKeepTopic : public Command
{
public:
CommandCSSetKeepTopic(const Anope::string &cpermission = "") : Command("KEEPTOPIC", 2, 2, cpermission)
CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
{
this->SetDesc(_("Retain topic when channel is not in use"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetKeepTopic");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -40,38 +51,28 @@ class CommandCSSetKeepTopic : public Command
else
this->OnSyntaxError(source, "KEEPTOPIC");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 KEEPTOPIC {ON | OFF}\002\n"
" \n"
"Enables or disables the \002topic retention\002 option for a \n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002topic retention\002 option for a \n"
"channel. When \002topic retention\002 is set, the topic for the\n"
"channel will be remembered by %s even after the\n"
"last user leaves the channel, and will be restored the\n"
"next time the channel is created."), this->name.c_str(), ChanServ->nick.c_str());
"next time the channel is created."), this->name.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET KEEPTOPIC", _("SET \037channel\037 KEEPTOPIC {ON | OFF}"));
}
};
class CommandCSSASetKeepTopic : public CommandCSSetKeepTopic
{
public:
CommandCSSASetKeepTopic() : CommandCSSetKeepTopic("chanserv/saset/keeptopic")
CommandCSSASetKeepTopic(Module *creator) : CommandCSSetKeepTopic(creator, "chanserv/saset/keeptopic")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET KEEPTOPIC", _("SASET \002channel\002 KEEPTOPIC {ON | OFF}"));
}
};
class CSSetKeepTopic : public Module
@@ -80,29 +81,13 @@ class CSSetKeepTopic : public Module
CommandCSSASetKeepTopic commandcssasetkeeptopic;
public:
CSSetKeepTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSSetKeepTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetkeeptopic(this), commandcssasetkeeptopic(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(this, &commandcssetkeeptopic);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetkeeptopic);
}
~CSSetKeepTopic()
{
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->DelSubcommand(&commandcssetkeeptopic);
c = FindCommand(ChanServ, "SASET");
if (c)
c->DelSubcommand(&commandcssasetkeeptopic);
ModuleManager::RegisterService(&commandcssetkeeptopic);
ModuleManager::RegisterService(&commandcssasetkeeptopic);
}
};
+115
View File
@@ -0,0 +1,115 @@
/*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
else if (source.permission.empty() && !ci->AccessFor(source.u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
ci->Shrink("cs_set_misc:" + source.command.replace_all_cs(" ", "_"));
if (params.size() > 1)
{
ci->Extend("cs_set_misc:" + source.command.replace_all_cs(" ", "_"), new ExtensibleItemRegular<Anope::string>(params[1]));
source.Reply(CHAN_SETTING_CHANGED, source.command.c_str(), ci->name.c_str(), params[1].c_str());
}
else
source.Reply(CHAN_SETTING_UNSET, source.command.c_str(), ci->name.c_str());
}
};
class CommandCSSASetMisc : public CommandCSSetMisc
{
public:
CommandCSSASetMisc(Module *creator) : CommandCSSetMisc(creator, "chanserv/saset/misc")
{
}
};
class CSSetMisc : public Module
{
CommandCSSetMisc commandcssetmisc;
CommandCSSASetMisc commandcssasetmisc;
public:
CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetmisc(this), commandcssasetmisc(this)
{
this->SetAuthor("Anope");
Implementation i[] = { I_OnChanInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::RegisterService(&this->commandcssetmisc);
ModuleManager::RegisterService(&this->commandcssasetmisc);
}
void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden)
{
std::deque<Anope::string> list;
ci->GetExtList(list);
for (unsigned i = 0; i < list.size(); ++i)
{
if (list[i].find("cs_set_misc:") != 0)
continue;
Anope::string value;
if (ci->GetExtRegular(list[i], value))
source.Reply(" %s: %s", list[i].substr(12).replace_all_cs("_", " ").c_str(), value.c_str());
}
}
void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci)
{
std::deque<Anope::string> list;
ci->GetExtList(list);
for (unsigned i = 0; i < list.size(); ++i)
{
if (list[i].find("cs_set_misc:") != 0)
continue;
Anope::string value;
if (ci->GetExtRegular(list[i], value))
WriteMetadata(list[i], ":" + value);
}
}
EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> &params)
{
if (key.find("cs_set_misc:") == 0)
ci->Extend(key, new ExtensibleItemRegular<Anope::string>(params[0]));
return EVENT_CONTINUE;
}
};
MODULE_INIT(CSSetMisc)
@@ -16,16 +16,27 @@
class CommandCSSetOpNotice : public Command
{
public:
CommandCSSetOpNotice(const Anope::string &cpermission = "") : Command("OPNOTICE", 2, 2, cpermission)
CommandCSSetOpNotice(Module *creator, const Anope::string &cname = "chanserv/set/opnotice") : Command(creator, cname, 2, 2)
{
this->SetDesc(_("Send a notice when OP/DEOP commands are used"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetOpNotice");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
@@ -40,37 +51,27 @@ class CommandCSSetOpNotice : public Command
else
this->OnSyntaxError(source, "OPNOTICE");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 OPNOTICE {ON | OFF}\002\n"
" \n"
"Enables or disables the \002op-notice\002 option for a channel.\n"
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002op-notice\002 option for a channel.\n"
"When \002op-notice\002 is set, %s will send a notice to the\n"
"channel whenever the \002OP\002 or \002DEOP\002 commands are used for a user\n"
"in the channel."), this->name.c_str(), ChanServ->nick.c_str());
"in the channel."), this->name.c_str(), source.owner->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET OPNOTICE", _("SET \037channel\037 OPNOTICE {ON | OFF}"));
}
};
class CommandCSSASetOpNotice : public CommandCSSetOpNotice
{
public:
CommandCSSASetOpNotice() : CommandCSSetOpNotice("chanserv/saset/opnotice")
CommandCSSASetOpNotice(Module *creator) : CommandCSSetOpNotice(creator, "chanserv/saset/opnotice")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET OPNOTICE", _("SASET \002channel\002 OPNOTICE {ON | OFF}"));
}
};
class CSSetOpNotice : public Module
@@ -79,29 +80,13 @@ class CSSetOpNotice : public Module
CommandCSSASetOpNotice commandcssasetopnotice;
public:
CSSetOpNotice(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSSetOpNotice(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetopnotice(this), commandcssasetopnotice(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(this, &commandcssetopnotice);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetopnotice);
}
~CSSetOpNotice()
{
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->DelSubcommand(&commandcssetopnotice);
c = FindCommand(ChanServ, "SASET");
if (c)
c->DelSubcommand(&commandcssasetopnotice);
ModuleManager::RegisterService(&commandcssetopnotice);
ModuleManager::RegisterService(&commandcssasetopnotice);
}
};
+93
View File
@@ -0,0 +1,93 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
ci->SetFlag(CI_PEACE);
source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str());
}
else if (params[1].equals_ci("OFF"))
{
ci->UnsetFlag(CI_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 &)
{
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.owner->nick.c_str());
return true;
}
};
class CommandCSSASetPeace : public CommandCSSetPeace
{
public:
CommandCSSASetPeace(Module *creator) : CommandCSSetPeace(creator, "chanserv/saset/peace")
{
}
};
class CSSetPeace : public Module
{
CommandCSSetPeace commandcssetpeace;
CommandCSSASetPeace commandcssasetpeace;
public:
CSSetPeace(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetpeace(this), commandcssasetpeace(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetpeace);
ModuleManager::RegisterService(&commandcssasetpeace);
}
};
MODULE_INIT(CSSetPeace)
@@ -16,16 +16,27 @@
class CommandCSSetPersist : public Command
{
public:
CommandCSSetPersist(const Anope::string &cpermission = "") : Command("PERSIST", 2, 2, cpermission)
CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2)
{
this->SetDesc(_("Set the channel as permanent"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetPersist");
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
@@ -51,9 +62,15 @@ class CommandCSSetPersist : public Command
*/
if (!ci->bi && !cm)
{
ChanServ->Assign(NULL, ci);
if (!ci->c->FindUser(ChanServ))
ChanServ->Join(ci->c);
BotInfo *bi = findbot(Config->ChanServ);
if (!bi)
{
source.Reply(_("ChanServ is required to enable persist on this network."));
return;
}
bi->Assign(NULL, ci);
if (!ci->c->FindUser(bi))
bi->Join(ci->c);
}
/* Set the perm mode */
@@ -66,7 +83,7 @@ class CommandCSSetPersist : public Command
}
}
source.Reply(_("Channel \002%s\002 is now persistant."), ci->name.c_str());
source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str());
}
else if (params[1].equals_ci("OFF"))
{
@@ -88,27 +105,36 @@ class CommandCSSetPersist : public Command
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
* which was assigned when persist was set on
*/
if (!cm && Config->s_BotServ.empty() && ci->bi)
if (!cm && Config->BotServ.empty() && ci->bi)
{
BotInfo *bi = findbot(Config->ChanServ);
if (!bi)
{
source.Reply(_("ChanServ is required to enable persist on this network."));
return;
}
/* Unassign bot */
ChanServ->UnAssign(NULL, ci);
bi->UnAssign(NULL, ci);
}
}
source.Reply(_("Channel \002%s\002 is no longer persistant."), ci->name.c_str());
source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str());
}
else
this->OnSyntaxError(source, "PERSIST");
return MOD_CONT;
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
source.Reply(_("Syntax: \002%s \037channel\037 PERSIST {ON | OFF}\002\n"
"Enables or disables the persistant channel setting.\n"
"When persistant is set, the service bot will remain\n"
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 a permanent (persistant) channel\n"
"If your IRCd does not 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"
@@ -118,31 +144,21 @@ class CommandCSSetPersist : public Command
"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 (persistant) channel mode\n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and is is set or unset (for any reason, including MLOCK),\n"
"persist is automatically set and unset for the channel aswell.\n"
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."), this->name.c_str());
"set persist on or off."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SET PERSIST", _("SET \037channel\037 PERSIST {ON | OFF}"));
}
};
class CommandCSSASetPersist : public CommandCSSetPersist
{
public:
CommandCSSASetPersist() : CommandCSSetPersist("chanserv/saset/persist")
CommandCSSASetPersist(Module *creator) : CommandCSSetPersist(creator, "chanserv/saset/persist")
{
}
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(source, "SASET PERSIST", _("SASET \002channel\002 PERSIST {ON | OFF}"));
}
};
class CSSetPersist : public Module
@@ -151,29 +167,13 @@ class CSSetPersist : public Module
CommandCSSASetPersist commandcssasetpeace;
public:
CSSetPersist(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
CSSetPersist(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetpeace(this), commandcssasetpeace(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(this, &commandcssetpeace);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetpeace);
}
~CSSetPersist()
{
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->DelSubcommand(&commandcssetpeace);
c = FindCommand(ChanServ, "SASET");
if (c)
c->DelSubcommand(&commandcssasetpeace);
ModuleManager::RegisterService(&commandcssetpeace);
ModuleManager::RegisterService(&commandcssasetpeace);
}
};
+93
View File
@@ -0,0 +1,93 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSSetPrivate : public Command
{
public:
CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
{
this->SetDesc(_("Hide channel from LIST command"));
this->SetSyntax(_("\037channel\037 {ON | OFF}"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
ci->SetFlag(CI_PRIVATE);
source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
}
else if (params[1].equals_ci("OFF"))
{
ci->UnsetFlag(CI_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 &)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Enables or disables the \002private\002 option for a channel.\n"
"When \002private\002 is set, a \002%s%s LIST\002 will not\n"
"include the channel in any lists."),
Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
return true;
}
};
class CommandCSSASetPrivate : public CommandCSSetPrivate
{
public:
CommandCSSASetPrivate(Module *creator) : CommandCSSetPrivate(creator, "chanserv/saset/private")
{
}
};
class CSSetPrivate : public Module
{
CommandCSSetPrivate commandcssetprivate;
CommandCSSASetPrivate commandcssasetprivate;
public:
CSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetprivate(this), commandcssasetprivate(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetprivate);
ModuleManager::RegisterService(&commandcssasetprivate);
}
};
MODULE_INIT(CSSetPrivate)
+91
View File
@@ -0,0 +1,91 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class 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)
{
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
if (ci == NULL)
{
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
{
source.Reply(ACCESS_DENIED);
return;
}
if (params[1].equals_ci("ON"))
{
ci->SetFlag(CI_RESTRICTED);
source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str());
}
else if (params[1].equals_ci("OFF"))
{
ci->UnsetFlag(CI_RESTRICTED);
source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str());
}
else
this->OnSyntaxError(source, "RESTRICTED");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &)
{
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 CommandCSSASetRestricted : public CommandCSSetRestricted
{
public:
CommandCSSASetRestricted(Module *creator) : CommandCSSetRestricted(creator, "chanserv/saset/restricted")
{
}
};
class CSSetRestricted : public Module
{
CommandCSSetRestricted commandcssetrestricted;
CommandCSSASetRestricted commandcssasetrestricted;
public:
CSSetRestricted(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcssetrestricted(this), commandcssasetrestricted(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetrestricted);
ModuleManager::RegisterService(&commandcssasetrestricted);
}
};
MODULE_INIT(CSSetRestricted)

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