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

Compare commits

...

252 Commits

Author SHA1 Message Date
Adam 469a04e7e0 Anope 1.9.4 Release 2011-05-16 02:58:06 -04:00
Adam 605b5d5717 Removed ngircd as we've decided not to support it at this time 2011-05-16 02:57:28 -04:00
Adam f7aa46fb33 Note m_async_commands is experimental 2011-05-16 02:47:23 -04:00
Adam b4450294af Fixed Windows build 2011-05-15 21:02:06 -04:00
Adam 57327a5e33 Fixed akill log message when there is no expiry time 2011-05-15 19:54:35 -04:00
Adam 4a3c64291f Fixed sometimes not removing nick masks from the access list when the group is dropped 2011-05-01 18:41:54 -04:00
Adam 036b3c9053 Temporary fix for /os restart with m_async_commands loaded, is fixed properly in 1.9.5 2011-04-29 18:03:04 -04:00
Adam 7da33344d1 Added a unique key for the anope_cs_mlock table 2011-04-28 19:13:44 -04:00
Adam cbdb9f59f3 Fixed bug #1265 2011-04-27 11:15:02 -04:00
Adam 5d3d6bcead Fixed a crash if an expiring channel had the founder also on the access list 2011-04-27 09:26:51 -04:00
Adam 0cdc628db0 Fixed crash when certain nicks expire 2011-04-25 15:58:46 -04:00
Adam 4a733c93d4 Don't attempt to connect to the uplink if given invalid hostnames 2011-04-25 04:17:21 -04:00
DukePyrolator 03d2378a9f resolve hosts when connecting with ssl 2011-04-25 07:08:57 +02:00
Adam 5e027c196d Two small SQL fixes 2011-04-23 02:36:42 -04:00
Adam 3aeaef5b9a A few more small fixes 2011-04-20 15:39:44 -04:00
Adam 4d26070a92 This actually isn't necessary 2011-04-20 09:35:09 -04:00
Adam f601b04594 Fixed logging messages with an empty category to everything 2011-04-19 23:42:16 -04:00
Adam ca169489b2 Allow unidentified users to still get access by non nickcore access entries 2011-04-18 21:07:54 -04:00
Adam 713c2eb704 Fixed /ns help register reply 2011-04-18 17:09:30 -04:00
Adam 660e0c78ac Fixed /ns help access 2011-04-17 19:00:01 -04:00
Adam 0862de6577 Fixed the mlock depreciated message 2011-04-16 16:06:52 -04:00
Adam 2cd511d3a3 Fixed botserv kicker logic 2011-04-16 04:35:14 -04:00
Adam efe5fedde9 Fixed caps kicker 2011-04-15 19:51:34 -04:00
Adam c8c6845452 Fixed /ns list unconfirmed 2011-04-10 22:05:48 -04:00
Adam bd62c4891e Fixed disabling channel levels 2011-04-09 20:52:25 -04:00
Adam 9535541f5a Fixed setting +r on nick ownership, lost somewhere in revision fbae33 2011-04-06 10:13:03 -04:00
Adam 711a570d24 Run OnCheckAuthentication with the account name if there is one 2011-04-06 09:41:39 -04:00
Adam cb9ccc443d Fixed bug #1261 2011-04-05 19:11:23 -04:00
Adam c681bdd2e3 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-04-03 18:23:17 -04:00
Adam 74844c0f28 Use dynamic_reference to check for users being killed from commands 2011-04-03 18:19:29 -04:00
Adam 905207093b Made LDAP support recover, release, resetpass, etc. 2011-04-03 18:07:58 -04:00
DukePyrolator 73a944fb74 fixed some duplicate messages and updated the german langfile (10% done) 2011-04-03 08:54:40 +02:00
Adam d1328d876a Fixed a typo making ns_register crash 2011-04-01 01:57:12 -04:00
Adam faa85564fc Removed some unneeded/unused code from m_ldap 2011-03-31 14:41:30 -04:00
Adam 8dec0c1f17 Fixed bug #1258, more Windows stuff, and more language strings 2011-03-30 23:59:57 -04:00
Adam 8098ed899a Fixed windows build more, including ldap 2011-03-30 00:55:45 -04:00
Adam 77c98f0750 Regenerated language files. 2011-03-29 14:02:35 -04:00
Adam 8dbdfa9a44 Fixed windows build 2011-03-29 13:43:40 -04:00
Adam 685e99be02 Fixed some left over useprivmsg problems and fixed some compiler warnings. 2011-03-29 13:43:22 -04:00
DukePyrolator b14b7bd55e burned all %R and %S in the .po files 2011-03-26 08:44:21 +01:00
DukePyrolator 365769d14c replaced all %R with %s in the language strings 2011-03-26 08:20:05 +01:00
DukePyrolator 01b901eba1 ignore additional parameters for /chanserv info 2011-03-25 20:56:42 +01:00
DukePyrolator 26de1d9f93 1. when dropping nicks, dont add the dropped nick as successor for a channel 2. set -r on dropped channels 2011-03-25 17:42:13 +01:00
Adam 451fb82e54 Bug #1203 2011-03-22 23:58:53 -04:00
Adam c02d51f523 Bug #1256 2011-03-22 18:16:05 -04:00
Adam b95027ba28 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-03-16 01:16:15 -04:00
DukePyrolator 5b476a2597 added a description for the HELP command 2011-03-16 06:14:28 +01:00
DukePyrolator bceeda8087 fixed displaying the RESEND command in /nickserv help output 2011-03-16 05:36:12 +01:00
Adam ee9636bba2 Fixed some logic fail in User::IsRecognized 2011-03-15 19:23:08 -04:00
Adam ddfb16de1a Fixed compile 2011-03-14 20:16:38 -04:00
Charles Kingsley 2555d0d637 Removed include/patricia.h due to oversight in attribution. This breaks compile, please do not use until this is fixed later. 2011-03-14 21:39:53 +00:00
Adam ed73d76751 Rewrote some of the opertype system, added os_login 2011-03-14 13:52:26 -04:00
Adam 4fe49af840 Fixed a crash in m_ldap is unloaded 2011-03-13 22:59:50 -04:00
Adam beabbb3a20 When a server quits use its quit reason for all of its links 2011-03-13 19:15:53 -04:00
Adam b4888c21ed Fixed a typo in os_stats 2011-03-13 17:20:44 -04:00
Adam b75fa1c6ec Fixed a crash in /cs help register 2011-03-13 14:03:02 -04:00
DukePyrolator 3fbf39b25d Added some useful Anope::Version functions to prevent some files from unnecessarily rebuilding on every make 2011-03-13 03:42:30 -04:00
DukePyrolator 15a833283b Set the locale to the default system locale on startup 2011-03-13 03:38:42 -04:00
DukePyrolator 5a0d04bb81 fixed a typo in os_news, thanks to Dan for reporting it 2011-03-13 07:09:17 +01:00
DukePyrolator fbae3344ff added ns_cert 2011-03-12 09:27:16 +01:00
Adam 95469fde30 Added some access checks to cs_mode and fixed some language strings 2011-03-12 02:40:08 -05:00
Adam 9f46972f19 _()ify Command::SetDesc 2011-03-11 17:26:27 -05:00
Adam 46a3afadb9 Fixed validating users on all server syncs 2011-03-11 17:09:49 -05:00
Adam 1b2f3bf369 Fixed some problems with m_alias and fantasy 2011-03-11 15:10:30 -05:00
Adam bb3b421385 Global should send logon news 2011-03-11 04:27:32 -05:00
Adam 1ee3d3d810 Added os_config and support for including additional configuration files. 2011-03-11 00:47:28 -05:00
Adam 97c2e0957d Bug #1251 - Fixed logging inspircd logging us logging inspircd. Also moved the Server::Find messages to debug level 2 2011-03-10 19:20:58 -05:00
Alexander Barton 09a5791bc6 ngIRCd protocol: announce Anope with its version 2011-03-09 12:29:59 -05:00
Adam 8db5ecd736 Fixed sending CHANINFO on ngIRCd with two parameters if the channel has no modes locked. 2011-03-09 12:28:24 -05:00
Adam e9aa04a8f4 Store mlock in the databases and removed some unused functions from misc.cpp 2011-03-09 01:25:49 -05:00
Adam 8eb23e7d48 Added support for extbans 2011-03-07 19:54:51 -05:00
Adam 093b3d258e Change the mode name code to use Flags names in preparation for extban support 2011-03-06 19:36:52 -05:00
Adam 48e6221cf0 Expire unconfirmed nicks, forgot to add this earlier.. 2011-03-05 22:00:27 -05:00
Adam ef0c095712 Made m_ldap_oper understand deopering 2011-03-05 18:18:51 -05:00
Adam a0355dfd9d Fixed /bs badword del to show what word was deleted 2011-03-05 17:43:51 -05:00
Adam 6fe2d8af97 Removed nickrequests, instead have unconfirmed registrations. Also made ns_resetpass allow remote-id to get past things such as kill immed. 2011-03-05 17:23:22 -05:00
Adam 90e5d0feaa Added LDAP support 2011-03-04 20:47:58 -05:00
Adam d79e22bfaa Updated TODO 2011-03-04 12:50:50 -05:00
Adam a9fb6bab15 Just use blocking sql queries if m_asynch_commands isn't loaded - it's not that bad. 2011-03-04 02:41:29 -05:00
Adam dd968c07be Fixed some logic fail when detecting who should be akicked 2011-03-04 02:19:20 -05:00
Adam feb81c51d2 Clarify the module dependency messages generated by cmake are non fatal 2011-03-04 02:17:51 -05:00
Adam aecf675e6b Fixed os_sqline del 2011-02-27 23:32:07 -05:00
Adam bcaf406747 Made akills work on IRCds that do not support bans (ngircd) 2011-02-27 16:47:23 -05:00
Adam f234a2bfab Replaced the few language strings we use with #defines to prevent accidentally translating them if we shouldnt 2011-02-26 17:54:03 -05:00
Adam 28d17a40ce Fixed session exception limit of 0 to mean unlimited 2011-02-25 21:41:27 -05:00
Adam 7cfca37e2a Fixed build on freebsd with precompiled headers 2011-02-25 21:41:18 -05:00
Adam c38b6392c5 More fixes. Also made db_mysql_live not keep bots updated because thats pointless and made m_asynch_commands respect user language settings. 2011-02-25 21:41:08 -05:00
Adam ee38756982 Fixed a lot of small problems 2011-02-25 21:40:43 -05:00
Adam eea7d2eb77 Fixed the first half of #1235 2011-02-22 20:44:47 -05:00
Adam b15410fd3a 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 2011-02-22 20:30:45 -05:00
Adam c83b2b73d7 Much more work on the live SQL. Should work pretty decently now under heavy load. 2011-02-20 01:05:16 -05:00
Adam dfbb5264fa Inspircd does not send CAPAB NOQUIT, assume it 2011-02-19 21:17:53 -05:00
Adam f49a3e03c1 Fixed aborting because of invalid values given to mode +f on inspircd 2011-02-19 19:03:05 -05:00
Adam 109d1744a0 Update SQL when a nick is deleted 2011-02-18 11:49:52 -05:00
Adam 470f8af97c Fixed some logic fail when determining when a recognized user gets access 2011-02-18 11:48:29 -05:00
Adam a1296a3b7c Changed the OnNickDrop event to call before the nick is deleted 2011-02-18 11:48:20 -05:00
Adam f38fe242cd Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-02-17 14:32:51 -05:00
Adam 536ea2189a Split db_mysql_live into two modules so other modules can make use of the asynchronous command interface 2011-02-17 14:31:21 -05:00
DukePyrolator ab0422b4d4 set the vhost before we call ns_ajoin or other modules on identify 2011-02-17 07:00:03 +01:00
Adam 18bd33f9a4 Use precompiled headers when building with gnu g++ to speed up build time 2011-02-16 12:50:23 -05:00
DukePyrolator d436e4ca4a added Anope::printf() 2011-02-13 20:06:01 +01:00
Adam 1372dc1953 Removed the Wallop config options and replaced them with the new log system 2011-02-12 16:17:17 -05:00
Adam 9ef7352e69 Merged os_umode into os_mode 2011-02-11 18:30:58 -05:00
Adam 2529ff6dae Made the help command description code more sane 2011-02-11 03:12:39 -05:00
Adam 7bdf592f7e Log rawio when in debug mode and fixed expiring session exceptions 2011-02-09 21:54:28 -05:00
Adam f463b772b0 Removed a lot of the old capab flags we dont/have never used 2011-02-09 20:09:26 -05:00
Adam eec897762c Enable quitstorm for ngircd 2011-02-09 17:41:07 -05:00
Adam f87c665b63 Foward port ebe0ce6610 / b6ab031fc1 2011-02-09 13:31:47 -05:00
Adam 36d3fd1710 Do not crash if a user is introduced with a nonexistant server 2011-02-09 13:25:28 -05:00
Adam d26a19b41d Made ./Config output a userful error message if cmake is not found 2011-02-09 01:12:43 -05:00
Adam a55b3742cb Removed the LIBINTL include hack 2011-02-05 18:35:20 -05:00
Adam 83556667fd try/catch-ified all instances of convertTo to keep from aborting when a user gives too large or too small a number 2011-02-04 21:01:33 -05:00
Adam faf5f3128f Merge 032c30dd5d 2011-02-04 19:31:02 -05:00
Adam a53a797271 Replaced all of the old %S's in the language strings that were used for service nicks 2011-02-04 18:32:04 -05:00
Adam 08583dc107 Moved the language strings which are only used once
out of the core and into the modules that use them.
2011-02-04 15:30:31 -05:00
Charles Kingsley c362a1e077 DP in "an user" grammar police mode. 2011-01-29 12:05:34 +00:00
Charles Kingsley 140208e5ee Another typo pointed out by the grammar police. ;) 2011-01-29 12:00:12 +00:00
Charles Kingsley 679d3c373f Fixing leftover spaces and other rubbish I missed on the first pass. 2011-01-29 11:58:59 +00:00
Charles Kingsley 557eceeefc Updated some docs/ & removed TROUBLESHOOTING as it is redundant. 2011-01-29 11:06:38 +00:00
Charles Kingsley 9704ccc8a6 QA fixes / refinements for example.conf 2011-01-29 10:44:27 +00:00
Adam e62664138b Added patricia_tree::iterator 2011-01-28 23:09:25 -05:00
Adam 3eadc1509f Fixed setting usermode +k on our clients on InspIRCd 2.0 2011-01-28 13:19:26 -05:00
lethality 9910aa3cc6 Bug #1237 - only set umode +h on a user joining help chan if they have op access 2011-01-28 00:09:34 +00:00
Adam 2a53e5f80e Fixed the order queries are done during sqlsync to make the new foreign keys happy 2011-01-24 19:03:15 -05:00
Adam 2e8acfb98c Fixed some SQL queries 2011-01-24 17:50:34 -05:00
Adam 48fa096943 Added %N for network name in dnsbl:reason 2011-01-24 02:54:09 -05:00
Adam bf559d788f Fixed loading forbidden nicks 2011-01-24 01:11:10 -05:00
Adam 3bfc8e9a39 std::stringstream::clear doesn't clear it 2011-01-23 12:56:21 -05:00
Adam a162f1d18e Bug #1234 - Fix reading resolv.conf if it has multiple spaces or tabs 2011-01-21 23:01:48 -05:00
lethality a86873c93e fixed some minor presentation, grammar mis-use and copyright date in DP's ngircd 2011-01-21 16:49:25 +00:00
Adam 05933e9f21 Removed db-upgrade, its no longer needed 2011-01-20 19:42:27 -05:00
Adam ab2e34d817 Added options:nomlock 2011-01-19 00:31:18 -05:00
Adam e7a8bcc30b Bug #1232 - Fixed db-convert to properly convert mode lock parameters 2011-01-18 18:47:08 -05:00
Adam 34c6c664c9 Added amsg kicker settings to /bs info 2011-01-18 18:41:16 -05:00
DukePyrolator 4a3ee91c55 fixed a bug in the ngircd protocol module 2011-01-18 19:05:20 +01:00
Adam 6f0d1af596 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.
2011-01-17 20:41:57 -05:00
Adam 01feb5b489 Fixed ns_ajoins list output formatting 2011-01-17 20:29:33 -05:00
Adam 8975b52cc3 Added ns_ajoin 2011-01-17 15:46:53 -05:00
Adam 7acbbbbf5b Fixed flag names to match 1.9.3s 2011-01-15 21:02:14 -05:00
Adam 4fecafa612 Made db_plain save amsg settings 2011-01-15 16:45:48 -05:00
Adam a4ded88e85 Made CA_SET always be accessable, even if db-converter messes up levels 2011-01-15 16:29:17 -05:00
Adam 1b6aab0cd7 Fixed /ns confirm's log message to show the nick of who was confirmed 2011-01-15 16:13:31 -05:00
Adam c669820481 Added an amsg kicker 2011-01-15 16:11:31 -05:00
lethality ecc2fc6029 Fix CODINGs formatting and a missed typo 2011-01-14 04:50:01 +00:00
Adam e490202a1b Bug #1230 - Fixed unknown CTCPs from crashing services 2011-01-11 22:19:46 -05:00
Adam fd2412a5f6 Send new memo replies to the receiver of the memo 2011-01-10 17:41:09 -05:00
Adam 07528ea8f2 Fixed CanAdd() to use safe iteration and make SNLine::Check really work
(cherry picked from commit 1bdadde68a)
2011-01-09 13:38:15 -05:00
Adam ce8a069eb5 Changed db_mysql_live to use a safer mutex system to prevent deadlocks 2011-01-08 18:55:12 -05:00
Adam 2ba97aee6c Ignore EINTR error from poll() 2011-01-08 03:35:04 -05:00
DukePyrolator a674d81caf updated the README file 2011-01-08 08:38:16 +01:00
DukePyrolator efb61ed4a8 enabled modeonid in example.conf 2011-01-08 08:21:18 +01:00
DukePyrolator 2e7d08c10b fixed a small bug in the ratbox protocol module 2011-01-08 08:18:46 +01:00
DukePyrolator 47b87e903b added support for ngIRCd protocol 2011-01-08 08:15:48 +01:00
Adam ddeff72544 Process flag changes from SQL 2011-01-08 00:52:46 -05:00
Adam 43995b4c6d Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-01-08 00:25:30 -05:00
Adam 512d23d60f Made the Flag class able to convert flags to strings and back 2011-01-08 00:25:11 -05:00
lethality 0eb9152749 fix some more copyright and typos (not mine) spotted by chaz :P 2011-01-07 23:01:19 +00:00
Adam 4403849126 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.
2011-01-07 15:57:13 -05:00
lethality 9efebe5461 update copyrights for 2011 2011-01-05 18:34:38 +00:00
DukePyrolator 7198fa73d1 removed SendSVSPart(), we dont use it 2011-01-04 07:33:34 +01:00
DukePyrolator 03ba592c48 removed SendSVSMode(), we dont use it 2011-01-04 07:14:50 +01:00
lethality 57a06f72e2 fixed a crash bug when a server squits 2010-12-31 21:20:34 +00:00
DukePyrolator 3019ba6f43 restoring topic for permchans on burst 2010-12-30 06:44:18 +01:00
DukePyrolator 2784cd17fc Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-30 05:50:55 +01:00
Adam 03cc9eb5c5 Assign bots to new empty permanent channels on IRCds without permchannel mode not just join 2010-12-29 23:30:28 -05:00
Adam 72b8f4609b Use empty SJOINs when allowed to create empty permanent channels 2010-12-29 23:12:26 -05:00
Adam d36e53f702 Added a ConvertException to be thrown when convertTo fails 2010-12-29 20:19:37 -05:00
Adam a36f14c1bf Automatically quit bots when they are deleted 2010-12-29 19:59:26 -05:00
DukePyrolator 292e187524 Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-29 22:39:20 +01:00
Adam 16cab979da Bug #1225 - Made REGISTER show in /cs help 2010-12-28 16:32:18 -05:00
DukePyrolator fd7f542bd9 Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-28 07:00:47 +01:00
Adam 5ead326454 Fixed build on debian lenny 2010-12-27 15:33:49 -05:00
Adam a1c635b050 Load session exceptions on start when using SQL 2010-12-27 01:35:08 -05:00
Adam d896bf9a1c Bug #1222 - Fixed crash from reading to read a range of memos 2010-12-27 01:00:12 -05:00
Adam 49dd1c3409 Bug #1220 - Fixed an event in /hs activate and /ms del 2010-12-27 00:42:38 -05:00
Adam fce491e18c Made socket engine stop processing once all sockets have been checked 2010-12-27 00:41:04 -05:00
Adam 87d0fc8bb5 Fixed poll engine to not reorder sockets if we remove the last socket because there is no need 2010-12-26 20:15:54 -05:00
DukePyrolator f638d1078a Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-26 09:36:45 +01:00
Adam 8af2465a61 Bug #1219 - Correctly restrict people from registering potentential guest names 2010-12-26 00:31:11 -05:00
Adam 1b3f2567bc Fixed a potential crash from dropping nicks 2010-12-26 00:14:49 -05:00
lethality 036d4514f0 updated crontab instructions in INSTALL 2010-12-25 15:27:02 +00:00
Adam 80721d1873 Forward port part of 821995bf60 2010-12-25 02:30:39 -05:00
Adam aa9e33cf74 Bug #1216 - Do not apply SQLines on our own clients 2010-12-24 19:55:09 -05:00
Adam 86900175c8 Made clearing SXLines remove the XLine from the IRCd too 2010-12-24 19:07:47 -05:00
Adam d5c1d6ebec Do not allow xop del to delete users on another list 2010-12-24 16:12:08 -05:00
Adam 35e328bcb6 Fixed Windows build 2010-12-24 01:23:22 -05:00
Adam befb4b3644 Made the default socket poller use poll() because it is supported on most platforms 2010-12-24 01:22:07 -05:00
DukePyrolator 4235df2b28 Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-24 06:42:55 +01:00
Adam a6c8a6a9f2 Prevent version.cpp from prepending version.sh's VERSION_EXTRA on every build 2010-12-23 23:33:02 -05:00
Adam 1a3ba00c24 Fixed noexpire channels expiring 2010-12-23 21:56:06 -05:00
Adam e8a2072792 Added a missing os_ignore.h 2010-12-23 19:18:25 -05:00
Adam 4886b56edb Fixed a crash in m_alias 2010-12-23 19:14:07 -05:00
Adam 15d29edae9 Do not clear want write on a socket if we are unable to completely write its buffer 2010-12-23 18:50:27 -05:00
Adam 3009540a00 Rewrote the ignore code. Adds creator and reason to /os ignore list. 2010-12-23 18:39:54 -05:00
DukePyrolator a0ad3c4fef Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-23 07:15:32 +01:00
Adam 265006b691 Fixed deleting expired SXLines 2010-12-23 00:03:50 -05:00
Adam 11b3b8a5ff Made SQLine clear work 2010-12-22 19:12:04 -05:00
Adam 2783c82685 Removed match_usermask 2010-12-22 18:28:22 -05:00
DukePyrolator 184e7b3f64 Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-22 07:05:40 +01:00
Adam 18377ac9fd Allow hostmasks to be in uplink:host 2010-12-21 15:57:57 -05:00
DukePyrolator 184e14ea83 Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-19 08:56:31 +01:00
Adam 21125cf2cb Made the version generator code work right when we are on a tag because git describe just gives the tag name and nothing else. 2010-12-18 19:53:32 -05:00
Adam 0d20c47703 Don't send SXLines until after we start bursting with our uplink 2010-12-18 19:41:13 -05:00
Adam 7f9a5e01c6 NULL the core *serv pointers when core clients are deleted 2010-12-17 03:09:51 -05:00
Adam eb9b12ed11 Bug #1211 - Fixed loading and saving anope_os_sxlines 2010-12-15 12:47:35 -05:00
Adam 4a4c0886cc Bug #1212 - Fixed some bad logic in /os exception preventing valid exceptions from being added 2010-12-15 12:18:20 -05:00
DukePyrolator 02476332ea Merge branch '1.9' of ssh://anope.git.sourceforge.net/gitroot/anope/anope into 1.9 2010-12-14 08:13:09 +01:00
Adam 49d3c97b67 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.
2010-12-13 16:36:36 -05:00
Adam 97467cb2c8 Bug #1113 - Document the fantasy character in /bs help 2010-12-13 13:26:01 -05:00
DukePyrolator 6a43886807 removed an unused variable 2010-12-13 07:34:06 +01:00
DukePyrolator 5d56a2486e changed a few 'if' to 'else if' 2010-12-13 07:26:05 +01:00
Adam eb138a02d6 Do not validate users during netburst until after the server is done syncing 2010-12-12 19:37:04 -05:00
Adam 2a4d0e3e89 Allow getting users opertype from XMLRPC requests 2010-12-12 19:37:04 -05:00
Adam 9f7a2e4da2 Bug #1177 - Readded in support for cs_mode to act on every channel 2010-12-12 19:37:04 -05:00
Adam 25e995b0f5 Fixed a few places in the plexus protocol module where we were sending nick not UID 2010-12-12 19:37:04 -05:00
Adam ad5da2a988 Handle not being able to completely flush our write buffer correctly 2010-12-12 19:37:03 -05:00
DukePyrolator 6ab7cf9689 fixed a compile error in plexus protocol module 2010-12-12 19:37:03 -05:00
DukePyrolator 099ead02a5 store the ssl fingerprint in the userstruct 2010-12-12 19:37:03 -05:00
Adam f1d04a2f8e Allow command aliases to be redirected to different pseudo clients 2010-12-12 19:37:03 -05:00
Adam aed53dbb47 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. 2010-12-12 19:37:03 -05:00
Adam a507816701 Fixed looking up users to use case insensitivity 2010-12-12 19:37:03 -05:00
Adam c41c828574 Do not use wildcard matching when looking up hosts on access add/del 2010-12-12 19:37:03 -05:00
Adam 5fe41fb8a0 Document that /cs owner and deowner allow nick args 2010-12-12 19:37:02 -05:00
Adam 0ba566491e Allowing adding hostmasks to channel access lists 2010-12-12 19:37:02 -05:00
Adam 2a4d57a1ca Fixed subcommands 2010-12-12 19:37:02 -05:00
Adam 71c433cc50 The rest of the earlier command changes 2010-12-12 19:37:00 -05:00
Adam 2b10cc84ea Added /bs set msg 2010-12-12 19:36:19 -05:00
Adam cb6ef574e3 Send replies from fantasy commands back to the channel, this will be expanded on later 2010-12-12 19:36:19 -05:00
Adam 37e02a3594 Added cs_entrymsg 2010-12-12 19:36:19 -05:00
Adam 7d1cfe9514 Fixed some sed failure 2010-12-12 19:36:18 -05:00
Adam 9870ee04dd Removed some unused code paths in some of the modules 2010-12-12 19:36:18 -05:00
Adam 1a286397e3 Added a plexus3 protocol module 2010-12-12 19:36:16 -05:00
Adam 697dc89382 Added a default expiry time for suspended and forbidden nicks and channels 2010-12-12 19:36:01 -05:00
Adam 4d342d955d Fixed some of the language strings 2010-12-12 19:35:58 -05:00
Adam c5eb349d41 Removed the AUTODEOP level, it is unnecessary now because of cs_mode 2010-12-12 19:35:30 -05:00
Adam 7790a7f98c Allow the patricia tree to store non-pointers 2010-12-12 19:35:30 -05:00
Adam 246f44b988 Added cs_mode, rewrote the old list mode code, and added CIDR support 2010-12-12 19:35:27 -05:00
Adam a85112172d Removed and deprecated /cs set mlock, removed /cs clear, removed /os clearmodes, removed /cs akick (un)stick, added /cs clearusers 2010-12-12 19:33:59 -05:00
Adam 5f18cb018d Allow users to drop their own nickrequests 2010-12-12 19:33:58 -05:00
Adam 872bc3fa5e Allow users to remove their own access in channels 2010-12-12 19:33:58 -05:00
Adam 1625a5af0c Added /chanserv clone command 2010-12-12 19:33:58 -05:00
Adam 2e9a632e14 Allow akill/szline/sqline to accept user names as a mask argument 2010-12-12 19:33:58 -05:00
Adam 3c9d4e9daf Added command aliases 2010-12-12 19:33:58 -05:00
Adam c792c7f62d Switched the system for storing users, channels, and sesions to a patricia
tree from STL's unordered_map, which was giving horrible performance.
2010-12-12 19:33:58 -05:00
Adam e512760364 Fixed DNS caching and made DNS cache empty results 2010-12-12 19:33:50 -05:00
Adam ac41137ce2 Added /ms ignore 2010-12-12 19:31:00 -05:00
Adam 28aba58e25 Just store lang strings in a char array, no need for the extra overhead of STL strings 2010-12-12 19:30:28 -05:00
Adam 4ec661c0bb If a channel drops because a nick drops, set the channel founder to the user with the highest access if there is no successor 2010-12-12 19:30:14 -05:00
Adam 87bdf73cb7 Document XMLRPC calls and added a .php class wrapper for them 2010-12-12 19:30:14 -05:00
Adam 21c8e89671 Do not allow ghosting unidentified users if the recover command exists 2010-12-12 19:30:14 -05:00
Adam 8fbe36635c Added m_xmlrpc and m_xmlrpc main, which allows remote programs to execute
remote RPC calls to Anope in realtime and receive responses
2010-12-12 19:30:14 -05:00
Adam 5cd4fefb4c Bump for 1.9.4-git 2010-12-12 19:30:11 -05:00
349 changed files with 69227 additions and 78377 deletions
+6 -4
View File
@@ -220,11 +220,15 @@ find_package(Gettext)
option(USE_RUN_CC_PL "Use run-cc.pl for building" OFF)
# Use the following directories as includes
include_directories(${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/include ${Anope_BINARY_DIR}/lang)
# Note that it is important the binary include directory comes before the
# source include directory so the precompiled headers work correctly.
include_directories(${Anope_BINARY_DIR}/include ${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/language)
# If using Windows, always add the _WIN32 define
if(WIN32)
add_definitions(-D_WIN32)
# And include the windows specific folder for our anope_windows.h
include_directories(${Anope_SOURCE_DIR}/src/win32)
endif(WIN32)
# If using Visual Studio, set the C++ flags accordingly
@@ -327,11 +331,9 @@ endif(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEB
# Check for the existance of the following include files
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(sys/select.h HAVE_SYS_SELECT_H)
check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
# Check for the existance of the following functions
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(setgrent HAVE_SETGRENT)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(stricmp HAVE_STRICMP)
@@ -449,7 +451,7 @@ endif(${Anope_SOURCE_DIR} STREQUAL ${Anope_BINARY_DIR})
# Go into the following directories and run their CMakeLists.txt as well
add_subdirectory(data)
add_subdirectory(docs)
add_subdirectory(lang)
add_subdirectory(language)
add_subdirectory(src)
add_subdirectory(modules)
add_subdirectory(include)
+16 -5
View File
@@ -2,7 +2,7 @@
#
# Configuration script for Services.
#
# Anope (c) 2003-2010 Anope team
# Anope (c) 2003-2011 Anope team
# Contact us at team@anope.org
#
# This program is free but copyrighted software; see the file COPYING for
@@ -153,6 +153,17 @@ done
###########################################################################
which cmake > /dev/null
if [ $? -ne 0 ] ; then
clear
echo "Anope requires CMake 2.4 or newer to be configured, which can"
echo "be downloaded at http://www.cmake.org/. If you have installed"
echo "CMake already, ensure it is in your PATH environment variable."
exit 0
fi
###########################################################################
if [ ! "$NO_INTRO" ] ; then
case `uname -s` in
MINGW*)
@@ -168,11 +179,11 @@ if [ ! "$NO_INTRO" ] ; then
VERSION=`git describe --tags`
VERSION_BUILD=`echo "$VERSION" | cut -d'-' -f2`
VERSION_EXTRA=`echo "$VERSION" | cut -d'-' -f3`
if [ "$VERSION_BUILD" == "$VERSION_EXTRA" ] ; then
VERSION_EXTRA=""
# Only do this if we are not on a tag, src/version.sh will be all we need then.
if [ "$VERSION_BUILD" != "$VERSION_EXTRA" ] ; then
echo "#define VERSION_BUILD $VERSION_BUILD" > include/version.h
echo "#define VERSION_EXTRA \"-$VERSION_EXTRA\"" >> include/version.h
fi
echo "#define VERSION_BUILD $VERSION_BUILD" > include/version.h
echo "#define VERSION_EXTRA \"$VERSION_EXTRA\"" >> include/version.h
fi
cat $SOURCE_DIR/.BANNER | sed "s/CURVER/$VERSION/" | sed "s@SOURCE_DIR@$SOURCE_DIR@" | $PAGER
echo ""
+1 -1
View File
@@ -20,7 +20,7 @@ endif(NOT WIN32)
# If we found everything we need set variables correctly for lang/CMakeLists.txt to use
if(GETTEXT_FOUND)
set(LIBINTL_INCLUDE "${GETTEXT_INCLUDE}/libintl.h")
include_directories("${GETTEXT_INCLUDE}")
set(GETTEXT_MSGFMT_EXECUTABLE ${GETTEXT_MSGFMT})
if(WIN32)
+700 -297
View File
File diff suppressed because it is too large Load Diff
+37 -45
View File
@@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Oct 31, 2010 at 03:02 AM
-- Generation Time: Apr 28, 2011 at 07:08 PM
-- Server version: 5.1.50
-- PHP Version: 5.3.3-pl1-gentoo
@@ -108,10 +108,6 @@ CREATE TABLE IF NOT EXISTS `anope_cs_info` (
`forbidby` text NOT NULL,
`forbidreason` text NOT NULL,
`bantype` smallint(6) NOT NULL DEFAULT '0',
`mlock_on` text NOT NULL,
`mlock_off` text NOT NULL,
`mlock_params` text NOT NULL,
`entry_message` text NOT NULL,
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
`botnick` varchar(255) NOT NULL DEFAULT '',
`botflags` text NOT NULL,
@@ -151,6 +147,23 @@ CREATE TABLE IF NOT EXISTS `anope_cs_levels` (
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_mlock`
--
CREATE TABLE IF NOT EXISTS `anope_cs_mlock` (
`channel` varchar(255) NOT NULL,
`mode` varchar(127) NOT NULL,
`status` int(11) NOT NULL,
`setter` varchar(255) NOT NULL,
`created` int(11) NOT NULL,
`param` varchar(255) NOT NULL,
UNIQUE KEY `entry` (`channel`,`mode`,`status`,`setter`,`param`),
KEY `FK_anope_cs_mlock` (`channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_ttb`
--
@@ -270,7 +283,7 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core` (
`email` text NOT NULL,
`greet` text NOT NULL,
`flags` text NOT NULL,
`language` smallint(5) unsigned NOT NULL DEFAULT '0',
`language` varchar(5) NOT NULL DEFAULT '',
`channelcount` smallint(5) unsigned NOT NULL DEFAULT '0',
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`display`)
@@ -290,21 +303,6 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` (
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_request`
--
CREATE TABLE IF NOT EXISTS `anope_ns_request` (
`nick` varchar(255) NOT NULL DEFAULT '',
`passcode` text NOT NULL,
`password` text NOT NULL,
`email` text NOT NULL,
`requested` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`nick`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_akills`
--
@@ -371,83 +369,77 @@ CREATE TABLE IF NOT EXISTS `anope_os_xlines` (
-- Constraints for table `anope_bs_badwords`
--
ALTER TABLE `anope_bs_badwords`
ADD CONSTRAINT `FK_anope_bs_badwords_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE
ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_bs_badwords_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_bs_info_metadata`
--
ALTER TABLE `anope_bs_info_metadata`
ADD CONSTRAINT `FK_anope_bs_info_metadata_botname` FOREIGN KEY (`botname`) REFERENCES `anope_bs_core` (`nick`) ON DELETE
CASCADE ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_bs_info_metadata_botname` FOREIGN KEY (`botname`) REFERENCES `anope_bs_core` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_access`
--
ALTER TABLE `anope_cs_access`
ADD CONSTRAINT `FK_anope_cs_access_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_cs_access_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_akick`
--
ALTER TABLE `anope_cs_akick`
ADD CONSTRAINT `FK_anope_cs_akick_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_cs_akick_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_info_metadata`
--
ALTER TABLE `anope_cs_info_metadata`
ADD CONSTRAINT `FK_anope_cs_info_metadata_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE
CASCADE ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_cs_info_metadata_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_levels`
--
ALTER TABLE `anope_cs_levels`
ADD CONSTRAINT `FK_anope_cs_levels_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_cs_levels_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_mlock`
--
ALTER TABLE `anope_cs_mlock`
ADD CONSTRAINT `FK_anope_cs_mlock_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_ttb`
--
ALTER TABLE `anope_cs_ttb`
ADD CONSTRAINT `FK_anope_cs_ttb_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_cs_ttb_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_hs_core`
--
ALTER TABLE `anope_hs_core`
ADD CONSTRAINT `FK_anope_hs_core_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE
CASCADE;
ADD CONSTRAINT `FK_anope_hs_core_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ms_info`
--
ALTER TABLE `anope_ms_info`
ADD CONSTRAINT `FK_anope_ms_info_receiver` FOREIGN KEY (`receiver`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON
UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_ms_info_receiver` FOREIGN KEY (`receiver`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_access`
--
ALTER TABLE `anope_ns_access`
ADD CONSTRAINT `FK_anope_ns_access_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE
ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_ns_access_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_alias`
--
ALTER TABLE `anope_ns_alias`
ADD CONSTRAINT `FK_anope_ns_alias_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE
ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_ns_alias_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_alias_metadata`
--
ALTER TABLE `anope_ns_alias_metadata`
ADD CONSTRAINT `FK_anope_ns_alias_metadata_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE
ON UPDATE CASCADE;
ADD CONSTRAINT `FK_anope_ns_alias_metadata_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
+1 -4
View File
@@ -1,4 +1 @@
Reported Bugs from Bugzilla: http://bugs.anope.org/
---------------------------------------------------
For all bug reports / updates please see http://bugs.anope.org
+209 -140
View File
@@ -1,170 +1,239 @@
Orginally pulled from: http://www.inspircd.org/wiki/Coding_Guidelines
Yes, I'm aware the formatting of this document is ugly. It'll be fixed when someone cares. Read the wiki page if you want pretty for now.
---
InspIRCd Coding Guidelines
The following are a set of guidelines for writing patches to InspIRCd, or for creating modules for distribution with the official package. These
guidelines were written a time after InspIRCd development started, and so not all code yet follows these. This will be rectified with time.
The following are a set of guidelines for writing patches to InspIRCd, or for
creating modules for distribution with the official package. These guidelines
were written a time after InspIRCd development started, and so not all code
yet follows these. This will be rectified with time.
1. Comments
Multi Line
Multiple line comments should follow the C-style comment, for example:
/*
* This is a multiple line comment, huzzah..
*/
Single Line
Single line comments should also be in the C style, for example:
/* This is a boring one-line comment */
* Multi Line
Multiple line comments should follow the C-style comment, for example:
/*
* This is a multiple line comment, huzzah..
*/
Doxygen commenting
If you wish your comment to show in doxygen, the comment should be directly above the item you are documenting (a class, function, enum, etc)
and the first line should be "/**". For example:
/** This is a doxygen multiline comment.
* Description of thingymebob here.
*/
The first line after the "**" is used as the short description of the item (up to the full stop) and everything afterwards as the detailed
description.
* Single Line
Single line comments should also be in the C style, for example:
/* This is a boring one-line comment */
Indentation
Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation, for example:
int main()
{
<tab>if (condition)
<tab>{
<tab><tab>code
<tab>}
}
* Doxygen commenting
If you wish your comment to show in doxygen, the comment should be directly
above the item you are documenting (a class, function, enum, etc) and the
first line should be "/**". For example:
/** This is a doxygen multiline comment.
* Description of thingymebob here.
*/
The first line after the "**" is used as the short description of the item
(up to the full stop) and everything afterwards as the detailed description.
Separation
Always put a space in between a keyword like if/while and the condition, for example:
if (foo == bar)
NOT
if(foo == bar)
2. Indentation
Braces
Always put braces opening and closing blocks on separate lines, see the identation example. For example, place braces like this:
if (apples == "green")
{
cout << "Apples are green" << endl;
}
Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation,
for example:
int main()
{
<tab>if (condition)
<tab>{
<tab><tab>code
<tab>}
}
and not:
if (apples == "green") {
cout << "Apples are green" << endl;
}
The one exception to this is if you are declaring a class method which is only one line long, in that case the following is acceptable in most cases:
class foo : public bar
{
foo() { }
getrandomfoo() { return rand(); }
};
Templates
Where possible, use templates rather than #defines. Avoid use of RTTI.
Structs
Structs should be declared in the following fashion:
struct BodyPartBasket
{
int arms;
int legs;
int scrotalsacs;
};
and not like this:
typedef struct
{
int arms;
int legs;
int scrotalsacs;
} BodyPartBasket;
The second way is not required in C++ to be able to do this:
BodyPartBasket mybasket;
Plus, placing the name at the bottom of the declaration makes readability more difficult (as you have to scroll down to the bottom of the
struct to find its name).
(where possible, call them classes rather than structs.)
3. Separation
Variable naming
Class and struct names should be in camel case with a leading capital letter, for example "MyBagOfBones" and not "my_bag_of_bones" or
"mybagofbones". Variable names can be in either camel case with a leading capital letter or alternatively all lower case, so long as the same
naming convention is adhered to throughout the class. No classes or variables should be named in capitals unless this makes sense for the
name (for example "class DNS"). Constants and enum values should always be completely in CAPITALS and underscores may be used, for example:
enum DecayState
{
DECAYED_MOULDY = 0,
DECAYED_SMELLY = 1,
DECAYED_MAGGOTS = 2
};
All value names in an enum should be started with the same text which should be related in some way to the enum's use. For example "DNS_CNAME,
DNS_A, DNS_AAAA".
Always put a space in between a keyword like if/while and the condition,
for example:
if (foo == bar)
NOT
if(foo == bar)
Use of references
Wherever possible, when dealing with any complex class, pass a const reference rather than a copy of the class. For example:
MyThingy::MyThingy(const std::string &thingyvalue)
{
}
Of course, if you intended to change the string you can just omit the 'const'.
Use of char pointers
Whenever you use char pointers (char*, char**) try to use const equivalents. This is much safer and avoids ugly and dangerous casts. For example:
MyThingy::Thingify(const char* const* wotsits)
{
}
If it is possible without performance loss, consider avoiding char pointers altogether and using std::string instead.
4. Braces
Use of STL
For more information on use of STL in InspIRCd, please see the separate STL FAQ.
Always put braces opening and closing blocks on separate lines, see the
identation example. For example, place braces like this:
if (apples == "green")
{
cout << "Apples are green" << endl;
}
Making copies of data
Never ever make a copy of a piece of data unless it is absolutely necessary. For example, don't use strlcpy() to make a copy of the const char* string
returned by std::string::c_str(), if the change can be done to the std::string itself. The same goes for unnecessary variable assignments, especially
those which assign large classes.
and not:
if (apples == "green") {
cout << "Apples are green" << endl;
}
namespace std
Avoid the following:
using namespace std;
It might take a bit more typing, but things work better if you don't set (then later assume) the namespace -- specify it explicitly when you want to
use it.
The one exception to this is if you are declaring a class method which is
only one line long, in that case the following is acceptable in most cases:
class foo : public bar
{
foo() { }
getrandomfoo() { return rand(); }
};
Linefeeds
Unix linefeeds only please. We do not like to see our screens covered in ^M. :-)
Portability
Always make sure your code is portable to all supported operating systems, remember of course that as of 1.1.8 this includes windows. Don't write code
that only works on windows, or only works on Linux. Test your code on all platforms or ask for help from other developers who have the platforms you
want to test on.
5. Templates
new() and delete(), malloc() and free()
Apart from the fact that using malloc() and free() is bad practice in C++ code, you must never use malloc() or free() in InspIRCd, within its modules
or within the core. This is because if you use malloc() or free() in windows, the memory is claimed from the program's local heap. In windows, each
shared object (module, dll) has its own heap, which is protected from other dlls and executables. To get around this issue and allow more posix-like
memory access from other dlls in the program (other modules), InspIRCd overrides the operators new and delete to ensure that memory allocated by them
comes from the windows global heap. If you use malloc() and free() for this, the ircd will segfault when another module tries to access the memory you
have allocated!
Where possible, use templates rather than #defines. Avoid use of RTTI.
strdup()
As with malloc(), above, strdup() should be avoided. Where strdup() is absolutely necessary, use strnewdup() which is our strdup() implementation that
calls operator new instead of using malloc(). char arrays allocated by strnewdup() should be deleted with operator delete[].
CoreExport and DllImport
Prefix all types you want to import or export to other modules with CoreExport and DllImport macros. These do nothing in POSIX operating systems,
however in windows these are expanded to the instructions __declspec(dllimport) and __declspec(dllexport) respectively depending on where they are
used and how.
6. Structs
External Dependencies
If a module is compiled as standard, or the code is part of the core, you must not use any dependencies that are not available as standard on all
supported operating systems beyond libstdc++, libc, and whatever else is currently required to build the core. Modules which use nonstandard
dependencies belong in the modules/extra directory.
Structs should be declared in the following fashion:
struct BodyPartBasket
{
int arms;
int legs;
int scrotalsacs;
};
and not like this:
typedef struct
{
int arms;
int legs;
int scrotalsacs;
} BodyPartBasket;
Profiling and Performance
It is one thing to assume that code performs bad, it is another thing to prove that it actually is. A lot of experienced programmers talk about
'premature optimisation', and here is what it means: if you have a piece of code called once on startup that takes 10 seconds instead of one second to
run, and a piece of code that takes 0.05 seconds to run when it should take 0.01, and it is called once per second, the second piece of code is the
priority.
In other words, make sure that what you think is slow, and a performance problem in Insp actually is.
To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the
output files.
The second way is not required in C++ to be able to do this:
BodyPartBasket mybasket;
Plus, placing the name at the bottom of the declaration makes readability
more difficult (as you have to scroll down to the bottom of the struct to
find its name). (where possible, call them classes rather than structs.)
7. Variable naming
Class and struct names should be in camel case with a leading capital letter,
for example "MyBagOfBones" and not "my_bag_of_bones" or "mybagofbones".
Variable names can be in either camel case with a leading capital letter or
alternatively all lower case, so long as the same naming convention is
adhered to throughout the class. No classes or variables should be named in
capitals unless this makes sense for the name (for example "class DNS").
Constants and enum values should always be completely in CAPITALS and
underscores may be used, for example:
enum DecayState
{
DECAYED_MOULDY = 0,
DECAYED_SMELLY = 1,
DECAYED_MAGGOTS = 2
};
All value names in an enum should be started with the same text which should
be related in some way to the enum's use. For example "DNS_CNAME, DNS_A,
DNS_AAAA".
8. Use of references
Wherever possible, when dealing with any complex class, pass a const reference
rather than a copy of the class. For example:
MyThingy::MyThingy(const std::string &thingyvalue)
{
}
Of course, if you intended to change the string you can just omit the 'const'.
9. Use of char pointers
Whenever you use char pointers (char*, char**) try to use const equivalents.
This is much safer and avoids ugly and dangerous casts. For example:
MyThingy::Thingify(const char* const* wotsits)
{
}
If it is possible without performance loss, consider avoiding char pointers
altogether and using std::string instead.
10. Use of STL
For more information on use of STL in InspIRCd, please see the separate
STL FAQ.
11. Making copies of data
Never ever make a copy of a piece of data unless it is absolutely necessary.
For example, don't use strlcpy() to make a copy of the const char* string
returned by std::string::c_str(), if the change can be done to the std::string
itself. The same goes for unnecessary variable assignments, especially those
which assign large classes.
12. namespace std
Avoid the following:
using namespace std;
It might take a bit more typing, but things work better if you don't set
(then later assume) the namespace -- specify it explicitly when you want to
use it.
13. Linefeeds
Unix linefeeds only please. We do not like to see our screens covered in ^M.
14. Portability
Always make sure your code is portable to all supported operating systems,
remember of course that as of 1.1.8 this includes windows. Don't write code
that only works on windows, or only works on Linux. Test your code on all
platforms or ask for help from other developers who have the platforms you
want to test on.
* new() and delete(), malloc() and free()
Apart from the fact that using malloc() and free() is bad practice in C++
code, you must never use malloc() or free() in InspIRCd, within its modules
or within the core. This is because if you use malloc() or free() in windows,
the memory is claimed from the program's local heap.
In windows, each shared object (module, dll) has its own heap, which is
protected from other dlls and executables. To get around this issue and
allow more posix-like memory access from other dlls in the program (other
modules), InspIRCd overrides the operators new and delete to ensure that
memory allocated by them comes from the windows global heap. If you use
malloc() and free() for this, the ircd will segfault when another module
tries to access the memory you have allocated!
* strdup()
As with malloc(), above, strdup() should be avoided. Where strdup() is
absolutely necessary, use strnewdup() which is our strdup() implementation
that calls operator new instead of using malloc().
char arrays allocated by strnewdup() should be deleted with operator delete[].
* CoreExport and DllImport
Prefix all types you want to import or export to other modules with CoreExport
and DllImport macros. These do nothing in POSIX operating systems, however
in windows these are expanded to the instructions __declspec(dllimport) and
__declspec(dllexport) respectively depending on where they are used and how.
15. External Dependencies
If a module is compiled as standard, or the code is part of the core, you must
not use any dependencies that are not available as standard on all supported
operating systems beyond libstdc++, libc, and whatever else is currently
required to build the core. Modules which use nonstandard dependencies belong
in the modules/extra directory.
16. Profiling and Performance
It is one thing to assume that code performs bad, it is another thing to prove
that it actually is. A lot of experienced programmers talk about 'premature
optimisation', and here is what it means: if you have a piece of code called
once on startup that takes 10 seconds instead of one second to run, and a
piece of code that takes 0.05 seconds to run when it should take 0.01, and
it is called once per second, the second piece of code is the priority.
In other words, make sure that what you think is slow, and a performance
problem in Insp actually is.
To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind
bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the output
files.
+21
View File
@@ -1,3 +1,24 @@
Anope Version 1.9.4
--------------------
A Automatically set channel founder to the user with the highest access if there is no successor
A /chanserv clone command to copy settings from one channel to another.
A /chanserv mode command
A Ability for users to delete their own access in channels
A Added support for Plexus 3
A Readded in support for /cs op/deop/etc to op/deop you in all channels
A Added LDAP support
A Added live SQL support
A Added support for learning tracking/storing/locking all modes at runtime
A Added m_alias
A Added support for XMLRPC queries
A Added /botserv set msg
A Added /operserv config
A Added /ns cert
A Added /operserv login
F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists
F Some failed logic in /operserv exception that prevents proper exceptions from being added
F Fixed the anope_os_sxlines MySQL table and code to work after restarting
Anope Version 1.9.3
--------------------
A Added italics BotServ kicks support
+22
View File
@@ -1,3 +1,25 @@
Anope Version 1.9.4
-------------------
** ADDED CONFIGURATION DIRECTIVES **
memoserv:modules added ms_ignore
chanserv:modules added cs_clone and cs_mode
nickserv:suspendexpire and nickserv:forbidexpire added
chanserv:suspendexpire and chanserv:forbidexpire added
module added cs_entrymsg
nickserv:modules added ns_ajoin, ns_cert
options:nomlock added
log:target added globops
nickserv:confirmemailchanges added
operserv:modules added os_config, os_login
** MODIFIED CONFIGURATION DIRECTIVES **
operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop
renamed nickserv:preregexpire to nickserv:unconfirmedexpire
** DELETED CONFIGURATION DIRECTIVES **
opertype:commands removed operserv/umode
operserv:modules removed os_umode
Anope Version 1.9.3
------------------
** ADDED CONFIGURATION DIRECTIVES **
+6 -8
View File
@@ -162,7 +162,7 @@ Note: You should also read the README and FAQ files!
4) Starting Anope
Go into the directory where binaries were installed (by default, this is
~/services). Type ./services to launch Anope.
~/services/bin). Type ./services to launch Anope.
If there are syntax errors in the configuration file they will be
displayed on the screen. Correct them until there are no errors anymore.
@@ -180,21 +180,19 @@ Note: You should also read the README and FAQ files!
5) Setting up a crontab
A crontab entry will allow you to check periodically whether Anope is
still running, and restart it if not. You'll need to have Anope binaries
and data installed in the same directory for this to work without
modification.
still running, and restart it if not.
First rename the example.chk script that is in Anope path (by default,
this is ~/services) to services.chk and edit it. You'll need to modify
the CONFIGURATION part of the file. Then ensure that the file is marked
as executable by typing chmod +x services.chk, and try to launch the
this is ~/services/data) to services.chk and edit it. You'll need to
modify the CONFIGURATION part of the file. Then ensure that the file is
marked as executable by typing chmod +x services.chk, and try to launch the
script to see if it works (Anope must not be running when you do this ;))
When this is done, you'll have to add the crontab entry. Type crontab -e.
This will open the default text editor with the crontab file. Enter the
following (with correct path):
*/5 * * * * /home/ircd/services/services.chk >/dev/null 2>&1
*/5 * * * * /home/ircd/services/data/services.chk >/dev/null 2>&1
The */5 at the beginning means "check every 5 minutes". You may replace
the 5 with other another number if you want (but less than 60). Consult
+8 -77
View File
@@ -106,18 +106,10 @@ How To Add IRCd Support
23) TS6: Does the IRCd support TS6? Use 1 for yes, 0 for no.
24) Channel CIDR: Set to 1 if channel bans, excepts and invites
support CIDR masks. Expected syntax: *!*@ip/mask.
When set to 1, anope will only parse strict CIDR masks.
IRCd's that try to correct invalid CIDR's (like nefarious)
will need a custom implementation in the core.
Contact the anope Dev Team if this is the case.
Set to 0 if CIDR's are not supported by your IRCd.
25) Global TLD Prefix: Prefix used to send global messages, should probably
24) Global TLD Prefix: Prefix used to send global messages, should probably
be "$"
26) Max Modes: The max number of mode changes we can send in one line
25) Max Modes: The max number of mode changes we can send in one line
3) Modes
@@ -155,12 +147,6 @@ How To Add IRCd Support
ModeManager::AddChannelMode(new ChannelModeOper('O'));
The CMODE_FLOOD param also has its own class, but due to the wide range of
valid parameters accepted across IRCds, your protocol module MUST have the
IsValid function for this.
bool ChannelModeFlood::IsValid(const Anope::string &value) { }
4) Functions and Events
A brief word about functions and events. All events are captured by creating a Message struct
@@ -183,74 +169,19 @@ How To Add IRCd Support
5) CAPAB/PROTOCTL
Most IRCD send a CAPAB or PROTOCTL line so that they can work out what
the other end of the connection is capable of doing. Anope has a function
to read these lines and set itself up to to handle these events better.
When adding support for your ircd, take the following steps.
Most IRCDs send a CAPAB or PROTOCTL line so that they can work out what
the other end of the connection is capable of doing. The protocol module should
handle all of these without the cores knowledge with the exception of the following:
1) In the module constructor you must tell Anope what the uplink is capable of that
isn't already passed in the CAPAB/PROTOCTL, you do this by something similar to:
CapabType c[] = { CAPAB_NOQUIT, CAPAB_NICKIP, CAPAB_ZIP, CAPAB_TOKEN, CAPAB_SSJ3, CAPAB_NICK2, CAPAB_VL, CAPAB_TLKEXT, CAPAB_CHANMODE, CAPAB_SJB64, CAPAB_NICKCHARS };
for (unsigned i = 0; i < 11; ++i)
Capab.SetFlag(c[i]);
Anything else given to Anope in the CAPAB/PROTOCTL message will be handled later by CapabParse.
The available CAPAB options are:
--------------------------------------------------------------------------
Define | Description
----------------|------------|-----------|--------------------------------
----------------|---------------------------------------------------------
CAPAB_NOQUIT | NOQUIT protocol support
CAPAB_TSMODE | Chanmodes are timestamped
CAPAB_UNCONNECT | UNCONNECT protocol support
CAPAB_NICKIP | IP sent in the NICK line
CAPAB_NSJOIN | Smart SJOIN support
CAPAB_ZIP | Support for gzipped links
CAPAB_BURST | Supports BURST command
CAPAB_TS3 | Support for TS3 protocol
CAPAB_TS5 | Support for TS5 protocol
CAPAB_DKEY | DH-Key exchange using DKEY
CAPAB_DOZIP | Link traffic will be gzipped
CAPAB_DODKEY | Do DKEY with this link
CAPAB_QS | Supports quit storm removal
CAPAB_SCS | String Cache System support
CAPAB_PT4 | Support for PT4 protocol
CAPAB_UID | Support for UIDs
CAPAB_KNOCK | Supports KNOCK
CAPAB_CLIENT | Supports CLIENT
CAPAB_IPV6 | Support for IPv6 addresses
CAPAB_SSJ5 | Smart Join protocol 5 support
CAPAB_SN2 | Support for SN2 protocol
CAPAB_VHOST | Supports VHOST protocol
CAPAB_TOKEN | Supports s2s tokens
CAPAB_SSJ3 | Smart Join protocol 3 support
CAPAB_NICK2 | Support for extended NICK (v2)
CAPAB_UMODE2 | Supports UMODE2 command
CAPAB_VL | VLine information in info field
CAPAB_TLKEXT | Not 8, but 10 params in TKL's
CAPAB_CHANMODE | Channel modes are passed here
CAPAB_SJB64 | SJOIN timestamps are base64 encoded
CAPAB_NICKCHARS | Character set used by the IRCD for nicks
CAPAB_QS | Quitstorm - same as NOQUIT
2) Ensure that the CAPAB/PROTOCTL event his handled correctly.
A) In the function module constructor make sure that you have the
following two lines:
Message message_capab("CAPAB", event_capab);
B) Add the function to handle the event
bool event_capab(const Anope::string &source, const std::vector<Anope::string> &params)
{
CapabParse(params);
return true;
}
This function should call the CapabParse function which parses
the received CAPAB/PROTOCTL line.
You can override the default OnCapab method in IRCdMessage if required.
6) IRCDProto Class
+2
View File
@@ -27,6 +27,8 @@ Anope Mutli Language Support
If you have finished a language file translation and you want others to use it, please send it to team@anope.org
(don't forget to mention clearly your (nick)name, your e-mail and the language name). You'll of course get full credit for it.
NOTE: There is no guarantee we will use your work so please do not be offended if we say no thanks.
3) Using langages with modules
Module authors can easially add the ability to have their modules translated by adding _() around the strings they
+284 -321
View File
@@ -1,321 +1,284 @@
Anope -- a set of IRC services for IRC networks
-----------------------------------------------
Anope is 2003-2010 Anope Team <team@anope.org>.
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
This program is free but copyrighted software; see the file COPYING for
details.
Information about Anope may be found at http://www.anope.org/
Information about Epona may be found at http://www.epona.org/
Information about Services may be found at http://www.ircservices.esper.net/
Table of Contents
-----------------
1) Credits
2) Presentation
3) Installation
4) Command Line Options
5) Messages Translation
6) Contact and Mailing List
1) Credits
Anope is based on Lara's Epona version 1.4.14.
Epona is based on Andy Church's IRC Services version 4.3.3.
The original credits:
* Mauritz Antunes
Portuguese translation
* Jose R. Holzmann, Raul S. Villarreal
Spanish translation
* Andrew Kempe <theshadow@shadowfire.org>
News system
* <d.duca@eurcom.net>
Italian translation
* <mikado@holyfire.com>
Turkish translation
* Andrew Kempe <theshadow@shadowfire.org>
Session limiting
Epona credits:
* lara <lara@pegsoft.net>
Main coding
* CafeiN <oytuny@yahoo.com>
Turkish translation
* Sylvain Cresto aka tost <scresto@netsante.fr>
FreeBSD 5 patch
* Marcelo Conde Foscarini aka Bras <ircadmin@brmarket.net>
Portuguese translation
* Alvaro Toledo aka POLLITO <atoledo@keldon.org>
Spanish translation
* chemical <chemical@musicplay.de>
German translation
* shine <dh@shinewelt.de>
German translation
* Guven Guzelbey aka MeShGuL <guzelbey@cs.utk.edu>
Turkish translation
* Jordi Pujol <jordi.pujol@aujac.org>
Catalan translation
* Eva Dachs <evadachs@terra.es>
Catalan translation
* Toni Perez <toni.perez@aujac.org>
Catalan translation
* Sergios Karalis <sergios_k@hotmail.com>
Greek translation
* Thomas J. Stensas aka ShadowMaster <shadowmaster@shadow-realm.org>
Ultimate 3.x support
Anope credits:
* Adam Kramer <ribosome@anope.org>
* Adam <adam@anope.org>
* Alvaro Toledo <atoledo@keldon.org>
* Amanda Folson <amanda@anope.org>
* Andrew Berquist <vash@anope.org>
* Björn Stiddien <keeper@anope.org>
* Charles Kingsley <chaz@anope.org>
* Chris Hogben <heinz@anope.org>
* Daniel Engel <dane@zero.org>
* David <dv@diboo.net>
* David Narayan <jester@phrixus.net>
* David Robson <rob@anope.org>
* Daniele Nicolucci <jollino@sogno.net>
* Florian Schulze <certus@anope.org>
* Gabriel Acevedo H. <drstein@anope.org>
* Jan Milants <viper@anope.org>
* Jens Voss <dukepyrolator@anope.org>
* JH <jh@irc-chat.net>
* Joris Vink <joris@anope.org>
* Lucas Nussbaum <lucas@lucas-nussbaum.net>
* Mark Summers <mark@goopler.net>
* Matthew Beeching <jobe@invictachat.net>
* Naram Qashat <cyberbotx@anope.org>
* Pieter Bootsma <geniusdex@anope.org>
* Robin Burchell <w00t@inspircd.org>
* Thomas Juberg StensĂĄs <ShadowMaster@Shadow-Realm.org>
* Trystan .S Lee <trystan@nomadirc.net>
* openglx <openglx@brasnerd.com.br>
Anope Translations:
* GeniusDex <geniusdex@anope.org> (nl.l)
* Kein <kein-of@yandex.ru> (ru.l)
* Stuff <the.stuff@gmx.de> (de.l)
* Gabriel Acevedo H. <drstein@anope.org> (es.l)
* Janos Kapitany <sarkanyka@cjbchat.hu> (hun.l)
* Szymon S'wierkosz <szymek@adres.pl> (pl.l)
Anope uses the strlcat() and strlcpy() functions from OpenSSH 2.5.1p2.
These functions are copyrighted by Todd C. Miller:
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
2) Presentation
Anope is a set of Services for IRC networks that allows users to manage
their nicks and channels in a secure and efficient way, and administrators
to manage their network with powerful tools.
Currently available services are:
* NickServ, a powerful nickname manager that users can use to protect
themselves against nick stealing. Each user has its own nickname
group, that allows the user to register as many nicks as needed
while still being able to take profit of his privileges and to
modify the nick configuration. NickServ also has an optional
password retrieval feature.
* ChanServ, a powerful channel manager that helps users to administer
their channels in a totally customizable way. ChanServ has an
internal list of privileged users and banned users that controls
accesses on a per-channel basis. It eliminates all takeover
problems, because of its powerful op/unban/invite and even mass
deop and mass kick functions.
* MemoServ, an helpful companion that allows sending short messages
to offline users, that they can then read when they come online
later.
* BotServ, an original service that allows users to get a permanent,
friendly bot on their channels in an easy way. Each bot can be
configured to monitor the channels against floods, repetitions,
caps writing, and swearing, and to take appropriate actions. It
also can handle user-friendly commands (like !op, !deop, !voice,
!devoice, !kick, and many others), say a short greet message when
an user joins a channel, and even "take over" ChanServ actions such
as auto-opping users, saying the entry notice, and so on. This
service can be disabled if you want to save some bandwidth.
* OperServ, the IRCops' and IRC admins' black box, that allows them
to manage the list of network bans (also known as AKILL (DALnet) or
GLINE (Undernet)), to configure messages displayed to users when
they log on, to set modes and to kick users from any channel, to
send notices quickly to the entire network, and much more!
* HostServ, a neat service that allows users to show custom vHosts
(virtual hosts) instead of their real IP address; this only works
on daemons supporting ip cloaking, such as UnrealIRCd, UltimateIRCd
and ViagraIRCd.
Anope currently works with:
* Bahamut 1.4.27 or later (including 1.8)
* InspIRCd 1.1, 1.2, or 2.0
* Ratbox 2.0.6 or later
* UnrealIRCd 3.2 or later
Anope could also work with some of the daemons derived by the ones listed
above, but there's no support for them if they work or don't work.
3) Installation
See the INSTALL file for instruction on installing Anope.
4) Command Line Options
Normally, Anope can be run simply by invoking the "services" executable.
Any of the following command-line options can be specified to change
the behavior of Anope:
--debug Enable debugging mode; more info sent to log (give
option more times for more info)
--readonly Enable read-only mode; no changes to databases
allowed
--nofork Do not fork after startup; log messages will be
written to terminal
--noexpire Expiration routines won't be run at all
--version Display the version of Anope
--nothird Do not load the non-core modules specified
--protocoldebug Debug each incoming message after protocol parsing
--support Used for support, same as -debug -nofork -nothird
Upon starting, Anope will parse its command-line parameters then
(assuming the -nofork option is not given) detach itself and run in the
background. If Anope encounters a problem reading the database files or
cannot connect to its uplink server, it will terminate immediately;
otherwise, it will run until the connection is terminated (or a QUIT,
SHUTDOWN, or RESTART command is sent; see OperServ's help).
In the case of an error, an appropriate error message will be written to
the log file.
If Anope is run with the "--readonly" command-line option, it can serve as
a "backup" to the full version of services. A "full" version of services
(run without --readonly) will automatically reintroduce its pseudo-clients
(NickServ, ChanServ, etc.), while a "backup" services will not, thus
allowing full services to be brought up at any time without disrupting
the network (and without having to take backup services down beforehand).
The "--debug" option is useful if you find or suspect a problem in Anope.
Giving it once on the command line will cause all traffic to and from
services as well as some other debugging information to be recorded in
the log file; if you send a bug report, PLEASE include an excerpt from
the log file WITH DEBUGGING ACTIVE; we cannot emphasize enough how
important this is to tracking down problems. (You can also enable
debugging while Services is running using OperServ's SET DEBUG command.)
If you repeat use --debug=<level>, the debugging level will be increased,
which provides more detailed information but may also slow Anope down
considerably and make the log file grow dramatically faster. In general,
a debug level of 1 is sufficient for the coding team to be able to trace
a problem, because all network traffic is included and we can usually
reproduce the problem.
5) Messages Translations
Anope has a powerful option in NickServ allowing users to choose what
language it must use when sending messages to users. Messages are stored
in language files (located in the lang directory).
Anope is currently provided with thirteen languages: Catalan, Dutch,
English, French, German, Greek, Hungarian, Italian, Polish, Portuguese,
Russian, Spanish and Turkish. If you want to translate Anope messages
into another language, follow this instructions:
* Copy the lang/en_us.l file to a meaningful name (for example, if
you would like to translate messages in Spanish, you would rename
it to es.l).
* Edit the file with your favorite text editor. Carefully read the
instructions given at the top of the file, and start translating
the whole file. The file is big, so make sure you have some coffee
available ;) Try to avoid the use of English words as much as
possible. If the new language contains only a few 'special'
characters, try and use latin representations of it, if possible.
Remember that most clients are only capable of handling the
ISO-8859-1 charset. Of course, if you are translating Anope to a
language with a totally different charset, such as Russian, feel
free to use the one that suites it best (and the one that is in use
by most speakers of that language ;)).
* When this is done, you have two solutions: either patch Services
source code so they take in account the new language file
(basically, you'll have to modify lang/Makefile, language.c and
maybe services.h), or send us the translated file so we can make
the patch and include your language in the next Anope release.
* Note that there is a language tool on bin/langtool.pl that can aid
the verification process on newly created language files. Try to
use it before you submit a language file.
When new major releases come out, you'll not have to retranslate the
whole file; the Changes.lang file will help you to know which messages
were added, modified or deleted.
If you did a language file translation, and want to let others use it,
please send it to team@anope.org (don't forget to mention clearly your
(nick)name, your e-mail and the language name). You'll of course get full
credit for it, and will even get future final major releases before
anyone else to complete the translation!... ;)
6) Contact
For announcements and discussions about Anope, please visit our
Portal and Forums at http://www.anope.org/ -- make sure you register
yourself and your network to get full benefits.
If you read the documentation carefully, and didn't find the answer to
your question, feel free to post on the website forums or join our irc
channel (irc.anope.org #anope). Once you join our Support channel, just
type "? report" for instructions on how to report a Bug. Be as precise as
possible when asking a question, because we have no extraordinary powers
and can't guess things if they aren't provided. The more precise you are,
the sooner you'll be likely to get an answer.
If you think you found a bug, add it to the bug tracking system
(http://bugs.anope.org) and - again - be as precise as possible. Also say
whether the bug happens always or under what circumstances, and anything
that could be useful to track your bug down. If you wrote a patch, send
it over. :)
Anope -- a set of IRC services for IRC networks
-----------------------------------------------
Anope is 2003-2011 Anope Team <team@anope.org>.
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
This program is free but copyrighted software; see the file COPYING for
details.
Information about Anope may be found at http://www.anope.org/
Information about Epona may be found at http://www.epona.org/
Information about Services may be found at http://www.ircservices.esper.net/
Table of Contents
-----------------
1) Credits
2) Presentation
3) Installation
4) Command Line Options
5) Messages Translation
6) Contact and Mailing List
1) Credits
Anope is based on Lara's Epona version 1.4.14.
Epona is based on Andy Church's IRC Services version 4.3.3.
The original credits:
* Mauritz Antunes
Portuguese translation
* Jose R. Holzmann, Raul S. Villarreal
Spanish translation
* Andrew Kempe <theshadow@shadowfire.org>
News system
* <d.duca@eurcom.net>
Italian translation
* <mikado@holyfire.com>
Turkish translation
* Andrew Kempe <theshadow@shadowfire.org>
Session limiting
Epona credits:
* lara <lara@pegsoft.net>
Main coding
* CafeiN <oytuny@yahoo.com>
Turkish translation
* Sylvain Cresto aka tost <scresto@netsante.fr>
FreeBSD 5 patch
* Marcelo Conde Foscarini aka Bras <ircadmin@brmarket.net>
Portuguese translation
* Alvaro Toledo aka POLLITO <atoledo@keldon.org>
Spanish translation
* chemical <chemical@musicplay.de>
German translation
* shine <dh@shinewelt.de>
German translation
* Guven Guzelbey aka MeShGuL <guzelbey@cs.utk.edu>
Turkish translation
* Jordi Pujol <jordi.pujol@aujac.org>
Catalan translation
* Eva Dachs <evadachs@terra.es>
Catalan translation
* Toni Perez <toni.perez@aujac.org>
Catalan translation
* Sergios Karalis <sergios_k@hotmail.com>
Greek translation
* Thomas J. Stensas aka ShadowMaster <shadowmaster@shadow-realm.org>
Ultimate 3.x support
Anope credits:
* Adam Kramer <ribosome@anope.org>
* Adam <adam@anope.org>
* Alvaro Toledo <atoledo@keldon.org>
* Amanda Folson <amanda@anope.org>
* Andrew Berquist <vash@anope.org>
* Björn Stiddien <keeper@anope.org>
* Charles Kingsley <chaz@anope.org>
* Chris Hogben <heinz@anope.org>
* Daniel Engel <dane@zero.org>
* David <dv@diboo.net>
* David Narayan <jester@phrixus.net>
* David Robson <rob@anope.org>
* Daniele Nicolucci <jollino@sogno.net>
* Florian Schulze <certus@anope.org>
* Gabriel Acevedo H. <drstein@anope.org>
* Jan Milants <viper@anope.org>
* Jens Voss <dukepyrolator@anope.org>
* JH <jh@irc-chat.net>
* Joris Vink <joris@anope.org>
* Lee Holmes <lethality@anope.org>
* Lucas Nussbaum <lucas@lucas-nussbaum.net>
* Mark Summers <mark@goopler.net>
* Matthew Beeching <jobe@invictachat.net>
* Naram Qashat <cyberbotx@anope.org>
* Phil Lavin <phil@anope.org>
* Pieter Bootsma <geniusdex@anope.org>
* Robin Burchell <w00t@inspircd.org>
* Sean Roe <therock247uk@anope.org>
* Sebastian V <hal9000@anope.org>
* Thomas Juberg StensĂĄs <ShadowMaster@Shadow-Realm.org>
* Trystan .S Lee <trystan@nomadirc.net>
* openglx <openglx@brasnerd.com.br>
Anope Translations:
* GeniusDex <geniusdex@anope.org> (nl.l)
* Kein <kein-of@yandex.ru> (ru.l)
* Maik Funke <Han@mefalcon.org> (de.l)
* Gabriel Acevedo H. <drstein@anope.org> (es.l)
* Janos Kapitany <sarkanyka@cjbchat.hu> (hun.l)
* Szymon S'wierkosz <szymek@adres.pl> (pl.l)
* Christopher N. <saka@epiknet.org> (fr.l)
* Yusuf Kurekci <ysfm.20@gmail.com> (tr.l)
Anope uses the strlcat() and strlcpy() functions from OpenSSH 2.5.1p2.
These functions are copyrighted by Todd C. Miller:
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
2) Presentation
Anope is a set of Services for IRC networks that allows users to manage
their nicks and channels in a secure and efficient way, and administrators
to manage their network with powerful tools.
Currently available services are:
* NickServ, a powerful nickname manager that users can use to protect
themselves against nick stealing. Each user has its own nickname
group, that allows the user to register as many nicks as needed
while still being able to take profit of his privileges and to
modify the nick configuration. NickServ also has an optional
password retrieval feature.
* ChanServ, a powerful channel manager that helps users to administer
their channels in a totally customizable way. ChanServ has an
internal list of privileged users and banned users that controls
accesses on a per-channel basis. It eliminates all takeover
problems, because of its powerful op/unban/invite and even mass
deop and mass kick functions.
* MemoServ, an helpful companion that allows sending short messages
to offline users, that they can then read when they come online
later.
* BotServ, an original service that allows users to get a permanent,
friendly bot on their channels in an easy way. Each bot can be
configured to monitor the channels against floods, repetitions,
caps writing, and swearing, and to take appropriate actions. It
also can handle user-friendly commands (like !op, !deop, !voice,
!devoice, !kick, and many others), say a short greet message when
an user joins a channel, and even "take over" ChanServ actions such
as auto-opping users, saying the entry notice, and so on. This
service can be disabled if you want to save some bandwidth.
* OperServ, the IRCops' and IRC admins' black box, that allows them
to manage the list of network bans (also known as AKILL (DALnet) or
GLINE (Undernet)), to configure messages displayed to users when
they log on, to set modes and to kick users from any channel, to
send notices quickly to the entire network, and much more!
* HostServ, a neat service that allows users to show custom vHosts
(virtual hosts) instead of their real IP address; this only works
on daemons supporting ip cloaking, such as UnrealIRCd.
Anope currently works with:
* Bahamut 1.4.27 or later (including 1.8)
* InspIRCd 1.1, 1.2, or 2.0
* Ratbox 2.0.6 or later
* UnrealIRCd 3.2 or later
* Plexus 3 or later
Anope could also work with some of the daemons derived by the ones listed
above, but there's no support for them if they work or don't work.
3) Installation
See the INSTALL file for instruction on installing Anope.
4) Command Line Options
Normally, Anope can be run simply by invoking the "services" executable.
Any of the following command-line options can be specified to change
the behavior of Anope:
--debug Enable debugging mode; more info sent to log (give
option more times for more info)
--readonly Enable read-only mode; no changes to databases
allowed
--nofork Do not fork after startup; log messages will be
written to terminal
--noexpire Expiration routines won't be run at all
--version Display the version of Anope
--nothird Do not load the non-core modules specified
--protocoldebug Debug each incoming message after protocol parsing
--support Used for support, same as -debug -nofork -nothird
Upon starting, Anope will parse its command-line parameters then
(assuming the -nofork option is not given) detach itself and run in the
background. If Anope encounters a problem reading the database files or
cannot connect to its uplink server, it will terminate immediately;
otherwise, it will run until the connection is terminated (or a QUIT,
SHUTDOWN, or RESTART command is sent; see OperServ's help).
In the case of an error, an appropriate error message will be written to
the log file.
If Anope is run with the "--readonly" command-line option, it can serve as
a "backup" to the full version of services. A "full" version of services
(run without --readonly) will automatically reintroduce its pseudo-clients
(NickServ, ChanServ, etc.), while a "backup" services will not, thus
allowing full services to be brought up at any time without disrupting
the network (and without having to take backup services down beforehand).
The "--debug" option is useful if you find or suspect a problem in Anope.
Giving it once on the command line will cause all traffic to and from
services as well as some other debugging information to be recorded in
the log file; if you send a bug report, PLEASE include an excerpt from
the log file WITH DEBUGGING ACTIVE; we cannot emphasize enough how
important this is to tracking down problems. (You can also enable
debugging while Services is running using OperServ's SET DEBUG command.)
If you repeat use --debug=<level>, the debugging level will be increased,
which provides more detailed information but may also slow Anope down
considerably and make the log file grow dramatically faster. In general,
a debug level of 1 is sufficient for the coding team to be able to trace
a problem, because all network traffic is included and we can usually
reproduce the problem.
5) Messages Translations
Please see LANGUAGE for this information
6) Contact
For announcements and discussions about Anope, please visit our
Portal and Forums at http://www.anope.org/ -- make sure you register
yourself to get full benefits.
If you read the documentation carefully, and didn't find the answer to
your question, feel free to post on the website forums or join our irc
channel (irc.anope.org #anope). Once you join our Support channel be as
precise as possible when asking a question, because we have no extraordinary
powers and can't guess things if they aren't provided.
The more precise you are the sooner you'll be likely to get an answer.
If you think you found a bug, add it to the bug tracking system
(http://bugs.anope.org) and - again - be as precise as possible. Also say
whether the bug happens always or under what circumstances, and anything
that could be useful to track your bug down. If you wrote a patch, send
it over. :)
+17 -30
View File
@@ -3,56 +3,43 @@ Legend:
? = unsure
+ = in progress
1.9.3
1.9.4
-----
[x] Add in a subcommand system, ns_set, cs_set, etc.
[x] Threading
[x] Mail sending needs to be threaded
[x] process_numlist needs to die
[x] SList needs to die
[x] SSL
[x] Command handling system needs to die, strtok() needs to die more
[x] Asynchronous DNS
[x] Hashing system for storing just about everything needs to die
[x] Add support for +k, +q, etc type umodes
[x] Language system is disgusting, it must die.
[x] Modules should also have a way to add strings programatically
[x] Should be able to add many strings by dropping a file in a set location.
[x] Config bailing on /os reload needs to be non fatal
[x] AutoID needs to be able to live through /os restart, current system is just annoying.
[x] SQL tables need to changed to have references etc
[x] Merge NS INFO blah ALL with NS INFO blah, if you're requesting info, you really want the info anyway.
[x] More "friendly" date displays of some things like registration time ("November 7th 2006 (2 years, 0 months, 0 days ago)")
[?] Remote identification
[x] Move a (lot) of stuff to class members as a defined interface rather than copypasta everywhere (ns_set, ns_saset!)
[x] Store vhosts in SQL.
[x] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
[x] Allow users to delete their own access
[x] ChanServ CLONE command
[x] XMLRPC to execute commands and get data from Anope
[+] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
[x] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc.
[ ] understanding extbans for /cs unban etc.
[ ] (optional?) A way to confirm email changes by users
[ ] Auto identify through SSL key
[ ] Optional os_login system that can also use SSL keys.
[ ] os_info module to show useful configuration settings to services opers.
[ ] Remove nick requests. Instead use an unconfirmed nick group which cant recieve umode +r and auto expires after 1d?
[ ] LDAP
Future
------
[+] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc.
[ ] XMLRPC to execute commands and get data from Anope
[ ] NS IDENTIFY changes
[?] Last failed identify? Maybe more useful for sopers only, so users don't get unnecessarily worried
[?] Last successful login time/ip? perhaps both of these should be a new nick setting
[ ] NS INFO: seperate field for last seen realhost, shown to SRA only
[ ] NS SUSPEND: show suspender and reason, probably to sopers only (see CS SUSPEND)
[ ] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
[ ] Allow channel founders to change the fantasy trigger for their channel.
[ ] CIDR Akills, session exceptions, etc
[ ] Language charset stuff, including collation (1.9.1? phoenix?)
[ ] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
[?] Language charset stuff, including collation (1.9.1? phoenix?)
[?] a way for a module to queue itself (or even another module) for unloading
[ ] Useful/common "third party" modules to core distro
[ ] NS AJOIN
[ ] CS ENTRYMSG
[x] CS ENTRYMSG
[?] Don't allow soper accounts to expire
[?] Reason for CS SET RESTRICTED
[x] AKILL/SGLINE/etc..
[x] Setter
[x] Time added
[+] Time modified (can they be modified?)
[ ] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human)
[x] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human)
[x] Reason
[ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs
[ ] HS ACTIVATE -ALL (rob sez this all needs reviewing)
[?] Drop CS SET ENTRYMSG, replace with a 'news' type system? (limited to a configured number of items, default 3)
+2 -2
View File
@@ -10,10 +10,10 @@ Anope Bundled Tools
options. To use the SMTP client instead of sendmail, find the line in your
services configuration file (services.conf) that defines sendmailpath. On
that line, change the path to your services installation directory, then
followed by "tools/anopesmtp" and the IP address of a valid SMTP server. It
followed by "bin/anopesmtp" and the IP address of a valid SMTP server. It
should look like this:
sendmailpath = "/home/anope/services/tools/anopesmtp 127.0.0.1"
sendmailpath = "/home/anope/services/bin/anopesmtp 127.0.0.1"
If the SMTP client doesn't send mail, or if there's an other problem with
it, you can compile it in debug mode. To do this, open anopesmtp.cpp, and look
-309
View File
@@ -1,309 +0,0 @@
Troubleshooting Guide for Anope 1.9
------------------------------------------------
NOTE:
An updated version of this guide can be found on our wiki:
http://wiki.anope.org/index.php/Troubleshooting
Table of Contents
-----------------
1) General
1.1) Anope complains in the logfile about being unable to load the default
language.
1.2) Anope spricht kein Deutsch!, etc. (Anope doesn't speak my language!)
1.3) I selected a language other than English, but sometimes Anope sends
responses in English instead.
1.4) Anope always dies after about five minutes, saying "FATAL ERROR! Can't
back up nick.db".
1.5) Anope crashed with a segmentation fault.
1.6) I've found a bug that's not mentioned here or in the README or BUGS
files. What should I do?
1.7) My FreeBSD box complains about 'Shared object "nss_dns.so.1" not
found'
1.8) Anope and long (more then 30 character) nicknames.
2) Installation / Configuration
2.1) When I run "make", I get an error message like "missing separator",
"Unassociated shell command", "Unexpected end of line seen", etc.
2.2) I get an error like "Makefile.inc not found".
2.3) I typed "./services" at the command line, but nothing happened!
2.4) Whenever I start Anope, I get a message on my IRC server saying
"connection refused" or something similar, and Anope gives an error
message from the server saying "Closing Link: ...".
2.5) My IRC server is giving me messages like "Connection to
services.whatever.net[127.0.0.1] activated" and then "Access denied --
no N line". Why?
2.6) When I say "/connect services.*", it doesn't work!
2.7) Anope starts up okay, but if I try to register a nickname, it comes
back with "Sorry, registration failed."
2.8) Anope reports (via /stats u or /msg OperServ STATS) a different number
of users online than I get from doing /lusers.
3) BotServ
3.1) How do I add bots to BotServ?
3.2) Why do kick triggers and fantasy commands fail to work with my Bahamut
IRCd?
4) ChanServ
4.1) Anope's channel mode setting doesn't work. I can't set modes with
OperServ, and every time ChanServ tries to set a mode, my server
reverses the change.
4.2) Anope ignored the SET SUCCESSOR setting and deleted a channel when the
founder expired.
4.3) How to auto voice all those whom join my #channel?
4.4) Channel options like RESTRICTED or SECUREOPS don't work. What's wrong?
5) OperServ
5.1) Using the OperServ JUPE command results in server messages like
"Server juped.server introduced by non-hub server services.my.net".
5.2) When I add an AKILL, the users matching it don't get killed.
5.3) Trying to use OperServ gives me "Access denied".
5.4) I can't get /OS UMODES and /OS SVSNICK to work!
5.5) What is a Super-Admin? How does it work? Why might it not work?
-------------------------------------------------------------------------------
1) General
1.1) Anope complains in the logfile about being unable to load the default
language.
You forgot to run "make install".
1.2) Anope spricht kein Deutsch!, etc. (Anope doesn't speak my language!)
See section 5 of the README file.
1.3) I selected a language other than English, but sometimes Anope sends
responses in English instead.
Some language files are not complete--in other words, they only have a
translation of some of the message Anope uses. In this case, the
missing messages will be displayed in English. You can either wait for
the primary translator to provide us with a translation, or do the
translation yourself and send us the messages translated into your
language.
1.4) Anope always dies after about five minutes, saying "FATAL ERROR! Can't
back up nick.db".
Make sure that the user Anope runs as has write access to the data
directory, and that the data directory actually exists (the latter
shouldn't be a problem if you ran the Config script). This means Anope
needs write and execute permission on the data directory itself and execute
permission on every parent directory of the data directory.
1.5) Anope crashed with a segmentation fault.
See if you can reproduce this by doing a certain sequence of things. If
so, please report it to us (see part 6 of README file). If not, you're
probably out of luck; if you like, you can report it to us anyway, but
chances are it won't get fixed if we don't have instructions on reproducing
it. If you do have such a problem, you may find the crontab utility useful
for dealing with it.
Also, see the DumpCore directive in the configuration file. It allows Anope
to dump its core whenever it's segfaulting, usually calling it core and
placing it into Anope's main directory. Open up gdb by issuing the
following command at your shell:
* gdb services core
(of course replacing 'core' with the name of the core if different) and
type 'bt' at the gdb prompt. After that, send us the output you got and
keep the core file in a safe place, in case we need it to dig deeper into
the problem.
1.6) I've found a bug that's not mentioned here or in the README or BUGS files.
What should I do?
See section 6 of the README file.
1.7) My FreeBSD box complains about 'Shared object "nss_dns.so.1" not found'
We haven't figured out the exact cause yet, but as a quickfix you can
delete the /etc/nsswitch.conf file. Please keep in mind that removing a
configuration file can be dangerous, so only do this if you know what you
are doing.
1.8) Anope and long (more then 30 character) nicknames.
By default, Anope only supports nicknames up to 30 characters (NICKLEN=30).
If your IRCd allows for longer nicknames or has been modified to do so
Anope will start logging a lot of ("NICK from nonexistent nick") messages.
This is because once a user uses a nick that is too long for Anope to handle,
Anope loses track of the user for the remainder of the session.
It is POSSIBLE but not NOT RECOMMENDED to extend the maximum length of nicknames
Anope can track, however this will also break database compatibility. DBs saved
with Anope set to allow for example 40 chars cannot be read by a clean Anope
installation and vice versa. So changing the maximum nick length is only possible
when starting with fresh databases and even then the consequences of this are
UNTESTED.
In order to change the maximum internal nick length, change the NICKMAX setting
in include/config.h, recompile anope and start without databases.
2) Installation / Configuration
2.1) When I run "make", I get an error message like "missing separator",
"Unassociated shell command", "Unexpected end of line seen", etc.
Your make program isn't compatible with the Makefile for Anope. The
Makefile was designed to work with GNU make, and as such may not work on
other systems' "make" programs. If you get an error from "make", obtain
GNU make from ftp://prep.ai.mit.edu/pub/gnu/make/ (or wherever you prefer) and
use it instead of your system's default "make". Note that GNU make may
already be installed on your system; try using the command "gmake" instead
of "make".
The make programs bundled with SunOS/Solaris and FreeBSD have been reported
not to work; you will need to use GNU make on these systems.
2.2) I get an error like "Makefile.inc not found".
You forgot to run the Config script first. See the INSTALL file for
compilation instructions.
2.3) I typed "./services" at the command line, but nothing happened!
Anope puts itself in the background when it starts, so you get your shell
prompt right back. Meanwhile, Anope will continue setting up, then connect
to the IRC server specified in services.conf (or on the command line). If
it doesn't connect, you probably specified the wrong IRCd or RemoteServer in
the configuration file. Check to make sure that you are actually running one of
the supported IRCds, also. A list of supported IRCds can be found in the README
file.
You can also check the log file (services.log by default) for error
messages. Starting services with the -support command line option
will prevent it from running in the background will output the
messages written to the log file to the console as well. Please note that this
will also prevent 3rd party modules from loading and will put Anope into
debug mode.
2.4) Whenever I start Anope, I get a message on my IRC server saying
"connection refused" or something similar, and Anope gives an error
message from the server saying "Closing Link: ...".
See section 3 of the INSTALL file.
2.5) My IRC server is giving me messages like "Connection to
services.whatever.net[127.0.0.1] activated" and then "Access denied -- no
N line". Why?
This is typically caused by including a port number in the C:line for
services, which tells your server to try to autoconnect to it (depending on
the class (Y:line) settings). This is not what you want, because Anope
will connect to the server itself, but does not listen for servers to
connect to it. The solution is to remove the port number from the C:line.
2.6) When I say "/connect services.*", it doesn't work!
You cannot /connect services. When you start Anope, it will attempt to
connect to the server you specified in services.conf. Please see the answer
above for more information.
2.7) Anope starts up okay, but if I try to register a nickname, it comes back
with "Sorry, registration failed."
Make sure you've selected the correct IRC server type in the configure
script; see section 3 of the INSTALL file for details.
2.8) Anope reports (via /stats u or /msg OperServ STATS) a different number of
users online than I get from doing /lusers.
Anope doesn't count its own pseudo-clients (NickServ, ChanServ, etc.) in
its user count, while the IRC server does.
3) BotServ
3.1) How do I add bots to BotServ?
Read /msg BotServ HELP and /msg BotServ HELP BOT. Note that you need to be
opered up and identified as a Services Administrator in Anope before you
can use the BOT command.
3.2) Why do kick triggers and fantasy commands fail to work with my Bahamut
IRCd?
Bahamut allows you to setup a server as 'serviceshub'. This will filter
certain data that services usually don't need to process. This option also
filters channel messages, because DALnet's services have no use for them.
Anope parses the channel messages for kick triggers and fantasy commands.
To make sure these work the server type of the hub they're linked to should
be simply 'hub' and not 'serviceshub'.
4) ChanServ
4.1) Anope's channel mode setting doesn't work. I can't set modes with
OperServ, and every time ChanServ tries to set a mode, my server reverses
the change.
Make sure EVERY server on your network has a U: line for Services in
ircd.conf, for example:
U:services.whatever.net:*:*
4.2) Anope ignored the SET SUCCESSOR setting and deleted a channel when the
founder expired.
Normally, this is because the successor had too many channels registered.
In this case, you will see an entry in the log file like the following:
[date] Successor (SuccessorNick) of channel #somechannel owns too many
channels, deleting channel #somechannel
If you don't get a message like this or you can verify that the successor
wasn't running into the channel limit, please report it using the
bug-reporting procedure in section 6 of the README file.
4.3) How to auto voice all those whom join my #channel?
Execute the following commands (/cs is an alias for /msg ChanServ):
/cs set #channel secure off
/cs set #channel xop off
/cs levels #channel set AUTOVOICE -1
4.4) Channel options like RESTRICTED or SECUREOPS don't work. What's wrong?
Make sure that you didn't put any of your normal IRCd's as a ULined server
in Anope. Some access checks for clients from ULined servers are skipped to
avoid fights between the ULined servers. This is usually only useful when
you have a statistics server connected to your network.
5) OperServ
5.1) Using the OperServ JUPE command results in server messages like "Server
juped.server introduced by non-hub server services.my.net".
Services' uplink must have an H: line for Services in the ircd.conf file,
which looks something like:
H:*::services.whatever.net
5.2) When I add an AKILL, the users matching it don't get killed.
Use the AkillOnAdd configuration directive.
5.3) Trying to use OperServ gives me "Access denied".
Check that you're opered on your IRCd (ie, moded +o)
Check that you're identified to a nickname listed within an opertype allowed to do the command you're trying.
Check whether you can use /msg operserv staff
5.4) I can't get /OS UMODES and /OS SVSNICK to work!
You need to be a SuperAdmin to be able to use these commands.
5.5) What is a Super-Admin? How does it work? Why might it not work?
SuperAdmin's have extra privileges, including being founder on all
channels. It must be activated on a per user basis and is only available to
Services Roots. It is set using OperServ and is not persistent. It only
works if SuperAdmin is not commented in the services configuration file,
which is commented out by default. Read /msg OperServ HELP SET SUPERADMIN
for further help.
+1 -1
View File
@@ -104,7 +104,7 @@ Anope for Windows
Building Anope with gettext requires libintl, libiconv, libgcc and
libmingex. We have precompiled these libraries for you that you may
use if you want. They are avaiable at http://anope.org/downloads/anope-extra.zip
The OpenSSL and MySQL header files and libraries are also included in
The OpenSSL, MySQL, and OpenLDAP header files and libraries are also included in
this package. Once downloaded and extracted, you should run install.bat
then give Config the path to the new 'installed' directory.
+26
View File
@@ -0,0 +1,26 @@
Starting with Anope 1.9.4 XMLRPC using PHP's xmlrpc_encode_request and xmlrpc_decode functions is supported.
This allows external applications, such as websites, to execute remote procedure calls to Anope in real time.
Currently there are 5 supported XMLRPC calls, provided by m_xmlrpc_main:
checkAuthetication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password
is correct for the account name, useful for making login pages on websites.
command - Takes three parameters, a service name (BotServ, ChanServ, NickServ), a user name (whether online or not), and the command
to execute. This will execute a the given command to Anope using the given service name. If the user given is online, the
command reply will go to them, if not it is returned by XMLRPC.
stats - Takes no parameters, returns miscellaneous stats that can be found in the /operserv stats command.
channel - Takes one parameter, a channel name, and returns real time information regarding that channel, such as users, modes
(ban lists and such), topic etc.
user - Takes one parameter, a user name, and returns real time information regarding that user.
XMLRPC was designed to be used with db_mysql, and will not return any information that can be pulled from the SQL
database, such as accounts and registered channel information. It is instead used for pulling realtime data such
as users and channels currently onlive. For examples on how to use these calls in PHP, see xmlrpc.php in docs/XMLRPC.
Also note that the parameter named "id" is reserved for query ID. If you pass a query to Anope containing a value for id. it will
be stored by Anope and the same id will be passed back in the result.
+101
View File
@@ -0,0 +1,101 @@
<?php
/* XMLRPC Functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
*/
class AnopeXMLRPC
{
private $Host, $Bind, $Port;
private $Socket;
function __construct($Host, $Port, $Bind = NULL)
{
$this->Host = $Host;
$this->Port = $Port;
$this->Bind = $Bind;
$this->Socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($Bind && socket_bind($this->Socket, $this->Bind) == false)
$his->Socket = false;
if (socket_connect($this->Socket, $this->Host, $this->Port) == false)
$this->Socket = false;
}
function __destruct()
{
@socket_close($this->Socket);
}
/** Run an XMLRPC command. Name should be a query name and params an array of parameters, eg:
* $this->RunXMLRPC("checkAuthentication", array("adam", "qwerty"));
* If successful returns back an array of useful information.
*
* Note that $params["id"] is reserved for query ID, you may set it to something if you wish.
* If you do, the same ID will be passed back with the reply from Anope.
*/
function RunXMLRPC($name, $params)
{
$xmlquery = xmlrpc_encode_request($name, $params);
socket_write($this->Socket, $xmlquery);
$inbuf = socket_read($this->Socket, 4096);
$inbuf = substr($inbuf, strpos($inbuf, "\r\n\r\n") + 4);
$response = xmlrpc_decode($inbuf);
if (isset($response[0]))
return $response[0];
return NULL;
}
/** Do Command on Service as User, eg:
* $anope->DoCommand("ChanServ", "Adam", "REGISTER #adam");
* Returns an array of information regarding the command execution, if
* If 'online' is set to yes, then the reply to the command was sent to the user on IRC.
* If 'online' is set to no, then the reply to the command is in the array member 'return'
*/
function DoCommand($Service, $User, $Command)
{
return $this->RunXMLRPC("command", array($Service, $User, $Command));
}
/** Check an account/nick name and password to see if they are valid
* Returns the account display name if valid
*/
function CheckAuthentication($Account, $Pass)
{
$ret = $this->RunXMLRPC("checkAuthentication", array($Account, $Pass));
if ($ret && $ret["result"] == "Success")
return $ret["account"];
return NULL;
}
/* Returns an array of misc stats regarding Anope
*/
function DoStats()
{
return $this->RunXMLRPC("stats", NULL);
}
/* Look up data for a channel
* Returns an array containing channel information, or an array of size one
* (just containing the name) if the channel does not exist
*/
function DoChannel($Channel)
{
return $this->RunXMLRPC("channel", NULL);
}
/* Like DoChannel(), but different.
*/
function DoUser($User)
{
return $this->RunXMLRPC("user", array($User));
}
}
?>
+28 -1
View File
@@ -16,5 +16,32 @@ if(NOT WIN32)
add_to_cpack_ignored_files("version.h$" TRUE)
endif(NOT WIN32)
set(PCH_SOURCES_GCH "")
if(CMAKE_COMPILER_IS_GNUCXX)
string(REPLACE " " ";" PCH_CXXFLAGS ${CXXFLAGS})
file(GLOB INCLUDE_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
remove_item_from_list(INCLUDE_SRCS "version.h")
set(PCH_SOURCES "module.h;modules.h;services.h")
foreach(PCH_SOURCE ${PCH_SOURCES})
set(PCH_EXTRAFLAGS "")
if(DEBUG_BUILD)
set(PCH_EXTRAFLAGS "-g")
endif(DEBUG_BUILD)
if(PCH_SOURCE STREQUAL "module.h")
set(PCH_EXTRAFLAGS ${PCH_EXTRAFLAGS} -fPIC)
endif(PCH_SOURCE STREQUAL "module.h")
if(GETTEXT_INCLUDE)
set(PCH_GETTEXT_INCLUDE "-I${GETTEXT_INCLUDE}")
endif(GETTEXT_INCLUDE)
set(PCH_SOURCES_GCH "${PCH_SOURCES_GCH};${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch")
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
COMMAND ${CMAKE_CXX_COMPILER} ARGS ${PCH_CXXFLAGS} ${PCH_EXTRAFLAGS} ${PCH_GETTEXT_INCLUDE} -I${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${PCH_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
DEPENDS ${INCLUDE_SRCS} VERBATIM
)
endforeach(PCH_SOURCE ${PCH_SOURCES})
endif(CMAKE_COMPILER_IS_GNUCXX)
# Add a custom target to the above file
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version.h)
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version.h ${PCH_SOURCES_GCH})
+54 -29
View File
@@ -5,15 +5,12 @@
class NickAlias;
class NickCore;
class NickRequest;
typedef unordered_map_namespace::unordered_map<Anope::string, NickAlias *, ci::hash, std::equal_to<ci::string> > nickalias_map;
typedef unordered_map_namespace::unordered_map<Anope::string, NickCore *, ci::hash, std::equal_to<ci::string> > nickcore_map;
typedef unordered_map_namespace::unordered_map<Anope::string, NickRequest *, ci::hash, std::equal_to<ci::string> > nickrequest_map;
extern CoreExport nickalias_map NickAliasList;
extern CoreExport nickcore_map NickCoreList;
extern CoreExport nickrequest_map NickRequestList;
/* NickServ nickname structures. */
@@ -41,6 +38,10 @@ enum NickNameFlag
NS_END
};
const Anope::string NickNameFlagStrings[] = {
"BEGIN", "FORBIDDEN", "NO_EXPIRE", "HELD", "COLLIDED", ""
};
/** Flags set on NickCores
*/
enum NickCoreFlag
@@ -81,23 +82,17 @@ enum NickCoreFlag
NI_AUTOOP,
/* This nickcore is forbidden, which means the nickalias for it is aswell */
NI_FORBIDDEN,
/* If set means the nick core does not have their email addrses confirmed.
*/
NI_UNCONFIRMED,
NI_END
};
class CoreExport NickRequest : public Extensible
{
public:
NickRequest(const Anope::string &nickname);
~NickRequest();
Anope::string nick;
Anope::string passcode;
Anope::string password;
Anope::string email;
time_t requested;
time_t lastmail; /* Unsaved */
const Anope::string NickCoreFlagStrings[] = {
"BEGIN", "KILLPROTECT", "SECURE", "MSG", "MEMO_HARDMAX", "MEMO_SIGNON", "MEMO_RECEIVE",
"PRIVATE", "HIDE_EMAIL", "HIDE_MASK", "HIDE_QUIT", "KILL_QUICK", "KILL_IMMED",
"MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "FORBIDDEN", "UNCONFIRMED", ""
};
class NickCore;
@@ -157,32 +152,21 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
Anope::string greet; /* Greet associated to the nick */
Anope::string language; /* Language name */
std::vector<Anope::string> access; /* Access list, vector of strings */
std::vector<Anope::string> cert; /* ssl certificate list, vector of strings */
MemoInfo memos;
uint16 channelcount; /* Number of channels currently registered */
OperType *ot;
Oper *o;
/* Unsaved data */
time_t lastmail; /* Last time this nick record got a mail */
std::list<NickAlias *> aliases; /* List of aliases */
/** Check whether this opertype has access to run the given command string.
* @param cmdstr The string to check, e.g. botserv/set/private.
* @return True if this opertype may run the specified command, false otherwise.
*/
virtual bool HasCommand(const Anope::string &cmdstr) const;
/** Checks whether this account is a services oper or not.
* @return True if this account is a services oper, false otherwise.
*/
virtual bool IsServicesOper() const;
/** Check whether this opertype has access to the given special permission.
* @param privstr The priv to check for, e.g. users/auspex.
* @return True if this opertype has the specified priv, false otherwise.
*/
virtual bool HasPriv(const Anope::string &privstr) const;
/** Add an entry to the nick's access list
*
* @param entry The nick!ident@host entry to add to the access list
@@ -222,6 +206,47 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
* Deletes all the memory allocated in the access list vector and then clears the vector.
*/
void ClearAccess();
/** Add an entry to the nick's certificate list
*
* @param entry The fingerprint to add to the cert list
*
* Adds a new entry into the cert list.
*/
void AddCert(const Anope::string &entry);
/** Get an entry from the nick's cert list by index
*
* @param entry Index in the certificaate list vector to retrieve
* @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
*
* Retrieves an entry from the certificate list corresponding to the given index.
*/
Anope::string GetCert(unsigned entry) const;
/** Find an entry in the nick's cert list
*
* @param entry The fingerprint to search for
* @return True if the fingerprint is found in the cert list, false otherwise
*
* Search for an fingerprint within the cert list.
*/
bool FindCert(const Anope::string &entry);
/** Erase a fingerprint from the nick's certificate list
*
* @param entry The fingerprint to remove
*
* Removes the specified fingerprint from the cert list.
*/
void EraseCert(const Anope::string &entry);
/** Clears the entire nick's cert list
*
* Deletes all the memory allocated in the certificate list vector and then clears the vector.
*/
void ClearCert();
};
/** Timer for colliding nicks to force people off of nicknames
+25 -4
View File
@@ -1,8 +1,8 @@
/*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -20,6 +20,9 @@ class Message;
namespace Anope
{
template<typename T> class map : public std::map<string, T> { };
template<typename T> class insensitive_map : public std::map<string, T, std::less<ci::string> > { };
/**
* A wrapper string class around all the other string classes, this class will
* allow us to only require one type of string everywhere that can be converted
@@ -153,6 +156,11 @@ namespace Anope
*/
inline size_type length() const { return this->_string.length(); }
/**
* Add a char to the end of the string.
*/
inline void push_back(char c) { return this->_string.push_back(c); }
/**
* Resizes the string content to n characters.
*/
@@ -294,8 +302,12 @@ namespace Anope
extern CoreExport time_t CurTime;
extern CoreExport string Version();
extern CoreExport string Build();
extern CoreExport string VersionShort();
extern CoreExport string VersionBuildString();
extern CoreExport int VersionMajor();
extern CoreExport int VersionMinor();
extern CoreExport int VersionPatch();
extern CoreExport int VersionBuild();
/** Check whether two strings match.
* @param str The string to check against the pattern (e.g. foobar)
@@ -324,6 +336,15 @@ namespace Anope
extern CoreExport void Unhex(const Anope::string &src, Anope::string &dest);
extern CoreExport void Unhex(const Anope::string &src, char *dest);
/** Returns a sequence of data formatted as the format argument specifies.
** After the format parameter, the function expects at least as many
** additional arguments as specified in format.
* @param fmt Format of the Message
* @param ... any number of parameters
* @return a Anope::string
*/
extern CoreExport string printf(const char *fmt, ...);
/** Return the last error, uses errno/GetLastError() to determin this
* @return An error message
*/
+10 -10
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -12,10 +12,8 @@
class BotInfo;
typedef unordered_map_namespace::unordered_map<Anope::string, BotInfo *, ci::hash, std::equal_to<ci::string> > botinfo_map;
typedef unordered_map_namespace::unordered_map<Anope::string, BotInfo *, Anope::hash> botinfo_uid_map;
extern CoreExport botinfo_map BotListByNick;
extern CoreExport botinfo_uid_map BotListByUID;
extern CoreExport Anope::insensitive_map<BotInfo *> BotListByNick;
extern CoreExport Anope::map<BotInfo *> BotListByUID;
/** Flags settable on a bot
*/
@@ -31,6 +29,8 @@ enum BotFlag
BI_END
};
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "" };
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
{
public:
@@ -75,15 +75,15 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
/** Join this bot to a channel
* @param c The channel
* @param update_ts Assume we're updating the TS for this channel
* @param status The status the bot should have on the channel
*/
void Join(Channel *c, bool update_ts = false);
void Join(Channel *c, ChannelStatus *status = NULL);
/** Join this bot to a channel
* @param chname The channel name
* @param update_ts Assume we're updating the TS for this channel
* @param status The status the bot should have on the channel
*/
void Join(const Anope::string &chname, bool update_ts = false);
void Join(const Anope::string &chname, ChannelStatus *status = NULL);
/** Part this bot from a channel
* @param c The channel
+15 -47
View File
@@ -1,6 +1,6 @@
/* Channel support
*
* (C) 2008-2010 Anope Team
* (C) 2008-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -52,7 +52,7 @@ struct UserContainer
typedef std::list<UserContainer *> CUserList;
enum ChannelFlags
enum ChannelFlag
{
/* Channel still exists when emptied */
CH_PERSIST,
@@ -62,15 +62,14 @@ enum ChannelFlags
CH_LOGCHAN
};
class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
{
public:
typedef std::multimap<ChannelModeName, Anope::string> ModeList;
private:
/** A map of channel modes with their parameters set on this channel
*/
std::map<ChannelModeName, Anope::string> Params;
/* Modes set on the channel */
Flags<ChannelModeName, CMODE_END * 2> modes;
ModeList modes;
public:
/** Default constructor
@@ -87,10 +86,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
ChannelInfo *ci; /* Corresponding ChannelInfo */
time_t creation_time; /* When channel was created */
EList *bans;
EList *excepts;
EList *invites;
/* List of users in the channel */
CUserList users;
@@ -146,16 +141,18 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
*/
bool HasUserStatus(User *u, ChannelModeName Name) const;
/** See if the channel has any modes at all
* @return true or false
*/
inline bool HasModes() const { return modes.FlagCount(); }
/** See if a channel has a mode
* @param Name The mode name
* @return true or false
* @return The number of modes set
* @param param The optional mode param
*/
bool HasMode(ChannelModeName Name) const;
size_t HasMode(ChannelModeName Name, const Anope::string &param = "");
/** Get a list of modes on a channel
* @param Name A mode name to get the list of
* @return a pair of iterators for the beginning and end of the list
*/
std::pair<ModeList::iterator, ModeList::iterator> GetModeList(ChannelModeName Name);
/** Set a mode internally on a channel, this is not sent out to the IRCd
* @param cm The mode
@@ -205,30 +202,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
*/
void RemoveMode(BotInfo *bi, ChannelModeName Name, const Anope::string &param = "", bool EnforceMLock = true);
/** Clear all the modes from the channel
* @param bi The client unsetting the modes
* @param internal Only remove the modes internally
*/
void ClearModes(BotInfo *bi = NULL, bool internal = false);
/** Clear all the bans from the channel
* @param bi The client unsetting the modes
* @param internal Only remove the modes internally
*/
void ClearBans(BotInfo *bi = NULL, bool internal = false);
/** Clear all the excepts from the channel
* @param bi The client unsetting the modes
* @param internal Only remove the modes internally
*/
void ClearExcepts(BotInfo *bi = NULL, bool internal = false);
/** Clear all the invites from the channel
* @param bi The client unsetting the modes
* @param internal Only remove the modes internally
*/
void ClearInvites(BotInfo *bi = NULL, bool internal = false);
/** Get a param from the channel
* @param Name The mode
* @param Target a string to put the param into
@@ -236,11 +209,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
*/
bool GetParam(ChannelModeName Name, Anope::string &Target) const;
/** Check if a mode is set and has a param
* @param Name The mode
*/
bool HasParam(ChannelModeName Name) const;
/** Set a string of modes on the channel
* @param bi The client setting the modes
* @param EnforceMLock Should mlock be enforced on this mode change
+55 -15
View File
@@ -1,9 +1,9 @@
/* Declarations for command data.
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -29,9 +29,9 @@ enum CommandReturn
};
extern CoreExport Command *FindCommand(BotInfo *bi, const Anope::string &cmd);
extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, const Anope::string &cmd);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, const Anope::string &message);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, const Anope::string &message);
extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cmd);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &message);
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope::string &command, const Anope::string &message);
enum CommandFlag
{
@@ -43,10 +43,44 @@ enum CommandFlag
CFLAG_DISABLE_FANTASY
};
const Anope::string CommandFlagStrings[] = {
"CFLAG_ALLOW_UNREGISTERED",
"CFLAG_ALLOW_FORBIDDEN",
"CFLAG_ALLOW_SUSPENDED",
"CFLAG_ALLOW_UNREGISTEREDCHANNEL",
"CFLAG_STRIP_CHANNEL",
"CFLAG_DISABLE_FANTASY",
""
};
/* The source for a command */
struct CoreExport CommandSource
{
/* User executing the command */
User *u;
/* Channel (if applicable) */
ChannelInfo *ci;
/* The service this command is on */
BotInfo *owner;
/* The service the reply should come from, *not* necessarily the service the command is on */
BotInfo *service;
/* Whether or not this was a fantasy command */
bool fantasy;
std::list<Anope::string> reply;
void Reply(const char *message, ...);
void Reply(const Anope::string &message);
void DoReply();
};
/** Every services command is a class, inheriting from Command.
*/
class CoreExport Command : public Flags<CommandFlag>
class CoreExport Command : public Flags<CommandFlag>, public Base
{
Anope::string desc;
public:
/* Maximum paramaters accepted by this command */
size_t MaxParams;
@@ -72,28 +106,33 @@ class CoreExport Command : public Flags<CommandFlag>
virtual ~Command();
protected:
void SetDesc(const Anope::string &d);
public:
/** Execute this command.
* @param u The user executing the command.
* @param source The source
* @param params Command parameters
*/
virtual CommandReturn Execute(User *u, const std::vector<Anope::string> &);
virtual CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
/** Called when HELP is requsted for the client this command is on.
* @param u The user requesting help
* @param source The source
*/
virtual void OnServHelp(User *u);
virtual void OnServHelp(CommandSource &source);
/** Requested when the user is requesting help on this command. Help on this command should be sent to the user.
* @param u The user requesting help
* @param source The source
* @param subcommand The subcommand the user is requesting help on, or an empty string. (e.g. /ns help set foo bar lol gives a subcommand of "FOO BAR LOL")
* @return true if help was provided to the user, false otherwise.
*/
virtual bool OnHelp(User *u, const Anope::string &subcommand);
virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand);
/** Requested when the user provides bad syntax to this command (not enough params, etc).
* @param u The user executing the command.
* @param source The source
* @param subcommand The subcommand the user tried to use
*/
virtual void OnSyntaxError(User *u, const Anope::string &subcommand);
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand);
/** Set which command permission (e.g. chanserv/forbid) is required for this command.
* @param reststr The permission required to successfully execute this command
@@ -101,9 +140,10 @@ class CoreExport Command : public Flags<CommandFlag>
void SetPermission(const Anope::string &reststr);
/** Add a subcommand to this command
* @param creator The creator of the subcommand
* @param c The command
*/
virtual bool AddSubcommand(Command *c);
virtual bool AddSubcommand(Module *creator, Command *c);
/** Delete a subcommand from this command
* @param c The command
+106 -169
View File
@@ -34,8 +34,6 @@ enum ConfigDataType
DT_UINTEGER, // Unsigned Integer
DT_LUINTEGER, // Long Unsigned Integer
DT_CHARPTR, // Char pointer
DT_CSSTRING, // std::string
DT_CISTRING, // ci::string
DT_STRING, // Anope::string
DT_BOOLEAN, // Boolean
DT_HOSTNAME, // Hostname syntax
@@ -53,7 +51,7 @@ enum ConfigDataType
* The callback function can then alter the values of the ValueItem
* classes to validate the settings.
*/
class ValueItem
class CoreExport ValueItem
{
private:
/** Actual data */
@@ -89,11 +87,7 @@ class ValueItem
int GetInteger() const;
/** Get value as a string */
const char *GetString() const;
/** Get value as an std::string */
inline const std::string GetCSValue() const { return v.str(); }
/** Get value as a ci::string */
inline const ci::string GetCIValue() const { return v.ci_str(); }
/** Get value as a ci::string */
/** Get value as an Anope::string */
inline const Anope::string &GetValue() const { return v; }
/** Get value as a bool */
bool GetBool() const;
@@ -177,78 +171,6 @@ template<> class ValueContainer<char **> : public ValueContainerBase
}
};
/** This a specific version of ValueContainer to handle std::string specially
*/
template<> class ValueContainer<std::string *> : public ValueContainerBase
{
private:
/** Contained item */
std::string *val;
public:
/** Initialize with nothing */
ValueContainer() : ValueContainerBase(), val(NULL) { }
/** Initialize with an std::string */
ValueContainer(std::string *Val) : ValueContainerBase(), val(Val) { }
/** Initialize with a copy */
ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
ValueContainer &operator=(const ValueContainer &Val)
{
val = Val.val;
return *this;
}
/** Change value to given std::string */
void Set(const std::string &newval)
{
*val = newval;
}
/** Change value to given ci::string */
void Set(const ci::string &newval)
{
*val = newval.c_str();
}
/** Change value to given char pointer */
void Set(const char *newval)
{
*val = newval;
}
};
/** This a specific version of ValueContainer to handle ci::string specially
*/
template<> class ValueContainer<ci::string *> : public ValueContainerBase
{
private:
/** Contained item */
ci::string *val;
public:
/** Initialize with nothing */
ValueContainer() : ValueContainerBase(), val(NULL) { }
/** Initialize with an std::string */
ValueContainer(ci::string *Val) : ValueContainerBase(), val(Val) { }
/** Initialize with a copy */
ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
ValueContainer &operator=(const ValueContainer &Val)
{
val = Val.val;
return *this;
}
/** Change value to given std::string */
void Set(const std::string &newval)
{
*val = newval.c_str();
}
/** Change value to given ci::string */
void Set(const ci::string &newval)
{
*val = newval;
}
/** Change value to given char pointer */
void Set(const char *newval)
{
*val = newval;
}
};
/** This a specific version of ValueContainer to handle Anope::string specially
*/
template<> class ValueContainer<Anope::string *> : public ValueContainerBase
@@ -268,16 +190,7 @@ template<> class ValueContainer<Anope::string *> : public ValueContainerBase
val = Val.val;
return *this;
}
/** Change value to given std::string */
void Set(const std::string &newval)
{
*val = newval;
}
/** Change value to given ci::string */
void Set(const ci::string &newval)
{
*val = newval;
}
/** Change value to given Anope::string */
void Set(const Anope::string &newval)
{
@@ -319,16 +232,6 @@ typedef ValueContainer<int *> ValueContainerInt;
*/
typedef ValueContainer<time_t *> ValueContainerTime;
/** A specialization of ValueContainer to hold a pointer to
* an std::string
*/
typedef ValueContainer<std::string *> ValueContainerCSString;
/** A specialization of ValueContainer to hold a pointer to
* an ci::string
*/
typedef ValueContainer<ci::string *> ValueContainerCIString;
/** A specialization of ValueContainer to hold a pointer to
* an Anope::string
*/
@@ -348,43 +251,89 @@ typedef bool (*MultiValidator)(ServerConfig *, const Anope::string &, const Anop
*/
typedef bool (*MultiNotify)(ServerConfig *, const Anope::string &);
/** Holds a core configuration item and its callbacks
bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateGuestPrefix(ServerConfig *conf, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data);
bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateDefCon(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data);
bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
/** Represents a configuration file
*/
struct InitialConfig
class ConfigurationFile
{
/** Tag name */
const Anope::string tag;
/** Value name */
const Anope::string value;
/** Default, if not defined */
const Anope::string default_value;
/** Value containers */
ValueContainerBase *val;
/** Data types */
int datatype;
/** Validation function */
Validator validation_function;
Anope::string name;
bool executable;
FILE *fp;
public:
ConfigurationFile(const Anope::string &, bool);
~ConfigurationFile();
const Anope::string &GetName() const;
bool IsOpen() const;
bool Open();
void Close();
bool End() const;
Anope::string Read();
};
/** Holds a core configuration item and its callbacks
* where there may be more than one item
/** Holds all of the core configuration items
*/
struct MultiConfig
class CoreExport ConfigItems
{
/** Tag name */
const Anope::string tag;
/** One or more items within tag */
const Anope::string items[17];
/** One or more defaults for items within tags */
const Anope::string items_default[17];
/** One or more data types */
int datatype[17];
/** Initialization function */
MultiNotify init_function;
/** Validation function */
MultiValidator validation_function;
/** Completion function */
MultiNotify finish_function;
public:
/** Holds a core configuration item and its callbacks
*/
struct Item
{
/** Tag name */
Anope::string tag;
/** Value name */
Anope::string value;
/** Default, if not defined */
Anope::string default_value;
/** Value containers */
ValueContainerBase *val;
/** Data types */
int datatype;
/** Validation function */
Validator validation_function;
} *Values;
/** Holds a core configuration item and its callbacks
* where there may be more than one item
*/
struct MultiItem
{
/** Tag name */
Anope::string tag;
/** One or more items within tag */
Anope::string items[17];
/** One or more defaults for items within tags */
Anope::string items_default[17];
/** One or more data types */
int datatype[17];
/** Initialization function */
MultiNotify init_function;
/** Validation function */
MultiValidator validation_function;
/** Completion function */
MultiNotify finish_function;
} *MultiValues;
ConfigItems(ServerConfig *conf);
~ConfigItems();
};
/** This class holds the bulk of the runtime configuration for Anope.
@@ -398,8 +347,6 @@ class CoreExport ServerConfig
*/
bool CheckOnce(const Anope::string &);
public:
/* Error from the config */
std::ostringstream errstr;
/** This holds all the information in the config file,
* it's indexed by tag name to a vector of key/values.
*/
@@ -407,15 +354,16 @@ class CoreExport ServerConfig
/** Construct a new ServerConfig
*/
ServerConfig();
/** Read the entire configuration into memory
* and initialize this class. All other methods
* should be used only by the core.
*/
void Read();
/** Load 'filename' into 'target', with the new config parser everything is parsed into
/** Load the configuration file into 'this'. With the new config parser everything is parsed into
* tag/key/value at load-time rather than at read-value time.
*/
bool LoadConf(ConfigDataHash &, const Anope::string &);
void LoadConf(ConfigurationFile &file);
// Both these return true if the value existed or false otherwise
/** Writes 'length' chars into 'result' as a string
*/
@@ -537,6 +485,9 @@ class CoreExport ServerConfig
bool UsePrivmsg;
/* Services only respond to full PRIVMSG client@services.server.name messages */
bool UseStrictPrivMsg;
/* This is not a configurable option.
* Config::Config will set it depending on the value of UseStrictPrivMsg */
Anope::string UseStrictPrivMsgString;
/* Number of seconds between consecutive uses of the REGISTER command
* Not to be confused with NSRegDelay */
unsigned NickRegDelay;
@@ -544,10 +495,12 @@ class CoreExport ServerConfig
unsigned NewsCount;
/* Default mlock modes */
Anope::string MLock;
/* Unmlockable modes */
Anope::string NoMLock;
/* Default botmodes on channels, defaults to ao */
Anope::string BotModes;
/* THe actual modes */
std::vector<ChannelModeStatus *> BotModeList;
ChannelStatus BotModeList;
/* How many times to try and reconnect to the uplink before giving up */
unsigned MaxRetries;
/* How long to wait between connection attempts */
@@ -593,12 +546,18 @@ class CoreExport ServerConfig
time_t NSRegDelay;
/* Time before the registering mail will be resent */
time_t NSResendDelay;
/* How long before nicks expir */
/* How long before nicks expire */
time_t NSExpire;
/* Time before NickRequests expire */
time_t NSRExpire;
/* How long before suspended nicks expire */
time_t NSSuspendExpire;
/* How long before forbidden nicks expire */
time_t NSForbidExpire;
/* Time before unconfirmed nicks expire */
time_t NSUnconfirmedExpire;
/* Force email when registering */
bool NSForceEmail;
/* Force users to validate new email addresses */
bool NSConfirmEmailChanges;
/* Max number of nicks in a group */
unsigned NSMaxAliases;
/* Max number of allowed strings on the access list */
@@ -623,6 +582,8 @@ class CoreExport ServerConfig
bool NSModeOnID;
/* Add the users hostnask their access list when they register */
bool NSAddAccessOnReg;
/* Maximum number of channels on AJoin */
unsigned AJoinMax;
/* Default flags for newly registered channels */
Flags<ChannelInfoFlag, CI_END> CSDefFlags;
@@ -630,6 +591,10 @@ class CoreExport ServerConfig
unsigned CSMaxReg;
/* Time before a channel expires */
time_t CSExpire;
/* How long before suspended channels expire */
time_t CSSuspendExpire;
/* How long before forbidden channels expire */
time_t CSForbidExpire;
/* Default ban type to use for channels */
int CSDefBantype;
/* Max number of entries allowed on channel access lists */
@@ -707,26 +672,6 @@ class CoreExport ServerConfig
bool WallOper;
/* Send a WALLOPS/GLOBOPS when a nonoper tries to use OperServ */
bool WallBadOS;
/* Send a WALLOPS/GLOBOPS when someone uses the GLOBAL command */
bool WallOSGlobal;
/* Send a WALLOPS/GLOBOPS when someone uses the MODE command */
bool WallOSMode;
/* Send a WALLOPS/GLOBOPS when someone uses the CLEARMODES command */
bool WallOSClearmodes;
/* Send a WALLOPS/GLOBOPS when someone uses the KICK command */
bool WallOSKick;
/* Send a WALLOPS/GLOBOPS when someone uses the AKILL command */
bool WallOSAkill;
/* Send a WALLOPS/GLOBOPS when someone uses the SNLINE command */
bool WallOSSNLine;
/* Send a WALLOPS/GLOBOPS when someone uses the SQLINE command */
bool WallOSSQLine;
/* Send a WALLOPS/GLOBOPS when someone uses the SZLINE command */
bool WallOSSZLine;
/* Send a WALLOPS/GLOBOPS when someone uses the NOOP command */
bool WallOSNoOp;
/* Send a WALLOPS/GLOBOPS when when someone uses the JUPE command */
bool WallOSJupe;
/* Send a WALLOPS/GLOBOPS when an akill expires */
bool WallAkillExpire;
/* Send a WALLOPS/GLOBOPS when SNLines expire */
@@ -737,14 +682,6 @@ class CoreExport ServerConfig
bool WallSZLineExpire;
/* Send a WALLOPS/GLOBOPS when exceptions expire */
bool WallExceptionExpire;
/* Send a WALLOPS/GLOBOPS when DROP is used */
bool WallDrop;
/* Send a WALLOPS/GLOBOPS when FORBID is used */
bool WallForbid;
/* Send a WALLOPS/GLOBOPS when GETPASS is used */
bool WallGetpass;
/* Send a WALLOPS/GLOBOPS when SETPASS is used */
bool WallSetpass;
/* Add the akillers nick to the akill reason */
bool AddAkiller;
@@ -823,7 +760,7 @@ class CoreExport ServerConfig
/* List of available opertypes */
std::list<OperType *> MyOperTypes;
/* List of pairs of opers and their opertype from the config */
std::list<std::pair<Anope::string, Anope::string> > Opers;
std::vector<Oper *> Opers;
};
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
@@ -871,7 +808,7 @@ class CoreExport ConfigReader
long error;
public:
/** Default constructor.
* This constructor initialises the ConfigReader class to read services.conf.
* This constructor initialises the ConfigReader class to read the configuration file(s).
*/
ConfigReader();
/** Overloaded constructor.
+11 -3
View File
@@ -113,7 +113,7 @@ struct DNSPacket
inline void FillBuffer(unsigned char *buffer);
};
struct DNSRecord
struct CoreExport DNSRecord
{
/* Name of the initial lookup */
Anope::string name;
@@ -130,9 +130,11 @@ struct DNSRecord
/* Record length */
unsigned short rdlength;
inline DNSRecord(const Anope::string &n);
/* When this record was created in our cache */
time_t created;
inline DNSRecord(const Anope::string &n);
operator bool() const;
};
/** The socket used to talk to the nameserver, uses UDP
@@ -154,7 +156,7 @@ class DNSSocket : public ConnectionSocket
/** DNS manager, manages the connection and all requests
*/
class DNSManager : public Timer
class CoreExport DNSManager : public Timer
{
std::multimap<Anope::string, DNSRecord *> cache;
public:
@@ -174,6 +176,12 @@ class DNSManager : public Timer
void Tick(time_t now);
void Cleanup(Module *mod);
/** Does a BLOCKING DNS query and returns the first IP.
* Only use this if you know what you are doing. Unless you specifically
* need a blocking query use the DNSRequest system
*/
static DNSRecord BlockingQuery(const Anope::string &mask, QueryType qt);
};
/** A DNS timeout, one is made for every DNS request to detect timeouts
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -28,7 +28,7 @@ template<typename T> class ExtensibleItemRegular : public ExtensibleItemBase
public:
ExtensibleItemRegular(T item) : Item(item) { }
virtual ~ExtensibleItemRegular() { }
T GetItem() const { return Item; }
T &GetItem() { return Item; }
};
/** Class used to represent an extensible item that holds a pointer
@@ -41,7 +41,7 @@ template<typename T> class ExtensibleItemPointer : public ExtensibleItemBase
public:
ExtensibleItemPointer(T *item) : Item(item) { }
virtual ~ExtensibleItemPointer() { delete Item; }
T *GetItem() const { return Item; }
T *GetItem() { return Item; }
};
/** Class used to represent an extensible item that holds a pointer to an arrray
@@ -54,7 +54,7 @@ template<typename T> class ExtensibleItemPointerArray : public ExtensibleItemBas
public:
ExtensibleItemPointerArray(T *item) : Item(item) { }
virtual ~ExtensibleItemPointerArray() { delete [] Item; }
T *GetItem() const { return Item; }
T *GetItem() { return Item; }
};
class CoreExport Extensible : public Base
@@ -108,7 +108,7 @@ class CoreExport Extensible : public Base
*/
void Extend(const Anope::string &key)
{
this->Extend(key, new ExtensibleItemRegular<char *>(NULL));
this->Extend(key, new ExtensibleItemPointer<char *>(NULL));
}
/** Shrink an Extensible class.
+51 -80
View File
@@ -1,9 +1,9 @@
/* Prototypes and external variable declarations.
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -23,12 +23,13 @@ E void ModuleRunTimeDirCleanUp();
E IRCDVar *ircd;
E IRCDProto *ircdproto;
E IRCdMessage *ircdmessage;
/**** actions.c ****/
E void kill_user(const Anope::string &source, const Anope::string &user, const Anope::string &reason);
E void kill_user(const Anope::string &source, User *user, const Anope::string &reason);
E bool bad_password(User *u);
E void common_unban(ChannelInfo *ci, const Anope::string &nick);
E void common_unban(ChannelInfo *ci, User *u, bool full = false);
E BotInfo *BotServ;
E BotInfo *ChanServ;
@@ -51,9 +52,10 @@ E BotInfo *findbot(const Anope::string &nick);
*/
E Anope::string normalizeBuffer(const Anope::string &);
E void check_ban(ChannelInfo *ci, User *u, int ttbtype);
E void bot_kick(ChannelInfo *ci, User *u, const char *message, ...);
E void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
E void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
E void bot_raw_mode(User *requester, ChannelInfo *ci, const Anope::string &mode, const Anope::string &nick);
/**** channels.c ****/
@@ -63,8 +65,6 @@ E Channel *findchan(const Anope::string &chan);
E User *nc_on_chan(Channel *c, const NickCore *nc);
E int get_access_level(ChannelInfo *ci, NickAlias *na);
E int get_access_level(ChannelInfo *ci, NickCore *nc);
E Anope::string get_xop_level(int level);
E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts);
@@ -75,18 +75,6 @@ E void MassChannelModes(BotInfo *bi, const Anope::string &modes);
E void chan_set_correct_modes(User *user, Channel *c, int give_modes);
E Entry *entry_create(const Anope::string &mask);
E Entry *entry_add(EList *list, const Anope::string &mask);
E void entry_delete(EList *list, Entry *e);
E EList *list_create();
E int entry_match(Entry *e, const Anope::string &nick, const Anope::string &user, const Anope::string &host, uint32 ip);
E int entry_match_mask(Entry *e, const Anope::string &mask, uint32 ip);
E Entry *elist_match(EList *list, const Anope::string &nick, const Anope::string &user, const Anope::string &host, uint32 ip);
E Entry *elist_match_mask(EList *list, const Anope::string &mask, uint32 ip);
E Entry *elist_match_user(EList *list, User *u);
E Entry *elist_find_mask(EList *list, const Anope::string &mask);
E long get_memuse(EList *list);
inline BotInfo *whosends(ChannelInfo *ci)
{
if (!ci || !ci->bi || !ci->c || !ci->botflags.HasFlag(BS_SYMBIOSIS) || !ci->c->FindUser(ci->bi))
@@ -103,7 +91,7 @@ E void get_chanserv_stats(long *nrec, long *memuse);
E void reset_levels(ChannelInfo *ci);
E void cs_init();
E void expire_chans();
E void cs_remove_nick(const NickCore *nc);
E void cs_remove_nick(NickCore *nc);
E void check_modes(Channel *c);
E int check_valid_admin(User *user, Channel *chan, int servermode);
@@ -112,19 +100,15 @@ E int check_valid_op(User *user, Channel *chan, int servermode);
E ChannelInfo *cs_findchan(const Anope::string &chan);
E int check_access(User *user, ChannelInfo *ci, int what);
E bool IsFounder(User *user, ChannelInfo *ci);
E int get_access(User *user, ChannelInfo *ci);
E void update_cs_lastseen(User *user, ChannelInfo *ci);
E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret);
E AutoKick *is_stuck(ChannelInfo *ci, const Anope::string &mask);
E void stick_mask(ChannelInfo *ci, AutoKick *akick);
E void stick_all(ChannelInfo *ci);
E int levelinfo_maxwidth;
E Anope::string get_mlock_modes(ChannelInfo *ci, int complete);
/**** config.c ****/
E Anope::string services_conf;
E ConfigurationFile services_conf;
E ServerConfig *Config;
/* hostserv.c */
@@ -134,7 +118,6 @@ E void HostServSyncVhosts(NickAlias *na);
/**** encrypt.c ****/
E int enc_encrypt(const Anope::string &src, Anope::string &dest);
E int enc_decrypt(const Anope::string &src, Anope::string &dest);
E int enc_check_password(Anope::string &plaintext, Anope::string &password);
/**** hostserv.c ****/
E void get_hostserv_stats(long *nrec, long *memuse);
@@ -151,17 +134,17 @@ E Uplink *uplink_server;
/**** ircd.c ****/
E void pmodule_ircd_proto(IRCDProto *);
E void pmodule_ircd_var(IRCDVar *ircdvar);
E void pmodule_ircd_message(IRCdMessage *message);
/**** language.cpp ****/
E std::vector<Anope::string> languages;
E void InitLanguages();
E const Anope::string GetString(const Anope::string &language, LanguageString string);
E const Anope::string GetString(LanguageString string);
E const Anope::string GetString(const NickCore *nc, LanguageString string);
E const Anope::string GetString(const User *u, LanguageString string);
E const Anope::string GetString(const char *domain, Anope::string language, const Anope::string &string);
E Anope::string language_strings[LANG_STRING_COUNT];
E void SyntaxError(BotInfo *bi, User *u, const Anope::string &command, LanguageString message);
E const Anope::string GetString(NickCore *nc, const char *string);
E const Anope::string GetString(const Anope::string &domain, const Anope::string &lang, const char *string);
E void PushLanguage(const Anope::string &, Anope::string);
E void PopLanguage();
E const char *anope_gettext(const char *string);
E void SyntaxError(CommandSource &source, const Anope::string &command, const Anope::string &message);
/*** logger.cpp ***/
E void InitLogChannels(ServerConfig *);
@@ -204,43 +187,54 @@ class CoreExport UplinkSocket : public ConnectionSocket
/**** memoserv.c ****/
E void ms_init();
E void rsend_notify(User *u, Memo *m, const Anope::string &chan);
E void rsend_notify(CommandSource &source, Memo *m, const Anope::string &chan);
E void check_memos(User *u);
E MemoInfo *getmemoinfo(const Anope::string &name, bool &ischan, bool &isforbid);
E void memo_send(User *u, const Anope::string &name, const Anope::string &text, int z);
E void memo_send(CommandSource &source, const Anope::string &name, const Anope::string &text, int z);
/**** messages.c ****/
/**** messages.cpp ****/
E int m_nickcoll(const Anope::string &user);
E int m_away(const Anope::string &source, const Anope::string &msg);
E int m_kill(const Anope::string &nick, const Anope::string &msg);
E int m_motd(const Anope::string &source);
E int m_privmsg(const Anope::string &source, const Anope::string &receiver, const Anope::string &message);
E bool m_stats(const Anope::string &source, const std::vector<Anope::string> &);
E int m_whois(const Anope::string &source, const Anope::string &who);
E bool m_time(const Anope::string &source, const std::vector<Anope::string> &);
E bool m_version(const Anope::string &source, const std::vector<Anope::string> &);
E void init_core_messages();
E bool OnStats(const Anope::string &source, const std::vector<Anope::string> &);
E bool OnTime(const Anope::string &source, const std::vector<Anope::string> &);
E bool OnVersion(const Anope::string &source, const std::vector<Anope::string> &);
E bool On436(const Anope::string &, const std::vector<Anope::string> &);
E bool OnAway(const Anope::string &, const std::vector<Anope::string> &);
E bool OnJoin(const Anope::string &, const std::vector<Anope::string> &);
E bool OnKick(const Anope::string &, const std::vector<Anope::string> &);
E bool OnKill(const Anope::string &, const std::vector<Anope::string> &);
E bool OnMode(const Anope::string &, const std::vector<Anope::string> &);
E bool OnNick(const Anope::string &, const std::vector<Anope::string> &);
E bool OnUID(const Anope::string &, const std::vector<Anope::string> &);
E bool OnPart(const Anope::string &, const std::vector<Anope::string> &);
E bool OnPing(const Anope::string &, const std::vector<Anope::string> &);
E bool OnPrivmsg(const Anope::string &, const std::vector<Anope::string> &);
E bool OnQuit(const Anope::string &, const std::vector<Anope::string> &);
E bool OnServer(const Anope::string &, const std::vector<Anope::string> &);
E bool OnSQuit(const Anope::string &, const std::vector<Anope::string> &);
E bool OnTopic(const Anope::string &, const std::vector<Anope::string> &);
E bool OnWhois(const Anope::string &, const std::vector<Anope::string> &);
E bool OnCapab(const Anope::string &, const std::vector<Anope::string> &);
E bool OnSJoin(const Anope::string &, const std::vector<Anope::string> &);
E bool OnError(const Anope::string &, const std::vector<Anope::string> &);
/**** misc.c ****/
E bool IsFile(const Anope::string &filename);
E int toupper(char);
E int tolower(char);
E char *strscpy(char *d, const char *s, size_t len);
#ifndef HAVE_STRLCPY
E size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
E size_t strlcat(char *, const char *, size_t);
#endif
E char *strnrepl(char *s, int32 size, const char *old, const char *nstr);
E const char *merge_args(int argc, char **argv);
E const char *merge_args(int argc, const char **argv);
E time_t dotime(const Anope::string &s);
E Anope::string duration(const NickCore *nc, time_t seconds);
E Anope::string expire_left(const NickCore *nc, time_t expires);
E Anope::string duration(time_t seconds);
E Anope::string expire_left(NickCore *nc, time_t expires);
E Anope::string do_strftime(const time_t &t);
E bool doValidHost(const Anope::string &host, int type);
@@ -264,25 +258,17 @@ E char *str_signed(unsigned char *str);
E std::list<Anope::string> BuildStringList(const Anope::string &, char = ' ');
E std::vector<Anope::string> BuildStringVector(const Anope::string &, char = ' ');
E uint32 cidr_to_netmask(uint16 cidr);
E uint16 netmask_to_cidr(uint32 mask);
E bool str_is_wildcard(const Anope::string &str);
E bool str_is_pure_wildcard(const Anope::string &str);
E bool str_is_cidr(const Anope::string &str, uint32 &ip, uint32 &mask, Anope::string &host);
/**** modes.cpp ****/
/* Number of generic modes we support */
E unsigned GenericChannelModes, GenericUserModes;
E Flags<ChannelModeName, CMODE_END * 2> DefMLockOn;
E Flags<ChannelModeName, CMODE_END * 2> DefMLockOff;
E std::map<ChannelModeName, Anope::string> DefMLockParams;
E std::multimap<ChannelModeName, ModeLock> def_mode_locks;
E void SetDefaultMLock(ServerConfig *config);
/**** nickserv.c ****/
E NickRequest *findrequestnick(const Anope::string &nick);
E void get_aliases_stats(long &count, long &mem);
E void get_core_stats(long &count, long &mem);
E void change_core_display(NickCore *nc);
@@ -292,21 +278,12 @@ E int do_setmodes(User *u);
E void ns_init();
E int validate_user(User *u);
E void expire_nicks();
E void expire_requests();
E NickAlias *findnick(const Anope::string &nick);
E NickCore *findcore(const Anope::string &nick);
E bool is_on_access(const User *u, const NickCore *nc);
/**** process.c ****/
E int allow_ignore;
E std::list<IgnoreData *> ignore;
E void add_ignore(const Anope::string &nick, time_t delta);
E IgnoreData *get_ignore(const Anope::string &nick);
E int delete_ignore(const Anope::string &nick);
E int clear_ignores();
E void process(const Anope::string &buf);
/**** send.c ****/
@@ -322,8 +299,8 @@ E std::vector<Exception *> exceptions;
E void get_session_stats(long &count, long &mem);
E void get_exception_stats(long &count, long &mem);
E void add_session(const Anope::string &nick, const Anope::string &host, const Anope::string &hostip);
E void del_session(const Anope::string &host);
E void add_session(User *u);
E void del_session(User *u);
E void expire_exceptions();
@@ -350,20 +327,14 @@ E void get_user_stats(long &count, long &mem);
E User *finduser(const Anope::string &nick);
E Anope::string TS6SID;
E User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid, const Anope::string &modes);
E void do_umode(const Anope::string &, const Anope::string &user, const Anope::string &modes);
E void do_quit(const Anope::string &source, const Anope::string &reason);
E void do_kill(const Anope::string &source, const Anope::string &reason);
E void do_umode(const Anope::string &user, const Anope::string &modes);
E void do_kill(User *user, const Anope::string &reason);
E bool is_oper(User *user);
E bool is_excepted(ChannelInfo *ci, User *user);
E bool matches_list(Channel *c, User *user, ChannelModeName mode);
E bool is_excepted_mask(ChannelInfo *ci, const Anope::string &mask);
E bool match_usermask(const Anope::string &mask, User *user);
E Anope::string create_mask(User *u);
/******************************************************************************/
+4 -4
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2010 InspIRCd Development Team
* Copyright (C) 2009-2010 Anope Team <team@anope.org>
* Copyright (C) 2002-2011 InspIRCd Development Team
* Copyright (C) 2009-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -170,7 +170,7 @@ namespace irc
/** Used to hash irc::strings for unordered_map
*/
struct hash
struct CoreExport hash
{
/* VS 2008 specific code */
enum { bucket_size = 4, min_buckets = 8 };
@@ -241,7 +241,7 @@ namespace ci
/** Used to hash ci::strings for unordered_map
*/
struct hash
struct CoreExport hash
{
/* VS 2008 specific code */
enum { bucket_size = 4, min_buckets = 8 };
+115 -1551
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -3,7 +3,6 @@
#include "anope.h"
extern CoreExport bool Mail(User *u, NickRequest *nr, BotInfo *service, const Anope::string &subject, const Anope::string &message);
extern CoreExport bool Mail(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message);
extern CoreExport bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &message);
extern CoreExport bool MailValidate(const Anope::string &email);
+86 -84
View File
@@ -1,7 +1,7 @@
/* Mode support
*
* Copyright (C) 2008-2010 Adam <Adam@anope.org>
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
* Copyright (C) 2008-2011 Adam <Adam@anope.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -16,14 +16,26 @@ enum UserModeName
UMODE_BEGIN,
UMODE_SERV_ADMIN, UMODE_BOT, UMODE_CO_ADMIN, UMODE_FILTER, UMODE_HIDEOPER, UMODE_NETADMIN,
UMODE_REGPRIV, UMODE_PROTECTED, UMODE_NO_CTCP, UMODE_WEBTV, UMODE_WHOIS, UMODE_ADMIN, UMODE_DEAF,
UMODE_REGPRIV, UMODE_PROTECTED, UMODE_NO_CTCP, UMODE_WEBTV, UMODE_WEBIRC, UMODE_WHOIS, UMODE_ADMIN, UMODE_DEAF,
UMODE_GLOBOPS, UMODE_HELPOP, UMODE_INVIS, UMODE_OPER, UMODE_PRIV, UMODE_GOD, UMODE_REGISTERED,
UMODE_SNOMASK, UMODE_VHOST, UMODE_WALLOPS, UMODE_CLOAK, UMODE_SSL, UMODE_CALLERID, UMODE_COMMONCHANS,
UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER,
UMODE_SNOMASK, UMODE_VHOST, UMODE_WALLOPS, UMODE_CLOAK, UMODE_SSL, UMODE_SOFTCALLERID, UMODE_CALLERID,
UMODE_COMMONCHANS, UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER, UMODE_RESTRICTED,
UMODE_END
};
const Anope::string UserModeNameStrings[] = {
"UMODE_BEGIN",
"UMODE_SERV_ADMIN", "UMODE_BOT", "UMODE_CO_ADMIN", "UMODE_FILTER", "UMODE_HIDEOPER", "UMODE_NETADMIN",
"UMODE_REGPRIV", "UMODE_PROTECTED", "UMODE_NO_CTCP", "UMODE_WEBTV", "UMODE_WEBIRC", "UMODE_WHOIS", "UMODE_ADMIN", "UMODE_DEAF",
"UMODE_GLOBOPS", "UMODE_HELPOP", "UMODE_INVIS", "UMODE_OPER", "UMODE_PRIV", "UMODE_GOD", "UMODE_REGISTERED",
"UMODE_SNOMASK", "UMODE_VHOST", "UMODE_WALLOPS", "UMODE_CLOAK", "UMODE_SSL", "UMODE_SOFTCALLERID", "UMODE_CALLERID",
"UMODE_COMMONCHANS", "UMODE_HIDDEN", "UMODE_STRIPCOLOR", "UMODE_INVISIBLE_OPER", "UMODE_RESTRICTED"
""
};
/** All of the valid channel mode names
*/
enum ChannelModeName
@@ -36,6 +48,7 @@ enum ChannelModeName
CMODE_NOCTCP, CMODE_FILTER, CMODE_NOKNOCK, CMODE_REDIRECT, CMODE_REGMODERATED, CMODE_NONICK, CMODE_OPERONLY,
CMODE_NOKICK, CMODE_REGISTEREDONLY, CMODE_STRIPCOLOR, CMODE_NONOTICE, CMODE_NOINVITE, CMODE_ALLINVITE,
CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, CMODE_DELAYEDJOIN, CMODE_NOREJOIN,
CMODE_BANDWIDTH,
/* b/e/I */
CMODE_BAN, CMODE_EXCEPT,
@@ -48,6 +61,29 @@ enum ChannelModeName
CMODE_END
};
const Anope::string ChannelModeNameStrings[] = {
"CMODE_BEGIN",
/* Channel modes */
"CMODE_BLOCKCOLOR", "CMODE_FLOOD", "CMODE_INVITE", "CMODE_KEY", "CMODE_LIMIT", "CMODE_MODERATED", "CMODE_NOEXTERNAL",
"CMODE_PRIVATE", "CMODE_REGISTERED", "CMODE_SECRET", "CMODE_TOPIC", "CMODE_AUDITORIUM", "CMODE_SSL", "CMODE_ADMINONLY",
"CMODE_NOCTCP", "CMODE_FILTER", "CMODE_NOKNOCK", "CMODE_REDIRECT", "CMODE_REGMODERATED", "CMODE_NONICK", "CMODE_OPERONLY",
"CMODE_NOKICK", "CMODE_REGISTEREDONLY", "CMODE_STRIPCOLOR", "CMODE_NONOTICE", "CMODE_NOINVITE", "CMODE_ALLINVITE",
"CMODE_BLOCKCAPS", "CMODE_PERM", "CMODE_NICKFLOOD", "CMODE_JOINFLOOD", "CMODE_DELAYEDJOIN", "CMODE_NOREJOIN",
"CMODE_BANDWIDTH",
/* b/e/I */
"CMODE_BAN", "CMODE_EXCEPT",
"CMODE_INVITEOVERRIDE",
/* v/h/o/a/q */
"CMODE_VOICE", "CMODE_HALFOP", "CMODE_OP",
"CMODE_PROTECT", "CMODE_OWNER",
""
};
/** The different types of modes
*/
enum ModeType
@@ -79,8 +115,6 @@ class CoreExport Mode : public Base
public:
/* Class of mode this is */
ModeClass Class;
/* The mode name, as a string */
Anope::string NameAsString;
/* Mode char for this */
char ModeChar;
/* Type of mode this is */
@@ -88,11 +122,10 @@ class CoreExport Mode : public Base
/** Default constructor
* @param mClass The type of mode this is
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param type The mode type
*/
Mode(ModeClass mClass, const Anope::string &mNameAsString, char modeChar, ModeType type);
Mode(ModeClass mClass, char modeChar, ModeType type);
/** Default destructor
*/
@@ -109,14 +142,17 @@ class CoreExport UserMode : public Mode
/** Default constructor
* @param nName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
UserMode(UserModeName mName, const Anope::string &mNameAsString, char modeChar);
UserMode(UserModeName mName, char modeChar);
/** Default destructor
*/
virtual ~UserMode();
/** Returns the mode name as a string
*/
const Anope::string NameAsString();
};
class CoreExport UserModeParam : public UserMode
@@ -124,10 +160,9 @@ class CoreExport UserModeParam : public UserMode
public:
/** Default constructor
* @param mName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
UserModeParam(UserModeName mName, const Anope::string &mNameAsString, char modeChar);
UserModeParam(UserModeName mName, char modeChar);
/** Check if the param is valid
* @param value The param
@@ -146,10 +181,9 @@ class CoreExport ChannelMode : public Mode
/** Default constructor
* @param mName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
ChannelMode(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar);
ChannelMode(ChannelModeName mName, char modeChar);
/** Default destructor
*/
@@ -159,7 +193,11 @@ class CoreExport ChannelMode : public Mode
* NOTE: User CAN be NULL, this is for checking if it can be locked with defcon
* @param u The user, or NULL
*/
virtual bool CanSet(User *u) const { return true; }
bool CanSet(User *u) const;
/** Returns the mode name as a string
*/
const Anope::string NameAsString();
};
@@ -170,10 +208,9 @@ class CoreExport ChannelModeList : public ChannelMode
public:
/** Default constructor
* @param mName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
ChannelModeList(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar);
ChannelModeList(ChannelModeName mName, char modeChar);
/** Default destructor
*/
@@ -185,18 +222,25 @@ class CoreExport ChannelModeList : public ChannelMode
*/
virtual bool IsValid(const Anope::string &mask) const { return true; }
/** Add the mask to the channel, this should be overridden
/** Checks if mask affects user
* Should only be used for extbans or other weird ircd-specific things.
* @param u The user
* @param e The entry to match against
* @return true on match
*/
virtual bool Matches(User *u, const Entry *e) { return false; }
/** Called when a mask is added to a channel
* @param chan The channel
* @param mask The mask
*/
virtual void AddMask(Channel *chan, const Anope::string &mask) { }
virtual void OnAdd(Channel *chan, const Anope::string &mask) { }
/** Delete the mask from the channel, this should be overridden
/** Called when a mask is removed from a channel
* @param chan The channel
* @param mask The mask
*/
virtual void DelMask(Channel *chan, const Anope::string &mask) { }
virtual void OnDel(Channel *chan, const Anope::string &mask) { }
};
/** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this
@@ -206,11 +250,10 @@ class CoreExport ChannelModeParam : public ChannelMode
public:
/** Default constructor
* @param mName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param MinusArg true if this mode sends no arg when unsetting
*/
ChannelModeParam(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar, bool MinusArg = false);
ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg = false);
/** Default destructor
*/
@@ -236,11 +279,10 @@ class CoreExport ChannelModeStatus : public ChannelMode
/** Default constructor
* @param mName The mode name
* @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param mSymbol The symbol for the mode, eg @ % +
*/
ChannelModeStatus(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar, char mSymbol);
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol);
/** Default destructor
*/
@@ -252,54 +294,17 @@ class CoreExport ChannelModeStatus : public ChannelMode
class CoreExport ChannelModeBan : public ChannelModeList
{
public:
ChannelModeBan(char modeChar) : ChannelModeList(CMODE_BAN, "CMODE_BAN", modeChar) { }
ChannelModeBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { }
void AddMask(Channel *chan, const Anope::string &mask);
void DelMask(Channel *chan, const Anope::string &mask);
void OnAdd(Channel *chan, const Anope::string &mask);
};
/** Channel mode +e
*/
class CoreExport ChannelModeExcept : public ChannelModeList
{
public:
ChannelModeExcept(char modeChar) : ChannelModeList(CMODE_EXCEPT, "CMODE_EXCEPT", modeChar) { }
void AddMask(Channel *chan, const Anope::string &mask);
void DelMask(Channel *chan, const Anope::string &mask);
};
/** Channel mode +I
*/
class CoreExport ChannelModeInvex : public ChannelModeList
{
public:
ChannelModeInvex(char modeChar) : ChannelModeList(CMODE_INVITEOVERRIDE, "CMODE_INVITEOVERRIDE", modeChar) { }
void AddMask(Channel *chan, const Anope::string &mask);
void DelMask(Channel *chan, const Anope::string &mask);
};
/** Channel mode +k (key)
*/
class CoreExport ChannelModeKey : public ChannelModeParam
{
public:
ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, "CMODE_KEY", modeChar) { }
bool IsValid(const Anope::string &value) const;
};
/** Channel mode +f (flood)
*/
class ChannelModeFlood : public ChannelModeParam
{
public:
ChannelModeFlood(char modeChar, bool minusNoArg = false) : ChannelModeParam(CMODE_FLOOD, "CMODE_FLOOD", modeChar, minusNoArg) { }
ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, modeChar) { }
bool IsValid(const Anope::string &value) const;
};
@@ -310,7 +315,7 @@ class ChannelModeFlood : public ChannelModeParam
class CoreExport ChannelModeAdmin : public ChannelMode
{
public:
ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, "CMODE_ADMINONLY", modeChar) { }
ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, modeChar) { }
/* Opers only */
bool CanSet(User *u) const;
@@ -322,7 +327,7 @@ class CoreExport ChannelModeAdmin : public ChannelMode
class CoreExport ChannelModeOper : public ChannelMode
{
public:
ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, "CMODE_OPERONLY", modeChar) { }
ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, modeChar) { }
/* Opers only */
bool CanSet(User *u) const;
@@ -334,7 +339,7 @@ class CoreExport ChannelModeOper : public ChannelMode
class CoreExport ChannelModeRegistered : public ChannelMode
{
public:
ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, "CMODE_REGISTERED", modeChar) { }
ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, modeChar) { }
/* No one mlocks +r */
bool CanSet(User *u) const;
@@ -401,18 +406,9 @@ class CoreExport ModeManager
static void StackerAddInternal(BotInfo *bi, Base *Object, Mode *mode, bool Set, const Anope::string &Param, StackerType Type);
public:
/* List of all modes Anope knows about */
static std::map<Anope::string, Mode *> Modes;
/* User modes */
static std::map<char, UserMode *> UserModesByChar;
static std::map<UserModeName, UserMode *> UserModesByName;
/* Channel modes */
static std::map<char, ChannelMode *> ChannelModesByChar;
static std::map<ChannelModeName, ChannelMode *> ChannelModesByName;
/* Although there are two different maps for UserModes and ChannelModes
* the pointers in each are the same. This is used to increase efficiency.
*/
/* List of all modes Anope knows about */
static std::vector<ChannelMode *> ChannelModes;
static std::vector<UserMode *> UserModes;
/** Add a user mode to Anope
* @param um A UserMode or UserMode derived class
@@ -450,11 +446,17 @@ class CoreExport ModeManager
*/
static UserMode *FindUserModeByName(UserModeName Name);
/** Find a mode by name
/** Find channel mode by string
* @param name The mode name
* @return The mode
*/
static Mode *FindModeByName(const Anope::string &name);
static ChannelMode *FindChannelModeByString(const Anope::string &name);
/** Find user mode by string
* @param name The mode name
* @return The mode
*/
static UserMode *FindUserModeByString(const Anope::string &name);
/** Gets the channel mode char for a symbol (eg + returns v)
* @param Value The symbol
-1
View File
@@ -4,6 +4,5 @@
#include "services.h"
#include "commands.h"
#include "modules.h"
#define _(x) x
#endif // MODULE_H
+126 -79
View File
@@ -1,9 +1,9 @@
/* Modular support
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -165,9 +165,9 @@ extern CoreExport std::list<Module *> Modules;
class Version
{
private:
unsigned Major;
unsigned Minor;
unsigned Build;
int Major;
int Minor;
int Build;
public:
/** Constructor
@@ -175,7 +175,7 @@ class Version
* @param vMinor The minor version numbber
* @param vBuild The build version numbber
*/
Version(unsigned vMajor, unsigned vMinor, unsigned vBuild);
Version(int vMajor, int vMinor, int vBuild);
/** Destructor
*/
@@ -184,17 +184,17 @@ class Version
/** Get the major version of Anope this was built against
* @return The major version
*/
unsigned GetMajor() const;
int GetMajor() const;
/** Get the minor version of Anope this was built against
* @return The minor version
*/
unsigned GetMinor() const;
int GetMinor() const;
/** Get the build version this was built against
* @return The build version
*/
unsigned GetBuild() const;
int GetBuild() const;
};
/* Forward declaration of CallBack class for the Module class */
@@ -284,11 +284,10 @@ class CoreExport Module : public Extensible
Version GetVersion() const;
/** Send a message to a user in their language, if a translation is available
* @param from Client to send the message from
* @param to User to send the message to
* @param source The source of the message
* @param fmt The message
*/
void SendMessage(BotInfo *from, User *to, const char *fmt, ...);
void SendMessage(CommandSource &source, const char *fmt, ...);
/**
* Add a module provided command to the given service.
@@ -365,27 +364,25 @@ class CoreExport Module : public Extensible
* @param bi The bot the command is being run from
* @param command The command
* @param message The parameters used for the command
* @param c The command class (if it exists)
* @param ci If a tanasy command, the channel the comman was used on
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommandRun(User *u, BotInfo *bi, const Anope::string &command, const Anope::string &message, Command *c) { return EVENT_CONTINUE; }
virtual EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci) { return EVENT_CONTINUE; }
/** Called before a command is due to be executed.
* @param u The user executing the command
* @param service The service the command is associated with
* @param source The source of the command
* @param command The command the user is executing
* @param params The parameters the user is sending
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommand(User *u, BotInfo *service, const Anope::string &command, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called after a command has been executed.
* @param u The user executing the command
* @param service The service the command is associated with
* @param source The source of the command
* @param command The command the user executed
* @param params The parameters the user sent
*/
virtual void OnPostCommand(User *u, BotInfo *service, const Anope::string &command, const std::vector<Anope::string> &params) { }
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { }
/** Called after the core has finished loading the databases, but before
* we connect to the server
@@ -407,7 +404,6 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
virtual EventReturn OnDecrypt(const Anope::string &hashm, const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
virtual EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password) { return EVENT_CONTINUE; }
/** Called on fantasy command
* @param command The command
@@ -426,10 +422,10 @@ class CoreExport Module : public Extensible
virtual void OnBotNoFantasyAccess(const Anope::string &command, User *u, ChannelInfo *ci, const Anope::string &params) { }
/** Called after a bot joins a channel
* @param ci The channael
* @param c The channel
* @param bi The bot
*/
virtual void OnBotJoin(ChannelInfo *ci, BotInfo *bi) { }
virtual void OnBotJoin(Channel *c, BotInfo *bi) { }
/** Called when a bot places a ban
* @param u User being banned
@@ -450,6 +446,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnBadWordDel(ChannelInfo *ci, BadWord *bw) { }
/** Called in findbot()
* @param nick The nick being looked up
*/
virtual void OnFindBot(const Anope::string &nick) { }
/** Called before a bot kicks a user
* @param bi The bot sending the kick
* @param c The channel the user is being kicked on
@@ -498,10 +499,10 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnPreChanExpire(ChannelInfo *ci) { return EVENT_CONTINUE; }
/** Called when a channel expires
* @param chname The channel name
/** Called before a channel expires
* @param ci The channel
*/
virtual void OnChanExpire(const Anope::string &chname) { }
virtual void OnChanExpire(ChannelInfo *ci) { }
/** Called before Anope connects to its uplink
* @param u The uplink we're going to connect to
@@ -559,14 +560,6 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when nickrequest metadata is read from the database
* @param nr The nickrequest
* @parm key The metadata key
* @param params The params from the database
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing
*/
virtual EventReturn OnDatabaseReadMetadata(NickRequest *nr, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when botinfo metadata is read from the database
* @param bi The botinfo
* @param key The metadata key
@@ -595,12 +588,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickAlias *na) { }
/** Called when we are wrting metadata for a nickrequest
* @param WriteMetata A callback function used to insert the metadata
* @param nr The nick request
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickRequest *nr) { }
/** Called when we are writing metadata for a botinfo
* @param WriteMetata A callback function used to insert the metadata
* @param bi The botinfo
@@ -726,25 +713,23 @@ class CoreExport Module : public Extensible
/** Called when access is deleted from a channel
* @param ci The channel
* @param u The user who removed the access
* @param nc The user who was deleted
* @param access The access entry being removed
*/
virtual void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc) { }
virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { }
/** Called when access is changed
* @param ci The channel
* @param u The user who changed the access
* @param nc The nick whos access was changed
* @param level The level of the new access
* @param u access The access changed
*/
virtual void OnAccessChange(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { }
/** Called when access is added
* @param ci The channel
* @param u The user who added the access
* @para nc The nick who was added to access
* @param level The level they were added at
* @param access The access changed
*/
virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
virtual void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access) { }
/** Called when the access list is cleared
* @param ci The channel
@@ -815,16 +800,22 @@ class CoreExport Module : public Extensible
virtual void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) { }
/** Called when a user requests info for a channel
* @param u The user requesting info
* @param source The user requesting info
* @param ci The channel the user is requesting info for
* @param ShowHidden true if we should show the user everything
*/
virtual void OnChanInfo(User *u, ChannelInfo *ci, bool ShowHidden) { }
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden) { }
/** Called on cs_findchan()
* @param chname The name being looked up
*/
virtual void OnFindChan(const Anope::string &chname) { }
/** Called when a nick is dropped
* @param nick The nick
* @param u The user dropping the nick
* @param na The nick
*/
virtual void OnNickDrop(const Anope::string &nick) { }
virtual void OnNickDrop(User *u, NickAlias *na) { }
/** Called when a nick is forbidden
* @param na The nick alias of the forbidden nick
@@ -878,16 +869,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) { }
/** called from ns_register.c, after the NickRequest have been created
* @param nr pointer to the NickRequest
*/
virtual void OnMakeNickRequest(NickRequest *nr) { }
/** called on delnickrequest()
* @param nr pointer to the NickRequest
*/
virtual void OnDelNickRequest(NickRequest *nr) { }
/** called from NickCore::ClearAccess()
* @param nc pointer to the NickCore
*/
@@ -905,12 +886,57 @@ class CoreExport Module : public Extensible
*/
virtual void OnNickEraseAccess(NickCore *nc, const Anope::string &entry) { }
/** called from NickCore::ClearCert()
* @param nc pointer to the NickCore
*/
virtual void OnNickClearCert(NickCore *nc) { }
/** Called when a user adds an entry to their cert list
* @param nc The nick
* @param entry The entry
*/
virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) { }
/** Called from NickCore::EraseCert()
* @param nc pointer to the NickCore
* @param entry The fingerprint
*/
virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) { }
/** Called when a user requests info for a nick
* @param u The user requesting info
* @param source The user requesting info
* @param na The nick the user is requesting info from
* @param ShowHidden true if we should show the user everything
*/
virtual void OnNickInfo(User *u, NickAlias *na, bool ShowHidden) { }
virtual void OnNickInfo(CommandSource &source, NickAlias *na, bool ShowHidden) { }
/** Called in findnick()
* Useful to modify the na returned by findnick()
* @param nick The nick being looked up
*/
virtual void OnFindNick(const Anope::string &nick) { }
/** Called in findcore()
* Useful to modify the nc returned by findcore()
* @param nick The nick being looked up
*/
virtual void OnFindCore(const Anope::string &nick) { }
/** Check whether a users password is correct.
* @param u The user
* @param command The command the user is doing
* @param params Command params
* @param account The account the password should be checked against
* @param password The password
* @return EVENT_ALLOW to allow the password, EVENT_STOP to stop processing completely
*/
virtual EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
/** Called when we get informed about a users SSL fingerprint
* when we call this, the fingerprint should already be stored in the user struct
* @param u pointer to the user
*/
virtual void OnFingerprint(User *u) { }
/** Called when a vhost is deleted
* @param na The nickalias of the vhost
@@ -991,20 +1017,18 @@ class CoreExport Module : public Extensible
virtual void OnUserModeAdd(UserMode *um) { }
/** Called when a mode is about to be mlocked
* @param ci The channel
* @param Name The mode being mlocked
* @param status true if its being mlocked +, false for -
* @param param The param, if there is one and if status is true
* @param ci The channel the mode is being locked on
* @param lock The mode lock
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
*/
virtual EventReturn OnMLock(ChannelInfo *ci, ChannelModeName Name, bool status, const Anope::string &param) { return EVENT_CONTINUE; }
virtual EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) { return EVENT_CONTINUE; }
/** Called when a mode is about to be unlocked
* @param ci The channel
* @param Name The mode being mlocked
* @param ci The channel the mode is being unlocked from
* @param mode The mode being unlocked
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
*/
virtual EventReturn OnUnMLock(ChannelInfo *ci, ChannelModeName Name) { return EVENT_CONTINUE; }
virtual EventReturn OnUnMLock(ChannelInfo *ci, ChannelMode *mode, const Anope::string &param) { return EVENT_CONTINUE; }
/** Called after a module is loaded
* @param u The user loading the module, can be NULL
@@ -1027,6 +1051,28 @@ class CoreExport Module : public Extensible
* @param s Our uplink
*/
virtual void OnUplinkSync(Server *s) { }
/** Called when we receive a PRIVMSG for one of our clients
* @param u The user sending the PRIVMSG
* @param bi The target of the PRIVMSG
* @param message The message
* @return EVENT_STOP to halt processing
*/
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, const Anope::string &message) { return EVENT_CONTINUE; }
/** Called when we receive a PRIVMSG for a registered channel we are in
* @param u The source of the message
* @param ci The channel
* @param msg The message
* @param Allow set to false to make the flood kickers halt
* @return MOD_STOP to stop processing completely
*/
virtual EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) { return EVENT_CONTINUE; }
/** Called when any object is destroyed
* @param b The object
*/
virtual void OnObjectDestroy(Base *b) { }
};
/** Implementation-specific flags which may be set in ModuleManager::Attach()
@@ -1038,18 +1084,19 @@ enum Implementation
I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop,
I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended,
I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay,
I_OnDelNickRequest, I_OnMakeNickRequest, I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
I_OnNickInfo,
I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
I_OnNickClearCert, I_OnNickAddCert, I_OnNickEraseCert,
I_OnNickInfo, I_OnFindNick, I_OnFindCore, I_OnCheckAuthentication,
/* ChanServ */
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel,
I_OnChanInfo,
I_OnChanInfo, I_OnFindChan,
/* BotServ */
I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign,
I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel,
I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel, I_OnFindBot,
/* HostServ */
I_OnSetVhost, I_OnDeleteVhost,
@@ -1059,7 +1106,7 @@ enum Implementation
/* Users */
I_OnPreUserConnect, I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnFingerprint,
/* OperServ */
I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
@@ -1077,9 +1124,9 @@ enum Implementation
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun,
I_OnPreCommand, I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword,
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnObjectDestroy,
I_END
};
+19 -1
View File
@@ -1,6 +1,6 @@
/* OperServ support
*
* (C) 2008-2010 Anope Team
* (C) 2008-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -138,11 +138,13 @@ class CoreExport XLineManager
*/
virtual XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
private:
/** Delete an XLine, eg, remove it from the IRCd.
* @param x The xline
*/
virtual void Del(XLine *x);
public:
/** Checks if a mask can/should be added to the XLineManager
* @param mask The mask
* @param expires When the mask would expire
@@ -176,6 +178,12 @@ class CoreExport XLineManager
* @param x The xline
*/
virtual void OnExpire(XLine *x);
/** Called to send an XLine to the IRCd
* @param u The user, if we know it
* @param x The xline
*/
virtual void Send(User *u, XLine *x) = 0;
};
/* This is for AKILLS */
@@ -189,6 +197,8 @@ class SGLineManager : public XLineManager
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
class SNLineManager : public XLineManager
@@ -201,6 +211,10 @@ class SNLineManager : public XLineManager
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
XLine *Check(User *u);
};
class SQLineManager : public XLineManager
@@ -214,6 +228,8 @@ class SQLineManager : public XLineManager
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
static bool Check(Channel *c);
};
@@ -227,6 +243,8 @@ class SZLineManager : public XLineManager
void OnMatch(User *u, XLine *x);
void OnExpire(XLine *x);
void Send(User *u, XLine *x);
};
#endif // OPERSERV_H
+37 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -10,6 +10,25 @@
#include "hashcomp.h"
class OperType;
struct Oper
{
Anope::string name;
Anope::string password;
Anope::string certfp;
OperType *ot;
Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) :
name(n), password(p), certfp(c), ot(o) { }
/** Find an oper block by name
* @param name The name
* @return the oper block
*/
static Oper *Find(const Anope::string &name);
};
class CoreExport OperType
{
private:
@@ -36,6 +55,12 @@ class CoreExport OperType
*/
std::set<OperType *> inheritances;
public:
/** Find an oper type by name
* @param name The name
* @return The oper type
*/
static OperType *Find(const Anope::string &name);
/** Create a new opertype of the given name.
* @param nname The opertype name, e.g. "sra".
*/
@@ -71,6 +96,16 @@ class CoreExport OperType
* @param ot The opertype to inherit from
*/
void Inherits(OperType *ot);
/** Gets the icommands for this opertype
* @return A list of commands
*/
const std::list<Anope::string> &GetCommands() const;
/** Gets the privileges for this opertype
* @return A list of privileges
*/
const std::list<Anope::string> &GetPrivs() const;
};
#endif // OPERTYPE_H
+122 -33
View File
@@ -1,6 +1,6 @@
/* Modular support
*
* (C) 2008-2010 Anope Team
* (C) 2008-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -62,15 +62,70 @@ enum ChannelInfoFlag
CI_END
};
const Anope::string ChannelInfoFlagStrings[] = {
"BEGIN", "INHABIT", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
"PEACE", "SECURE", "FORBIDDEN", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
"SIGNKICK", "SIGNKICK_LEVEL", "XOP", "SUSPENDED", "PERSIST", ""
};
class CoreExport ChanAccess
{
Anope::string mask; /* Mask of the access entry */
public:
int16 level;
NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
time_t last_seen;
Anope::string creator;
ChanAccess(const Anope::string &umask);
const Anope::string &GetMask();
};
/** Flags for auto kick
*/
enum AutoKickFlag
{
/* Is by nick core, not mask */
AK_ISNICK
};
const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" };
/* AutoKick data. */
class AutoKick : public Flags<AutoKickFlag>
{
public:
AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString) { }
/* Only one of these can be in use */
Anope::string mask;
NickCore *nc;
Anope::string reason;
Anope::string creator;
time_t addtime;
time_t last_used;
};
struct ModeLock
{
bool set;
ChannelModeName name;
Anope::string param;
Anope::string setter;
time_t created;
ModeLock(bool s, ChannelModeName n, const Anope::string &p, const Anope::string &se = "", time_t c = Anope::CurTime) : set(s), name(n), param(p), setter(se), created(c) { }
};
class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, CI_END>
{
private:
std::map<ChannelModeName, Anope::string> Params; /* Map of parameters by mode name for mlock */
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
private:
std::vector<ChanAccess *> access; /* List of authorized users */
std::vector<AutoKick *> akick; /* List of users to kickban */
std::vector<BadWord *> badwords; /* List of badwords */
Flags<ChannelModeName, CMODE_END * 2> mlock_on; /* Modes mlocked on */
Flags<ChannelModeName, CMODE_END * 2> mlock_off; /* Modes mlocked off */
ModeList mode_locks;
public:
/** Default constructor
@@ -78,6 +133,11 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
ChannelInfo(const Anope::string &chname);
/** Copy constructor
* @param ci The ChannelInfo to copy settings to
*/
ChannelInfo(ChannelInfo *ci);
/** Default destructor
*/
~ChannelInfo();
@@ -94,14 +154,13 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
Anope::string last_topic_setter; /* Setter */
time_t last_topic_time; /* Time */
// These two should be using extensible
Anope::string forbidby;
Anope::string forbidreason;
int16 bantype;
int16 *levels; /* Access levels for commands */
Anope::string entry_message; /* Notice sent on entering channel */
MemoInfo memos;
Channel *c; /* Pointer to channel record (if channel is currently in use) */
@@ -118,14 +177,15 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
/** Add an entry to the channel access list
*
* @param nc The NickCore of the user that the access entry should be tied to
* @param mask The mask of the access entry
* @param level The channel access level the user has on the channel
* @param creator The user who added the access
* @param last_seen When the user was last seen within the channel
* @return The new access class
*
* Creates a new access list entry and inserts it into the access list.
*/
void AddAccess(NickCore *nc, int16 level, const Anope::string &creator, int32 last_seen = 0);
ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0);
/** Get an entry from the channel access list by index
*
@@ -136,15 +196,36 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
ChanAccess *GetAccess(unsigned index);
/** Get an entry from the channel access list by User
*
* @param u The User to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @return A ChanAccess struct corresponding to the User, or NULL if not found
*
* Retrieves an entry from the access list that matches the given User, optionally also matching a certain level.
*/
ChanAccess *GetAccess(User *u, int16 level = 0);
/** Get an entry from the channel access list by NickCore
*
* @param nc The NickCore to find within the access list vector
* @param u The NickCore to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
*
* Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
*/
ChanAccess *GetAccess(const NickCore *nc, int16 level = 0);
ChanAccess *GetAccess(NickCore *nc, int16 level = 0);
/** Get an entry from the channel access list by mask
*
* @param u The mask to find within the access list vector
* @param level Optional channel access level to compare the access entries to
* @param wildcard True to match using wildcards
* @return A ChanAccess struct corresponding to the mask, or NULL if not found
*
* Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level.
*/
ChanAccess *GetAccess(const Anope::string &mask, int16 level = 0, bool wildcard = true);
/** Get the size of the accss vector for this channel
* @return The access vector size
@@ -159,6 +240,14 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
void EraseAccess(unsigned index);
/** Erase an entry from the channel access list
*
* @param taccess The access to remove
*
* Clears the memory used by the given access entry and removes it from the vector.
*/
void EraseAccess(ChanAccess *taccess);
/** Clear the entire channel access list
*
* Clears the entire access list by deleting every item and then clearing the vector.
@@ -236,51 +325,51 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
void LoadMLock();
/** Check if a mode is mlocked
* @param Name The mode
* @param mode The mode
* @param An optional param
* @param status True to check mlock on, false for mlock off
* @return true on success, false on fail
*/
bool HasMLock(ChannelModeName Name, bool status) const;
bool HasMLock(ChannelMode *mode, const Anope::string &param, bool status) const;
/** Set a mlock
* @param Name The mode
* @param mode The mode
* @param status True for mlock on, false for mlock off
* @param param An optional param arg for + mlocked modes
* @param setter Who is setting the mlock
* @param created When the mlock was created
* @return true on success, false on failure (module blocking)
*/
bool SetMLock(ChannelModeName Name, bool status, const Anope::string &param = "");
bool SetMLock(ChannelMode *mode, bool status, const Anope::string &param = "", Anope::string setter = "", time_t created = Anope::CurTime);
/** Remove a mlock
* @param Name The mode
* @return true on success, false on failure (module blcoking)
* @param mode The mode
* @param param The param of the mode, required if it is a list or status mode
* @return true on success, false on failure
*/
bool RemoveMLock(ChannelModeName Name);
bool RemoveMLock(ChannelMode *mode, const Anope::string &param = "");
/** Clear all mlocks on the channel
*/
void ClearMLock();
/** Get the number of mlocked modes for this channel
* @param status true for mlock on, false for mlock off
* @return The number of mlocked modes
/** Get all of the mlocks for this channel
* @return The mlocks
*/
size_t GetMLockCount(bool status) const;
const std::multimap<ChannelModeName, ModeLock> &GetMLock() const;
/** Get a param from the channel
* @param Name The mode
* @param Target a string to put the param into
* @return true on success
/** Get a list of modes on a channel
* @param Name The mode name to get a list of
* @return a pair of iterators for the beginning and end of the list
*/
bool GetParam(ChannelModeName Name, Anope::string &Target) const;
std::pair<ModeList::iterator, ModeList::iterator> GetModeList(ChannelModeName Name);
/** Check if a mode is set and has a param
* @param Name The mode
/** Get details for a specific mlock
* @param mname The mode name
* @param An optional param to match with
* @return The MLock, if any
*/
bool HasParam(ChannelModeName Name) const;
/** Clear all the params from the channel
*/
void ClearParams();
ModeLock *GetMLock(ChannelModeName mname, const Anope::string &param = "");
/** Check whether a user is permitted to be on this channel
* @param u The user
+2 -33
View File
@@ -4,10 +4,7 @@
/* Anope */
extern CoreExport Server *Me;
extern CoreExport void CapabParse(const std::vector<Anope::string> &params);
extern CoreExport void do_server(const Anope::string &source, const Anope::string &servername, unsigned int hops, const Anope::string &descript, const Anope::string &numeric);
extern CoreExport void do_squit(const Anope::string &source, const Anope::string &server);
extern CoreExport const char *ts6_uid_retrieve();
extern CoreExport const char *ts6_sid_retrieve();
@@ -21,33 +18,7 @@ enum CapabType
CAPAB_NOQUIT,
CAPAB_TSMODE,
CAPAB_UNCONNECT,
CAPAB_NICKIP,
CAPAB_NSJOIN,
CAPAB_ZIP,
CAPAB_BURST,
CAPAB_TS3,
CAPAB_TS5,
CAPAB_DKEY,
CAPAB_DOZIP,
CAPAB_DODKEY,
CAPAB_QS,
CAPAB_SCS,
CAPAB_PT4,
CAPAB_UID,
CAPAB_KNOCK,
CAPAB_CLIENT,
CAPAB_IPV6,
CAPAB_SSJ5,
CAPAB_SN2,
CAPAB_VHOST,
CAPAB_TOKEN,
CAPAB_SSJ3,
CAPAB_NICK2,
CAPAB_VL,
CAPAB_TLKEXT,
CAPAB_CHANMODE,
CAPAB_SJB64,
CAPAB_NICKCHARS,
CAPAB_END
};
@@ -73,6 +44,8 @@ enum ServerFlag
SERVER_JUPED
};
const Anope::string ServerFlagStrings[] = { "SERVER_NONE", "SERVER_SYNCING", "SERVER_JUPED", "" };
/** Class representing a server
*/
class CoreExport Server : public Flags<ServerFlag>
@@ -159,10 +132,6 @@ class CoreExport Server : public Flags<ServerFlag>
*/
void DelLink(Server *s);
/** Remove all links from this server
*/
void ClearLinks();
/** Finish syncing this server and optionally all links to it
* @param SyncLinks True to sync the links for this server too (if any)
*/
+136 -139
View File
@@ -1,9 +1,9 @@
/*
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -43,6 +43,13 @@
#include <fcntl.h>
#include <typeinfo>
#if GETTEXT_FOUND
# include <libintl.h>
# define _(x) anope_gettext(x)
#else
# define _(x) x
#endif
#ifndef _WIN32
# include <unistd.h>
# include <grp.h>
@@ -50,6 +57,7 @@
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/socket.h>
# include <sys/time.h>
# include <dirent.h>
# ifdef HAVE_BACKTRACE
# include <execinfo.h>
@@ -59,31 +67,7 @@
# define MARK_DEPRECATED __attribute((deprecated))
# define DeleteFile unlink
#else
# include <winsock2.h>
# include <ws2tcpip.h>
# include <windows.h>
# include <sys/timeb.h>
# include <direct.h>
# include <io.h>
# ifdef MODULE_COMPILE
# define CoreExport __declspec(dllimport)
# define DllExport __declspec(dllexport)
# else
# define CoreExport __declspec(dllexport)
# define DllExport __declspec(dllimport)
# endif
/* VS2008 hates having this define before its own */
# define vsnprintf _vsnprintf
/* We have our own inet_pton and inet_ntop (Windows doesn't have its own) */
# define inet_pton inet_pton_
# define inet_ntop inet_ntop_
# define setenv(x, y, z) SetEnvironmentVariable(x, y)
# define unsetenv(x) SetEnvironmentVariable(x, NULL)
# define MARK_DEPRECATED
extern CoreExport USHORT WindowsGetLanguage(const char *lang);
extern CoreExport int inet_pton(int af, const char *src, void *dst);
extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size_t size);
# include "anope_windows.h"
#endif
/* Telling compilers about printf()-like functions: */
@@ -93,18 +77,10 @@ extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size
# define FORMAT(type, fmt, start)
#endif
#ifdef HAVE_GETTIMEOFDAY
# include <sys/time.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#if HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef _AIX
/* Some AIX boxes seem to have bogus includes that don't have these
* prototypes. */
@@ -128,18 +104,6 @@ extern int strncasecmp(const char *, const char *, size_t);
#define tolower tolower_
#define toupper toupper_
#ifdef __WINS__
# ifndef BKCHECK
# define BKCHECK
extern "C" void __pfnBkCheck() {}
# endif
#endif
#if INTTYPE_WORKAROUND
# undef int16
# undef int32
#endif
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
* It defines the class factory and external AnopeInit and AnopeFini functions.
@@ -305,8 +269,11 @@ template<typename T, size_t Size = 32> class Flags
{
protected:
std::bitset<Size> Flag_Values;
const Anope::string *Flag_Strings;
public:
Flags(const Anope::string *flag_strings) : Flag_Strings(flag_strings) { }
/** Add a flag to this item
* @param Value The flag
*/
@@ -346,6 +313,23 @@ template<typename T, size_t Size = 32> class Flags
{
Flag_Values.reset();
}
std::vector<Anope::string> ToString()
{
std::vector<Anope::string> ret;
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
if (this->HasFlag(static_cast<T>(i)))
ret.push_back(this->Flag_Strings[i]);
return ret;
}
void FromString(const std::vector<Anope::string> &strings)
{
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
for (unsigned j = 0; j < strings.size(); ++j)
if (this->Flag_Strings[i] == strings[j])
this->SetFlag(static_cast<T>(i));
}
};
#include "sockets.h"
@@ -356,12 +340,20 @@ template<typename T, size_t Size = 32> class Flags
/*************************************************************************/
class ConvertException : public CoreException
{
public:
ConvertException(const Anope::string &reason = "") : CoreException(reason) { }
virtual ~ConvertException() throw() { }
};
template<typename T> inline Anope::string stringify(const T &x)
{
std::ostringstream stream;
if (!(stream << x))
throw CoreException("Stringify fail");
throw ConvertException("Stringify fail");
return stream.str();
}
@@ -373,11 +365,11 @@ template<typename T> inline void convert(const Anope::string &s, T &x, Anope::st
char c;
bool res = i >> x;
if (!res)
throw CoreException("Convert fail");
throw ConvertException("Convert fail");
if (failIfLeftoverChars)
{
if (i.get(c))
throw CoreException("Convert fail");
throw ConvertException("Convert fail");
}
else
{
@@ -412,12 +404,11 @@ template<typename T> inline T convertTo(const Anope::string &s, bool failIfLefto
class User;
class NickCore;
class NickAlias;
class NickRequest;
class BotInfo;
class ChannelInfo;
class Channel;
class Server;
struct EList;
class Entry;
struct Session;
#include "threadengine.h"
@@ -432,7 +423,6 @@ struct IRCDVar
{
const char *name; /* Name of the IRCd command */
const char *pseudoclient_mode; /* Mode used by BotServ Bots */
int max_symbols; /* Chan Max Symbols */
int svsnick; /* Supports SVSNICK */
int vhost; /* Supports vhost */
int snline; /* Supports SNline */
@@ -441,8 +431,6 @@ struct IRCDVar
int join2msg; /* Join 2 Message */
int chansqline; /* Supports Channel Sqlines */
int quitonkill; /* IRCD sends QUIT when kill */
int svsmode_unban; /* svsmode can be used to unban */
int reversekickcheck; /* Can reverse ban check */
int vident; /* Supports vidents */
int svshold; /* Supports svshold */
int tsonmode; /* Timestamp on mode changes */
@@ -452,11 +440,9 @@ struct IRCDVar
int svsmode_ucmode; /* Can remove User Channel Modes with SVSMODE */
int sglineenforce;
int ts6; /* ircd is TS6 */
int cidrchanbei; /* channel bans/excepts/invites support CIDR (syntax: +b *!*@192.168.0.0/15)
* 0 for no support, 1 for strict cidr support, anything else
* for ircd specific support (nefarious only cares about first /mask) */
const char *globaltldprefix; /* TLD prefix used for Global */
unsigned maxmodes; /* Max modes to send per line */
int certfp; /* IRCd sends a SSL users certificate fingerprint */
};
/*************************************************************************/
@@ -467,17 +453,22 @@ enum MemoFlag
{
/* Memo is unread */
MF_UNREAD,
/* SEnder requests a receipt */
/* Sender requests a receipt */
MF_RECEIPT,
/* Memo is a notification of receipt */
MF_NOTIFYS
};
const Anope::string MemoFlagStrings[] = {
"MF_UNREAD", "MF_RECEIPT", "MF_NOTIFYS", ""
};
/* Memo info structures. Since both nicknames and channels can have memos,
* we encapsulate memo data in a MemoList to make it easier to handle. */
class Memo : public Flags<MemoFlag>
class CoreExport Memo : public Flags<MemoFlag>
{
public:
Memo();
time_t time; /* When it was sent */
Anope::string sender;
Anope::string text;
@@ -485,12 +476,14 @@ class Memo : public Flags<MemoFlag>
struct CoreExport MemoInfo
{
unsigned memomax;
int16 memomax;
std::vector<Memo *> memos;
std::vector<ci::string> ignores;
unsigned GetIndex(Memo *m) const;
void Del(unsigned index);
void Del(Memo *m);
bool HasIgnore(User *u);
};
/*************************************************************************/
@@ -564,44 +557,6 @@ enum AccessLevel
ACCESS_QOP = 10000
};
/* Channel info structures. Stored similarly to the nicks, except that
* the second character of the channel name, not the first, is used to
* determine the list. (Hashing based on the first character of the name
* wouldn't get very far. ;) ) */
/* Access levels for users. */
struct ChanAccess
{
int16 level;
NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */
time_t last_seen;
Anope::string creator;
};
/** Flags for auto kick
*/
enum AutoKickFlag
{
/* Is by nick core, not mask */
AK_ISNICK,
/* This entry is stuck */
AK_STUCK
};
/* AutoKick data. */
class AutoKick : public Flags<AutoKickFlag>
{
public:
/* Only one of these can be in use */
Anope::string mask;
NickCore *nc;
Anope::string reason;
Anope::string creator;
time_t addtime;
time_t last_used;
};
/** Flags for badwords
*/
enum BadWordType
@@ -631,11 +586,9 @@ enum ChannelAccess
CA_SET, /* but not FOUNDER or PASSWORD */
CA_UNBAN,
CA_AUTOOP,
CA_AUTODEOP, /* Maximum, not minimum */
CA_AUTOVOICE,
CA_OPDEOP, /* ChanServ commands OP and DEOP */
CA_ACCESS_LIST,
CA_CLEAR,
CA_NOJOIN, /* Maximum */
CA_ACCESS_CHANGE,
CA_MEMO,
@@ -661,6 +614,7 @@ enum ChannelAccess
CA_BANME,
CA_BAN,
CA_TOPIC,
CA_MODE,
CA_INFO,
CA_AUTOOWNER,
CA_OWNER,
@@ -703,9 +657,24 @@ enum BotServFlag
BS_KICK_REPEAT,
/* BotServ kicks for italics */
BS_KICK_ITALICS,
/* BotServ kicks for amsgs */
BS_KICK_AMSGS,
/* Send fantasy replies back to the channel via PRIVMSG */
BS_MSG_PRIVMSG,
/* Send fantasy replies back to the channel via NOTICE */
BS_MSG_NOTICE,
/* Send fantasy replies back to the channel via NOTICE to ops */
BS_MSG_NOTICEOPS,
BS_END
};
const Anope::string BotServFlagStrings[] = {
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "SYMBIOSIS", "GREET", "NOBOT",
"KICK_BOLDs", "KICK_COLORS", "KICK_REVERSES", "KICK_UNDERLINES", "KICK_BADWORDS", "KICK_CAPS",
"KICK_FLOOD", "KICK_REPEAT", "KICK_ITALICS", "KICK_AMSGS", "MSG_PRIVMSG", "MSG_NOTICE",
"MSG_NOTICEOPS", ""
};
/* Indices for TTB (Times To Ban) */
enum
{
@@ -718,6 +687,7 @@ enum
TTB_FLOOD,
TTB_REPEAT,
TTB_ITALICS,
TTB_AMSGS,
TTB_SIZE
};
@@ -729,7 +699,6 @@ enum
* user is kicked.
*/
#include "language.h"
#include "users.h"
#include "account.h"
#include "bots.h"
@@ -745,7 +714,7 @@ struct LevelInfo
{
int what;
Anope::string name;
LanguageString desc;
const char *desc;
};
#include "channels.h"
@@ -755,7 +724,7 @@ struct LevelInfo
enum EntryType
{
ENTRYTYPE_NONE,
ENTRYTYPE_CIDR4,
ENTRYTYPE_CIDR,
ENTRYTYPE_NICK_WILD,
ENTRYTYPE_NICK,
ENTRYTYPE_USER_WILD,
@@ -764,29 +733,32 @@ enum EntryType
ENTRYTYPE_HOST
};
class Entry : public Flags<EntryType>
class CoreExport Entry : public Flags<EntryType>
{
ChannelModeName modename;
public:
Entry *next, *prev;
uint32 cidr_ip; /* IP mask for CIDR matching */
uint32 cidr_mask; /* Netmask for CIDR matching */
Anope::string nick, user, host, mask;
};
struct EList
{
Entry *entries;
int32 count;
};
/*************************************************************************/
/* Ignorance list data. */
struct IgnoreData
{
unsigned char cidr_len;
Anope::string mask;
time_t time; /* When do we stop ignoring them? */
Anope::string nick, user, host;
/** Constructor
* @param _host A full nick!ident@host/cidr mask
* @param mode What mode this host is for - can be CMODE_BEGIN for unknown/no mode
*/
Entry(ChannelModeName mode, const Anope::string &_host);
/** Get the banned mask for this entry
* @return The mask
*/
const Anope::string GetMask();
/** Check if this entry matches a user
* @param u The user
* @param full True to match against a users real host and IP
* @return true on match
*/
bool Matches(User *u, bool full = false) const;
};
/*************************************************************************/
@@ -804,7 +776,7 @@ struct NewsMessages
{
NewsType type;
Anope::string name;
LanguageString msgs[10];
const char *msgs[10];
};
struct NewsItem
@@ -825,7 +797,6 @@ struct MailInfo
FILE *pipe;
User *sender;
NickCore *recipient;
NickRequest *recip;
};
/*************************************************************************/
@@ -842,8 +813,7 @@ struct Exception
/*************************************************************************/
typedef unordered_map_namespace::unordered_map<Anope::string, Session *, Anope::hash> session_map;
extern CoreExport session_map SessionList;
extern CoreExport Anope::map<Session *> SessionList;
struct Session
{
@@ -886,10 +856,13 @@ enum DefconLevel
* Forward declaration reqired, because the base IRCDProto class uses some crap from in here.
*/
class IRCDProto;
class IRCdMessage;
struct Uplink;
class ServerConfig;
class ConfigurationFile;
#include "extern.h"
#include "language.h"
#include "operserv.h"
#include "mail.h"
#include "servers.h"
@@ -918,10 +891,9 @@ class CoreExport IRCDProto
virtual void SendSVSNOOP(const Anope::string &, int) { }
virtual void SendTopic(BotInfo *, Channel *) = 0;
virtual void SendVhostDel(User *) { }
virtual void SendAkill(const XLine *) = 0;
virtual void SendAkill(User *, const XLine *) = 0;
virtual void SendAkillDel(const XLine *) = 0;
virtual void SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...);
virtual void SendSVSMode(const User *, int, const char **) = 0;
virtual void SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...);
virtual void SendClientIntroduction(const User *u, const Anope::string &) = 0;
@@ -937,13 +909,12 @@ class CoreExport IRCDProto
virtual void SendQuit(const User *u, const char *fmt, ...);
virtual void SendPing(const Anope::string &servname, const Anope::string &who);
virtual void SendPong(const Anope::string &servname, const Anope::string &who);
virtual void SendJoin(const BotInfo *, const Anope::string &, time_t) = 0;
virtual void SendJoin(BotInfo *, const ChannelContainer *);
virtual void SendSQLineDel(const XLine *x) = 0;
virtual void SendJoin(BotInfo *, Channel *, const ChannelStatus *) = 0;
virtual void SendSQLineDel(const XLine *x) { }
virtual void SendInvite(const BotInfo *bi, const Anope::string &chan, const Anope::string &nick);
virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...);
virtual void SendGlobops(const BotInfo *source, const char *fmt, ...);
virtual void SendSQLine(const XLine *x) = 0;
virtual void SendSQLine(User *, const XLine *x) { }
virtual void SendSquit(const Anope::string &servname, const Anope::string &message);
virtual void SendSVSO(const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendChangeBotNick(const BotInfo *bi, const Anope::string &newnick);
@@ -954,14 +925,11 @@ class CoreExport IRCDProto
virtual void SendSVSHoldDel(const Anope::string &) { }
virtual void SendSGLineDel(const XLine *) { }
virtual void SendSZLineDel(const XLine *) { }
virtual void SendSZLine(const XLine *) { }
virtual void SendSGLine(const XLine *) { }
virtual void SendBanDel(const Channel *, const Anope::string &) { }
virtual void SendSVSModeChan(const Channel *, const Anope::string &, const Anope::string &) { }
virtual void SendSZLine(User *u, const XLine *) { }
virtual void SendSGLine(User *, const XLine *) { }
virtual void SendUnregisteredNick(const User *) { }
virtual void SendCTCP(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendSVSJoin(const Anope::string &, const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendSVSPart(const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendSWhois(const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendBOB() { }
virtual void SendEOB() { }
@@ -986,6 +954,35 @@ class CoreExport IRCDProto
* @param u The user
*/
virtual void SetAutoIdentificationToken(User *u) { }
/** Send a channel creation message to the uplink.
* On most TS6 IRCds this is a SJOIN with no nick
*/
virtual void SendChannel(Channel *c) { }
};
class CoreExport IRCdMessage
{
public:
virtual bool On436(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnAway(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnJoin(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnKick(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnKill(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnMode(const Anope::string &, const std::vector<Anope::string> &) = 0;
virtual bool OnUID(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnNick(const Anope::string &, const std::vector<Anope::string> &) = 0;
virtual bool OnPart(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnPing(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnPrivmsg(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnQuit(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnServer(const Anope::string &, const std::vector<Anope::string> &) = 0;
virtual bool OnSQuit(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnTopic(const Anope::string &, const std::vector<Anope::string> &) = 0;
virtual bool OnWhois(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnCapab(const Anope::string &, const std::vector<Anope::string> &);
virtual bool OnSJoin(const Anope::string &, const std::vector<Anope::string> &) = 0;
virtual bool OnError(const Anope::string &, const std::vector<Anope::string> &);
};
/*************************************************************************/
+2 -2
View File
@@ -1,9 +1,9 @@
/*
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
+18 -4
View File
@@ -1,9 +1,9 @@
/*
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -80,6 +80,18 @@ union CoreExport sockaddrs
void ntop(int type, const void *src);
};
class CoreExport cidr
{
sockaddrs addr;
Anope::string cidr_ip;
unsigned char cidr_len;
public:
cidr(const Anope::string &ip);
cidr(const Anope::string &ip, unsigned char len);
Anope::string mask() const;
bool match(sockaddrs &other);
};
class SocketException : public CoreException
{
public:
@@ -109,6 +121,8 @@ enum SocketFlag
SF_WRITABLE
};
static const Anope::string SocketFlagStrings[] = { "SF_DEAD", "SF_WRITABLE", "" };
class Socket;
class ClientSocket;
class ListenSocket;
@@ -328,13 +342,13 @@ class CoreExport ConnectionSocket : public BufferedSocket
void Connect(const Anope::string &TargetHost, int Port, const Anope::string &BindHost = "");
};
class ClientSocket : public BufferedSocket
class CoreExport ClientSocket : public BufferedSocket
{
public:
/* Listen socket this connection came from */
ListenSocket *LS;
/* Clients address */
sockaddrs clientaddr;
public:
/** Constructor
* @param ls Listen socket this connection is from
-6
View File
@@ -8,19 +8,16 @@
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STDDEF_H 1
#cmakedefine HAVE_BACKTRACE 1
#cmakedefine HAVE_GETTIMEOFDAY 1
#cmakedefine HAVE_SETGRENT 1
#cmakedefine HAVE_STRCASECMP 1
#cmakedefine HAVE_STRICMP 1
#cmakedefine HAVE_STRINGS_H 1
#cmakedefine HAVE_STRLCAT 1
#cmakedefine HAVE_STRLCPY 1
#cmakedefine HAVE_SYS_SELECT_H 1
#cmakedefine HAVE_UMASK 1
#cmakedefine HAVE_EVENTFD 1
#cmakedefine GETTEXT_FOUND 1
#cmakedefine RUNGROUP "@RUNGROUP@"
#define LIBINTL "@LIBINTL_INCLUDE@"
#cmakedefine HAVE_UINT8_T 1
#cmakedefine HAVE_U_INT8_T 1
@@ -104,9 +101,6 @@ typedef unsigned long uint32;
#endif
#ifdef _WIN32
# ifdef MSVCPP
# define snprintf _snprintf
# endif
# define popen _popen
# define pclose _pclose
# define ftruncate _chsize
+11 -1
View File
@@ -45,7 +45,7 @@ class CoreExport Thread : public Extensible
{
private:
/* Set to true to tell the thread to finish and we are waiting for it */
bool Exit;
bool exit;
public:
/* Handle for this thread */
@@ -67,6 +67,10 @@ class CoreExport Thread : public Extensible
*/
void SetExitState();
/** Exit the thread. Note that the thread still must be joined to free resources!
*/
void Exit();
/** Returns the exit state of the thread
* @return true if we want to exit
*/
@@ -99,6 +103,12 @@ class CoreExport Mutex
/** Unlock the mutex, it must be locked first
*/
void Unlock();
/** Attempt to lock the mutex, will return true on success and false on fail
* Does not block
* @return true or false
*/
bool TryLock();
};
class CoreExport Condition : public Mutex
+2 -2
View File
@@ -1,9 +1,9 @@
/* Timer include stuff.
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
+40 -24
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -8,18 +8,13 @@
#ifndef USERS_H
#define USERS_H
/* Hash maps used for users. Note UserListByUID will not be used on non-TS6 IRCds, and should never
* be assumed to have users
*/
typedef unordered_map_namespace::unordered_map<Anope::string, User *, ci::hash, std::equal_to<ci::string> > user_map;
typedef unordered_map_namespace::unordered_map<Anope::string, User *, Anope::hash> user_uid_map;
extern CoreExport user_map UserListByNick;
extern CoreExport user_uid_map UserListByUID;
extern CoreExport Anope::insensitive_map<User *> UserListByNick;
extern CoreExport Anope::map<User *> UserListByUID;
class CoreExport ChannelStatus : public Flags<ChannelModeName, CMODE_END * 2>
{
public:
ChannelStatus();
Anope::string BuildCharPrefixList() const;
Anope::string BuildModePrefixList() const;
};
@@ -54,6 +49,7 @@ class CoreExport User : public Extensible
Anope::string vhost; /* User's virtual hostname */
Anope::string chost; /* User's cloaked hostname */
Anope::string realname; /* Realname */
Anope::string fingerprint; /* SSL Fingerprint */
sockaddrs ip; /* User's IP */
Server *server; /* Server user is connected to */
time_t timestamp; /* Timestamp of the nick */
@@ -90,7 +86,7 @@ class CoreExport User : public Extensible
/** Update the nickname of a user record accordingly, should be
* called from ircd protocol.
*/
virtual void SetNewNick(const Anope::string &newnick);
void SetNewNick(const Anope::string &newnick);
/** Update the displayed (vhost) of a user record.
* This is used (if set) instead of real host.
@@ -145,25 +141,22 @@ class CoreExport User : public Extensible
*/
Anope::string GetMask() const;
/** Get the full display mask (nick!vident@vhost/chost)
*/
Anope::string GetDisplayedMask() const;
/** Updates the realname of the user record.
*/
void SetRealname(const Anope::string &realname);
/**
* Send a message (notice or privmsg, depending on settings) to a user
* @param source Sender nick
* @param source Sender
* @param fmt Format of the Message
* @param ... any number of parameters
*/
virtual void SendMessage(const Anope::string &source, const char *fmt, ...) const;
virtual void SendMessage(const Anope::string &source, const Anope::string &msg) const;
/** Send a language string message to a user
* @param source Sender
* @param message The message num
* @param ... parameters
*/
void SendMessage(BotInfo *source, LanguageString message, ...) const;
void SendMessage(BotInfo *source, const char *fmt, ...);
virtual void SendMessage(BotInfo *source, Anope::string msg);
/** Collide a nick
* See the comment in users.cpp
@@ -171,6 +164,13 @@ class CoreExport User : public Extensible
*/
void Collide(NickAlias *na);
/** Identify the user to the Nick
* updates last_seen, logs the user in,
* send messages, checks for mails, set vhost and more
* @param the NickAlias
*/
void Identify(NickAlias *na);
/** Login the user to a NickCore
* @param core The account the user is useing
*/
@@ -184,19 +184,35 @@ class CoreExport User : public Extensible
* @return The account or NULL
*/
virtual NickCore *Account();
virtual const NickCore *Account() const;
/** Check if the user is identified for their nick
* @param CheckNick True to check if the user is identified to the nickname they are on too
* @return true or false
*/
virtual bool IsIdentified(bool CheckNick = false) const;
virtual bool IsIdentified(bool CheckNick = false);
/** Check if the user is recognized for their nick (on the nicks access list)
* @param CheckSecure Only returns true if the user has secure off
* @return true or false
*/
virtual bool IsRecognized(bool CheckSecure = false) const;
virtual bool IsRecognized(bool CheckSecure = false);
/** Check if the user is a services oper
* @return true if they are an oper
*/
bool IsServicesOper();
/** Check whether this user has access to run the given command string.
* @param cmdstr The string to check, e.g. botserv/set/private.
* @return True if this user may run the specified command, false otherwise.
*/
bool HasCommand(const Anope::string &cmdstr);
/** Check whether this user has access to the given special permission.
* @param privstr The priv to check for, e.g. users/auspex.
* @return True if this user has the specified priv, false otherwise.
*/
bool HasPriv(const Anope::string &privstr);
/** Update the last usermask stored for a user, and check to see if they are recognized
*/
+10 -3
View File
@@ -1,9 +1,9 @@
/* Build bumper
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for furhter details.
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
@@ -54,12 +54,19 @@ int main(int argc, char *argv[])
std::string version_build = "#define VERSION_BUILD 1";
std::string build = "#define BUILD 1";
std::string version_extra;
if (fd.is_open())
{
while (getline(fd, filebuf))
{
if (!filebuf.find("#define VERSION_BUILD"))
version_build = filebuf;
else if (!filebuf.find("#define VERSION_EXTRA"))
{
size_t q = filebuf.find('"');
version_extra = filebuf.substr(q + 1, filebuf.length() - q - 2);
}
else if (!filebuf.find("#define BUILD"))
{
size_t tab = filebuf.find(' ');
@@ -89,7 +96,7 @@ int main(int argc, char *argv[])
for (std::list<std::pair<std::string, std::string> >::iterator it = versions.begin(), it_end = versions.end(); it != it_end; ++it)
{
if (it->first == "EXTRA")
fd << "#define VERSION_EXTRA \"" << it->second << "\"" << std::endl;
fd << "#define VERSION_EXTRA \"" << (!version_extra.empty() ? version_extra : "") << (version_extra.find(it->second) == std::string::npos ? it->second : "") << "\"" << std::endl;
else
fd << "#define VERSION_" << it->first << " " << it->second << std::endl;
}
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
HLANG=`cat ../include/language.h | grep "^\s" | sed 's/[\t,]//g'`
CPPLANG=`cat ../src/language.cpp | grep "\s\/\* [A-Z0-9_]* \*\/" | sed 's/\/\* \(.*\) \*\//\1/' | sed 's/\t//'`
echo "${HLANG} ${CPPLANG}" | sed 's/ /\n/' | sort | uniq -u
-27
View File
@@ -1,27 +0,0 @@
# Italian translations for ns_maxemail
# Traduzioni italiane per il ns_maxemail
# Copyright (C) 2010 Anope Team
# This file is distributed under the same license as Anope IRC Services
# Adam <adam@anope.org>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-09-25 23:51-0400\n"
"PO-Revision-Date: 2010-09-26 00:11-0400\n"
"Last-Translator: Adam <adam@anope.org>\n"
"Language-Team: Italian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ns_maxemail.cpp:33
#, c-format
msgid "The given email address has reached it's usage limit of %d users."
msgstr "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di %d utenti."
#: ns_maxemail.cpp:31
msgid "The given email address has reached it's usage limit of 1 user."
msgstr "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di 1 utente."
-10
View File
@@ -1,10 +0,0 @@
#!/bin/bash
for string in `egrep "^.+[A-Z]+," ../include/language.h | sed "s/\t\(.*\),/\1/"` ; do
CMD=`grep -RI $string {../src,../modules,../include} | grep -v "language\.cpp:.*\/\* $string" | grep -v "language\.h:"`
if [ ! -n "$CMD" ] ; then
echo "$string is unused"
sed -i "s/\/\* $string \*\//\/* $string - UNUSED *\//" ../src/language.cpp
sed -i "/$string,/d" ../include/language.h
fi
done
-10
View File
@@ -1,10 +0,0 @@
#!/bin/bash
pushd ../src > /dev/null
xgettext -C -s -d Anope -o ../lang/anope.pot --from-code=utf-8 --keyword=_ language.cpp
popd > /dev/null
for f in *.po
do
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
done
@@ -24,7 +24,6 @@ if(GETTEXT_FOUND)
MAIN_DEPENDENCY ${LANG_PO}
)
# Add to cpack ignored files if not on Windows.
file(RELATIVE_PATH LANG_RELATIVE ${Anope_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${LANG_LANG})
if(NOT WIN32)
add_to_cpack_ignored_files("${LANG_MO}")
endif(NOT WIN32)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
rm anope.pot
touch anope.pot
cd ..
FILES=`find ./ -name *.cpp -o -name *.h | grep -v /modules/extra/`
for f in $FILES
do
xgettext -C -s -d Anope -j -o language/anope.pot --from-code=utf-8 --keyword=_ $f
done
cd -
for f in *.po
do
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
done
rm -f *~
+15 -8
View File
@@ -1,3 +1,5 @@
add_subdirectory("extra/language")
# Get a list of ALL files and directories within the current directory
file(GLOB MODULES_FOLDERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
remove_item_from_list(MODULES_FOLDERS "CMakeFiles")
@@ -75,10 +77,10 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
set(WIN32_NO_LIBS)
endif(WIN32)
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}")
add_dependencies(${SO} ${PROGRAM_NAME})
# For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
# For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
if(WIN32)
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES})
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES})
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
endif(WIN32)
# Set the module to be installed to the module directory under the data directory
@@ -86,12 +88,15 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
DESTINATION data/modules
)
endif(HAS_FUNCTION)
else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES)
message(" This is not a fatal error - ${SRC} will not be built.")
endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES)
endforeach(SRC)
# Get a list of ALL files and directories within this modules directory
file(GLOB SUBMODULE_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${MODULE_FOLDER}/*")
remove_item_from_list(SUBMODULE_DIRS "CMakeFiles")
remove_item_from_list(SUBMODULE_DIRS "extra/language")
foreach(SUBDIR ${SUBMODULE_DIRS})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
@@ -149,7 +154,7 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
endforeach(SRC)
# Continue if library and function requirements are met
if(NOT SKIP AND HAS_FUNCTION)
if(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
# Remove duplicates from the linker flags
if(SUBDIR_LDFLAGS)
remove_list_duplicates(SUBDIR_LDFLAGS)
@@ -169,17 +174,19 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
# Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand
add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS})
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}")
add_dependencies(${SO} ${PROGRAM_NAME})
# For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
# For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
if(WIN32)
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS})
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS})
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
endif(WIN32)
# Set the module to be installed to the module directory under the data directory
install(TARGETS ${SO}
DESTINATION data/modules
)
endif(NOT SKIP AND HAS_FUNCTION)
else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
message(" This is not a fatal error - ${SUBDIR} will not be built.")
endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
endforeach(SUBDIR)
endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FOLDER}")
+15 -15
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,28 +18,30 @@ class CommandBSAct : public Command
public:
CommandBSAct() : Command("ACT", 2, 2)
{
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = cs_findchan(params[0]);
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string message = params[1];
if (!check_access(u, ci, CA_SAY))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (!ci->bi)
{
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
return MOD_CONT;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
u->SendMessage(BotServ, BOT_NOT_ON_CHANNEL, ci->name.c_str());
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
return MOD_CONT;
}
@@ -56,21 +58,19 @@ class CommandBSAct : public Command
return MOD_CONT;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "ACT", BOT_ACT_SYNTAX);
SyntaxError(source, "ACT", _("ACT \037channel\037 \037text\037"));
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_ACT);
source.Reply(_("Syntax: \002ACT \037channel\037 \037text\037\002\n"
" \n"
"Makes the bot do the equivalent of a \"/me\" command\n"
"on the given channel using the given text."));
return true;
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_ACT);
}
};
class BSAct : public Module
+25 -26
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,44 +18,44 @@ class CommandBSAssign : public Command
public:
CommandBSAssign() : Command("ASSIGN", 2, 2)
{
this->SetDesc(_("Assigns a bot to a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string nick = params[1];
BotInfo *bi;
ChannelInfo *ci;
const Anope::string &chan = params[0];
const Anope::string &nick = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
u->SendMessage(BotServ, BOT_ASSIGN_READONLY);
source.Reply(_(BOT_ASSIGN_READONLY));
return MOD_CONT;
}
if (!(bi = findbot(nick)))
BotInfo *bi = findbot(nick);
if (!bi)
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
}
ci = cs_findchan(chan);
if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->Account()->HasPriv("botserv/administration")))
if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration")))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (bi->HasFlag(BI_PRIVATE) && !u->Account()->HasCommand("botserv/assign/private"))
if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private"))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (ci->bi && nick.equals_ci(ci->bi->nick))
{
u->SendMessage(BotServ, BOT_ASSIGN_ALREADY, ci->bi->nick.c_str(), chan.c_str());
source.Reply(_("Bot \002%s\002 is already assigned to channel \002%s\002."), ci->bi->nick.c_str(), chan.c_str());
return MOD_CONT;
}
@@ -63,24 +63,23 @@ class CommandBSAssign : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick;
bi->Assign(u, ci);
u->SendMessage(BotServ, BOT_ASSIGN_ASSIGNED, bi->nick.c_str(), ci->name.c_str());
source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str());
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_ASSIGN);
source.Reply(_("Syntax: \002ASSIGN \037chan\037 \037nick\037\002\n"
" \n"
"Assigns a bot pointed out by nick to the channel chan. You\n"
"can then configure the bot for the channel so it fits\n"
"your needs."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_ASSIGN);
SyntaxError(source, "ASSIGN", _("ASSIGN \037chan\037 \037nick\037"));
}
};
+102 -70
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,88 +15,88 @@
class BadwordsListCallback : public NumberList
{
User *u;
ChannelInfo *ci;
CommandSource &source;
bool SentHeader;
public:
BadwordsListCallback(User *_u, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), u(_u), ci(_ci), SentHeader(false)
BadwordsListCallback(CommandSource &_source, const Anope::string &list) : NumberList(list, false), source(_source), SentHeader(false)
{
}
~BadwordsListCallback()
{
if (!SentHeader)
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetBadWordCount())
if (!Number || Number > source.ci->GetBadWordCount())
return;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(BotServ, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), source.ci->name.c_str());
}
DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1));
DoList(source, Number - 1, source.ci->GetBadWord(Number - 1));
}
static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw)
static void DoList(CommandSource &source, unsigned Number, BadWord *bw)
{
u->SendMessage(BotServ, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")));
source.Reply(_(" %3d %-30s %s"), Number + 1, bw->word.c_str(), bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")));
}
};
class BadwordsDelCallback : public NumberList
{
User *u;
ChannelInfo *ci;
CommandSource &source;
Command *c;
unsigned Deleted;
bool override;
public:
BadwordsDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0), override(false)
BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false)
{
if (!check_access(u, ci, CA_BADWORDS) && u->Account()->HasPriv("botserv/administration"))
if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
this->override = true;
}
~BadwordsDelCallback()
{
if (!Deleted)
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
else if (Deleted == 1)
u->SendMessage(BotServ, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s bad words list."), source.ci->name.c_str());
else
u->SendMessage(BotServ, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str());
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, source.ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetBadWordCount())
if (!Number || Number > source.ci->GetBadWordCount())
return;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL " << ci->GetBadWord(Number -1 )->word;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "DEL " << source.ci->GetBadWord(Number - 1)->word;
++Deleted;
ci->EraseBadWord(Number - 1);
source.ci->EraseBadWord(Number - 1);
}
};
class CommandBSBadwords : public Command
{
private:
CommandReturn DoList(User *u, ChannelInfo *ci, const Anope::string &word)
CommandReturn DoList(CommandSource &source, const Anope::string &word)
{
bool override = !check_access(u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
ChannelInfo *ci = source.ci;
bool override = !check_access(source.u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
if (!ci->GetBadWordCount())
u->SendMessage(BotServ, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
{
BadwordsListCallback list(u, ci, word);
BadwordsListCallback list(source, word);
list.Process();
}
else
@@ -113,21 +113,24 @@ class CommandBSBadwords : public Command
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(BotServ, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), ci->name.c_str());
}
BadwordsListCallback::DoList(u, ci, i, bw);
BadwordsListCallback::DoList(source, i, bw);
}
if (!SentHeader)
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
return MOD_CONT;
}
CommandReturn DoAdd(User *u, ChannelInfo *ci, const Anope::string &word)
CommandReturn DoAdd(CommandSource &source, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
size_t pos = word.rfind(' ');
BadWordType type = BW_ANY;
Anope::string realword = word;
@@ -149,7 +152,7 @@ class CommandBSBadwords : public Command
if (ci->GetBadWordCount() >= Config->BSBadWordsMax)
{
u->SendMessage(BotServ, BOT_BADWORDS_REACHED_LIMIT, Config->BSBadWordsMax);
source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax);
return MOD_CONT;
}
@@ -159,26 +162,27 @@ class CommandBSBadwords : public Command
if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word))))
{
u->SendMessage(BotServ, BOT_BADWORDS_ALREADY_EXISTS, bw->word.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
return MOD_CONT;
}
}
bool override = !check_access(u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << realword;
bool override = !check_access(source.u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "ADD " << realword;
ci->AddBadWord(realword, type);
u->SendMessage(BotServ, BOT_BADWORDS_ADDED, realword.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
return MOD_CONT;
}
CommandReturn DoDelete(User *u, ChannelInfo *ci, const Anope::string &word)
CommandReturn DoDelete(CommandSource &source, const Anope::string &word)
{
ChannelInfo *ci = source.ci;
/* Special case: is it a number/list? Only do search if it isn't. */
if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos)
{
BadwordsDelCallback list(u, ci, this, word);
BadwordsDelCallback list(source, this, word);
list.Process();
}
else
@@ -196,90 +200,118 @@ class CommandBSBadwords : public Command
if (i == end)
{
u->SendMessage(BotServ, BOT_BADWORDS_NOT_FOUND, word.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str());
return MOD_CONT;
}
bool override = !check_access(u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << badword->word;
ci->EraseBadWord(i);
bool override = !check_access(source.u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "DEL " << badword->word;
u->SendMessage(BotServ, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
ci->EraseBadWord(i);
}
return MOD_CONT;
}
CommandReturn DoClear(User *u, ChannelInfo *ci)
CommandReturn DoClear(CommandSource &source)
{
bool override = !check_access(u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
ChannelInfo *ci = source.ci;
bool override = !check_access(source.u, ci, CA_BADWORDS);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR";
ci->ClearBadWords();
u->SendMessage(BotServ, BOT_BADWORDS_CLEAR);
source.Reply(_("Bad words list is now empty."));
return MOD_CONT;
}
public:
CommandBSBadwords() : Command("BADWORDS", 2, 3)
{
this->SetDesc(_("Maintains bad words list"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string cmd = params[1];
Anope::string word = params.size() > 2 ? params[2] : "";
ChannelInfo *ci;
const Anope::string &cmd = params[1];
const Anope::string &word = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR");
if (!need_args && word.empty())
{
this->OnSyntaxError(u, cmd);
this->OnSyntaxError(source, cmd);
return MOD_CONT;
}
ci = cs_findchan(chan);
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->Account()->HasPriv("botserv/administration")))
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (readonly)
{
u->SendMessage(BotServ, BOT_BADWORDS_DISABLED);
source.Reply(_("Sorry, channel bad words list modification is temporarily disabled."));
return MOD_CONT;
}
if (cmd.equals_ci("ADD"))
return this->DoAdd(u, ci, word);
return this->DoAdd(source, word);
else if (cmd.equals_ci("DEL"))
return this->DoDelete(u, ci, word);
return this->DoDelete(source, word);
else if (cmd.equals_ci("LIST"))
return this->DoList(u, ci, word);
return this->DoList(source, word);
else if (cmd.equals_ci("CLEAR"))
return this->DoClear(u, ci);
return this->DoClear(source);
else
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_BADWORDS);
source.Reply(_("Syntax: \002BADWORDS \037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]\002\n"
" \002BADWORDS \037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}\002\n"
" \002BADWORDS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002BADWORDS \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002bad words list\002 for a channel. The bad\n"
"words list determines which words are to be kicked\n"
"when the bad words kicker is enabled. For more information,\n"
"type \002%s%s HELP KICK BADWORDS\002.\n"
" \n"
"The \002BADWORDS ADD\002 command adds the given word to the\n"
"badword list. If SINGLE is specified, a kick will be\n"
"done only if a user says the entire word. If START is \n"
"specified, a kick will be done if a user says a word\n"
"that starts with \037word\037. If END is specified, a kick\n"
"will be done if a user says a word that ends with\n"
"\037word\037. If you don't specify anything, a kick will\n"
"be issued every time \037word\037 is said by a user.\n"
" \n"), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
source.Reply(_("The \002BADWORDS DEL\002 command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
" \n"
"The \002BADWORDS LIST\002 command displays the bad words list. If\n"
"a wildcard mask is given, only those entries matching the\n"
"mask are displayed. If a list of entry numbers is given,\n"
"only those entries are shown; for example:\n"
" \002BADWORDS #channel LIST 2-5,7-9\002\n"
" Lists bad words entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
"The \002BADWORDS CLEAR\002 command clears all entries of the\n"
"bad words list."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_BADWORDS);
SyntaxError(source, "BADWORDS", _("BADWORDS \037channel\037 {ADD|DEL|LIST|CLEAR} [\037word\037 | \037entry-list\037] [SINGLE|START|END]"));
}
};
+93 -80
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,70 +16,70 @@
class CommandBSBot : public Command
{
private:
CommandReturn DoAdd(User *u, const std::vector<Anope::string> &params)
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params[1];
Anope::string user = params[2];
Anope::string host = params[3];
Anope::string real = params[4];
const Anope::string &nick = params[1];
const Anope::string &user = params[2];
const Anope::string &host = params[3];
const Anope::string &real = params[4];
BotInfo *bi;
if (findbot(nick))
{
u->SendMessage(BotServ, BOT_BOT_ALREADY_EXISTS, nick.c_str());
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
}
if (nick.length() > Config->NickLen)
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
if (user.length() > Config->UserLen)
{
u->SendMessage(BotServ, BOT_LONG_IDENT, Config->UserLen);
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
}
if (host.length() > Config->HostLen)
{
u->SendMessage(BotServ, BOT_LONG_HOST, Config->HostLen);
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
/* Check the host is valid re RFC 2812 */
if (!isValidHost(host, 3))
{
u->SendMessage(BotServ, BOT_BAD_HOST);
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
}
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
if (!isalnum(user[i]))
{
u->SendMessage(BotServ, BOT_BAD_IDENT, Config->UserLen);
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
}
@@ -89,73 +89,73 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
u->SendMessage(BotServ, NICK_ALREADY_REGISTERED, nick.c_str());
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
}
if (!(bi = new BotInfo(nick, user, host, real)))
{
// XXX this cant happen?
u->SendMessage(BotServ, BOT_BOT_CREATION_FAILED);
source.Reply(_("Sorry, bot creation failed."));
return MOD_CONT;
}
Log(LOG_ADMIN, u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
Log(LOG_ADMIN, source.u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
u->SendMessage(BotServ, BOT_BOT_ADDED, bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
source.Reply(_("%s!%s@%s (%s) added to the bot list."), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi));
return MOD_CONT;
}
CommandReturn DoChange(User *u, const std::vector<Anope::string> &params)
CommandReturn DoChange(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string oldnick = params[1];
Anope::string nick = params.size() > 2 ? params[2] : "";
Anope::string user = params.size() > 3 ? params[3] : "";
Anope::string host = params.size() > 4 ? params[4] : "";
Anope::string real = params.size() > 5 ? params[5] : "";
const Anope::string &oldnick = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
const Anope::string &user = params.size() > 3 ? params[3] : "";
const Anope::string &host = params.size() > 4 ? params[4] : "";
const Anope::string &real = params.size() > 5 ? params[5] : "";
BotInfo *bi;
if (oldnick.empty() || nick.empty())
{
this->OnSyntaxError(u, "CHANGE");
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
}
if (!(bi = findbot(oldnick)))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
}
if (!oldnick.equals_ci(nick) && nickIsServices(oldnick, false))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
}
if (nick.length() > Config->NickLen)
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
if (!user.empty() && user.length() > Config->UserLen)
{
u->SendMessage(BotServ, BOT_LONG_IDENT, Config->UserLen);
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
return MOD_CONT;
}
if (!host.empty() && host.length() > Config->HostLen)
{
u->SendMessage(BotServ, BOT_LONG_HOST, Config->HostLen);
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
return MOD_CONT;
}
if (!oldnick.equals_ci(nick) && nickIsServices(nick, false))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
return MOD_CONT;
}
@@ -166,34 +166,34 @@ class CommandBSBot : public Command
*/
if (nick.equals_cs(bi->nick) && (!user.empty() ? user.equals_cs(bi->GetIdent()) : 1) && (!host.empty() ? host.equals_cs(bi->host) : 1) && (!real.empty() ? real.equals_cs(bi->realname) : 1))
{
u->SendMessage(BotServ, BOT_BOT_ANY_CHANGES);
source.Reply(_("Old info is equal to the new one."));
return MOD_CONT;
}
/* Check the nick is valid re RFC 2812 */
if (isdigit(nick[0]) || nick[0] == '-')
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
if (!isvalidnick(nick[i]))
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
/* check for hardcored ircd forbidden nicks */
if (!ircdproto->IsNickValid(nick))
{
u->SendMessage(BotServ, BOT_BAD_NICK);
source.Reply(_("Bot Nicks may only contain valid nick characters."));
return MOD_CONT;
}
if (!host.empty() && !isValidHost(host, 3))
{
u->SendMessage(BotServ, BOT_BAD_HOST);
source.Reply(_("Bot Hosts may only contain valid host characters."));
return MOD_CONT;
}
@@ -201,13 +201,13 @@ class CommandBSBot : public Command
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
if (!isalnum(user[i]))
{
u->SendMessage(BotServ, BOT_BAD_IDENT, Config->UserLen);
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
return MOD_CONT;
}
if (!nick.equals_ci(bi->nick) && findbot(nick))
{
u->SendMessage(BotServ, BOT_BOT_ALREADY_EXISTS, nick.c_str());
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
return MOD_CONT;
}
@@ -219,7 +219,7 @@ class CommandBSBot : public Command
*/
if (findnick(nick))
{
u->SendMessage(BotServ, NICK_ALREADY_REGISTERED, nick.c_str());
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
return MOD_CONT;
}
@@ -241,7 +241,7 @@ class CommandBSBot : public Command
{
ircdproto->SendChangeBotNick(bi, nick);
XLine x(bi->nick, "Reserved for services");
ircdproto->SendSQLine(&x);
ircdproto->SendSQLine(NULL, &x);
}
if (!nick.equals_cs(bi->nick))
@@ -258,80 +258,78 @@ class CommandBSBot : public Command
{
ircdproto->SendClientIntroduction(bi, ircd->pseudoclient_mode);
XLine x(bi->nick, "Reserved for services");
ircdproto->SendSQLine(&x);
ircdproto->SendSQLine(NULL, &x);
bi->RejoinAll();
}
u->SendMessage(BotServ, BOT_BOT_CHANGED, oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
Log(LOG_ADMIN, u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)"), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
Log(LOG_ADMIN, source.u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
FOREACH_MOD(I_OnBotChange, OnBotChange(bi));
return MOD_CONT;
}
CommandReturn DoDel(User *u, const std::vector<Anope::string> &params)
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params[1];
const Anope::string &nick = params[1];
BotInfo *bi;
if (nick.empty())
{
this->OnSyntaxError(u, "DEL");
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
}
if (!(bi = findbot(nick)))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
}
if (nickIsServices(nick, false))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
return MOD_CONT;
}
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str());
XLine x(bi->nick);
ircdproto->SendSQLineDel(&x);
Log(LOG_ADMIN, u, this) << "DEL " << bi->nick;
Log(LOG_ADMIN, source.u, this) << "DEL " << bi->nick;
source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str());
delete bi;
u->SendMessage(BotServ, BOT_BOT_DELETED, nick.c_str());
return MOD_CONT;
}
public:
CommandBSBot() : Command("BOT", 1, 6)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Maintains network bot list"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string cmd = params[0];
const Anope::string &cmd = params[0];
User *u = source.u;
if (readonly)
{
u->SendMessage(BotServ, BOT_BOT_READONLY);
source.Reply(_("Sorry, bot modification is temporarily disabled."));
return MOD_CONT;
}
if (cmd.equals_ci("ADD"))
{
// ADD nick user host real - 5
if (!u->Account()->HasCommand("botserv/bot/add"))
if (!u->HasCommand("botserv/bot/add"))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (params.size() < 5)
{
this->OnSyntaxError(u, "ADD");
this->OnSyntaxError(source, "ADD");
return MOD_CONT;
}
@@ -340,63 +338,78 @@ class CommandBSBot : public Command
if (tempparams.size() >= 6)
tempparams[4] = tempparams[4] + " " + tempparams[5];
return this->DoAdd(u, tempparams);
return this->DoAdd(source, tempparams);
}
else if (cmd.equals_ci("CHANGE"))
{
// CHANGE oldn newn user host real - 6
// but only oldn and newn are required
if (!u->Account()->HasCommand("botserv/bot/change"))
if (!u->HasCommand("botserv/bot/change"))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (params.size() < 3)
{
this->OnSyntaxError(u, "CHANGE");
this->OnSyntaxError(source, "CHANGE");
return MOD_CONT;
}
return this->DoChange(u, params);
return this->DoChange(source, params);
}
else if (cmd.equals_ci("DEL"))
{
// DEL nick
if (!u->Account()->HasCommand("botserv/bot/del"))
if (!u->HasCommand("botserv/bot/del"))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (params.size() < 1)
{
this->OnSyntaxError(u, "DEL");
this->OnSyntaxError(source, "DEL");
return MOD_CONT;
}
return this->DoDel(u, params);
return this->DoDel(source, params);
}
else
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_BOT);
source.Reply(_("Syntax: \002BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\002\n"
" \002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
" \002BOT DEL \037nick\037\002\n"
" \n"
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
"channels.\n"
" \n"
"\002BOT ADD\002 adds a bot with the given nickname, username,\n"
"hostname and realname. Since no integrity checks are done \n"
"for these settings, be really careful.\n"
"\002BOT CHANGE\002 allows to change nickname, username, hostname\n"
"or realname of a bot without actually delete it (and all\n"
"the data associated with it).\n"
"\002BOT DEL\002 removes the given bot from the bot list. \n"
" \n"
"\002Note\002: you cannot create a bot that has a nick that is\n"
"currently registered. If an unregistered user is currently\n"
"using the nick, they will be killed."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "BOT", BOT_BOT_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_BOT);
SyntaxError(source, "BOT", _("BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\n"
"\002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
"\002BOT DEL \037nick\037\002"));
}
};
+18 -24
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,65 +18,59 @@ class CommandBSBotList : public Command
public:
CommandBSBotList() : Command("BOTLIST", 0, 0)
{
this->SetDesc(_("Lists available bots"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
unsigned count = 0;
if (BotListByNick.empty())
{
u->SendMessage(BotServ, BOT_BOTLIST_EMPTY);
return MOD_CONT;
}
for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
{
BotInfo *bi = it->second;
if (!bi->HasFlag(BI_PRIVATE))
{
if (!count)
u->SendMessage(BotServ, BOT_BOTLIST_HEADER);
source.Reply(_("Bot list:"));
++count;
u->SendMessage(Config->s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
}
}
if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size())
if (u->HasCommand("botserv/botlist") && count < BotListByNick.size())
{
u->SendMessage(BotServ, BOT_BOTLIST_PRIVATE_HEADER);
source.Reply(_("Bots reserved to IRC operators:"));
for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
{
BotInfo *bi = it->second;
if (bi->HasFlag(BI_PRIVATE))
{
u->SendMessage(Config->s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
++count;
}
}
}
if (!count)
u->SendMessage(BotServ, BOT_BOTLIST_EMPTY);
source.Reply(_("There are no bots available at this time.\n"
"Ask a Services Operator to create one!"));
else
u->SendMessage(BotServ, BOT_BOTLIST_FOOTER, count);
source.Reply(_("%d bots available."), count);
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_BOTLIST);
source.Reply(_("Syntax: \002BOTLIST\002\n"
" \n"
"Lists all available bots on this network."));
return true;
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_BOTLIST);
}
};
class BSBotList : public Module
+21 -8
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -20,22 +20,35 @@ class CommandBSHelp : public Command
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(findbot(Config->s_BotServ), u, params[0]);
mod_help_cmd(BotServ, source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
// Abuse syntax error to display general list help.
u->SendMessage(BotServ, BOT_HELP);
User *u = source.u;
source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n"
"It has been created for users that can't host or\n"
"configure a bot, or for use on networks that don't\n"
"allow user bots. Available commands are listed \n"
"below; to use them, type \002%s%s \037command\037\002. For\n"
"more information on a specific command, type\n"
"\002%s%s HELP \037command\037\002."),
BotServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(),
Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission)))
it->second->OnServHelp(u);
u->SendMessage(BotServ, BOT_HELP_FOOTER, Config->BSMinUsers);
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
source.Reply(_("Bot will join a channel whenever there is at least\n"
"\002%d\002 user(s) on it. Additionally, all %s commands\n"
"can be used if fantasy is enabled by prefixing the command\n"
"name with a %c."), Config->BSMinUsers, Config->s_ChanServ.c_str(), Config->BSFantasyCharacter[0]);
}
};
+92 -73
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -17,7 +17,7 @@
class CommandBSInfo : public Command
{
private:
void send_bot_channels(User *u, BotInfo *bi)
void send_bot_channels(CommandSource &source, BotInfo *bi)
{
Anope::string buf;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
@@ -28,7 +28,7 @@ class CommandBSInfo : public Command
{
if (buf.length() + ci->name.length() > 300)
{
u->SendMessage(Config->s_BotServ, "%s", buf.c_str());
source.Reply("%s", buf.c_str());
buf.clear();
}
buf += " " + ci->name + " ";
@@ -36,185 +36,204 @@ class CommandBSInfo : public Command
}
if (!buf.empty())
u->SendMessage(Config->s_BotServ, "%s", buf.c_str());
source.Reply("%s", buf.c_str());
return;
}
public:
CommandBSInfo() : Command("INFO", 1, 1)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Allows you to see BotServ information about a channel or a bot"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
BotInfo *bi;
ChannelInfo *ci;
Anope::string query = params[0];
const Anope::string &query = params[0];
int need_comma = 0;
bool need_comma = false;
char buf[BUFSIZE], *end;
if ((bi = findbot(query)))
User *u = source.u;
BotInfo *bi = findbot(query);
ChannelInfo *ci;
if (bi)
{
u->SendMessage(BotServ, BOT_INFO_BOT_HEADER, bi->nick.c_str());
u->SendMessage(BotServ, BOT_INFO_BOT_MASK, bi->GetIdent().c_str(), bi->host.c_str());
u->SendMessage(BotServ, BOT_INFO_BOT_REALNAME, bi->realname.c_str());
u->SendMessage(BotServ, BOT_INFO_BOT_CREATED, do_strftime(bi->created).c_str());
u->SendMessage(BotServ, BOT_INFO_BOT_OPTIONS, GetString(u, (bi->HasFlag(BI_PRIVATE) ? NICK_INFO_OPT_PRIVATE : NICK_INFO_OPT_NONE)).c_str());
u->SendMessage(BotServ, BOT_INFO_BOT_USAGE, bi->chancount);
source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
source.Reply(_(" Mask : %s@%s"), bi->GetIdent().c_str(), bi->host.c_str());
source.Reply(_(" Real name : %s"), bi->realname.c_str());
source.Reply(_(" Created : %s"), do_strftime(bi->created).c_str());
source.Reply(_(" Options : %s"), bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None"));
source.Reply(_(" Used on : %d channel(s)"), bi->chancount);
if (u->Account()->HasPriv("botserv/administration"))
this->send_bot_channels(u, bi);
if (u->HasPriv("botserv/administration"))
this->send_bot_channels(source, bi);
}
else if ((ci = cs_findchan(query)))
{
if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration"))
if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration"))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
u->SendMessage(BotServ, CHAN_INFO_HEADER, ci->name.c_str());
source.Reply(_(CHAN_INFO_HEADER), ci->name.c_str());
if (ci->bi)
u->SendMessage(BotServ, BOT_INFO_CHAN_BOT, ci->bi->nick.c_str());
source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str());
else
u->SendMessage(BotServ, BOT_INFO_CHAN_BOT_NONE);
source.Reply(_(" Bot nick : not assigned yet."));
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
if (ci->ttb[TTB_BADWORDS])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_BADWORDS]);
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BADWORDS]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Bad words kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Bad words kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_BOLDS))
{
if (ci->ttb[TTB_BOLDS])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_BOLDS]);
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BOLDS]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Bolds kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Bolds kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_CAPS))
{
if (ci->ttb[TTB_CAPS])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), _(ENABLED), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->capsmin, ci->capspercent);
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), _(ENABLED), ci->capsmin, ci->capspercent);
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Caps kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_COLORS))
{
if (ci->ttb[TTB_COLORS])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_COLORS]);
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_COLORS]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Colors kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Colors kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
if (ci->ttb[TTB_FLOOD])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), _(ENABLED), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->floodlines, ci->floodsecs);
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), _(ENABLED), ci->floodlines, ci->floodsecs);
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Flood kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (ci->ttb[TTB_REPEAT])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_REPEAT], ci->repeattimes);
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), _(ENABLED), ci->ttb[TTB_REPEAT], ci->repeattimes);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->repeattimes);
source.Reply(_(" Repeat kicker : %s (%d times)"), _(ENABLED), ci->repeattimes);
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Repeat kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_REVERSES))
{
if (ci->ttb[TTB_REVERSES])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_REVERSES]);
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_REVERSES]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Reverses kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Reverses kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES))
{
if (ci->ttb[TTB_UNDERLINES])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_UNDERLINES]);
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_UNDERLINES]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Underlines kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Underlines kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_ITALICS))
{
if (ci->ttb[TTB_ITALICS])
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_ITALICS]);
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_ITALICS]);
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS, GetString(u, BOT_INFO_ACTIVE).c_str());
source.Reply(_(" Italics kicker : %s"), _(ENABLED));
}
else
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS, GetString(u, BOT_INFO_INACTIVE).c_str());
source.Reply(_(" Italics kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_KICK_AMSGS))
{
if (ci->ttb[TTB_AMSGS])
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_AMSGS]);
else
source.Reply(_(" AMSG kicker : %s"), _(ENABLED));
}
else
source.Reply(_(" AMSG kicker : %s"), _(DISABLED));
if (ci->botflags.HasFlag(BS_MSG_PRIVMSG))
source.Reply(_(" Fantasy reply : %s"), "PRIVMSG");
else if (ci->botflags.HasFlag(BS_MSG_NOTICE))
source.Reply(_(" Fantasy reply : %s"), "NOTICE");
else if (ci->botflags.HasFlag(BS_MSG_NOTICEOPS))
source.Reply(_(" Fantasy reply : %s"), "NOTICEOPS");
end = buf;
*end = 0;
if (ci->botflags.HasFlag(BS_DONTKICKOPS))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s", GetString(u, BOT_INFO_OPT_DONTKICKOPS).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s", _("Ops protection"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_DONTKICKVOICES))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_DONTKICKVOICES).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Voices protection"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_FANTASY))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_FANTASY).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Fantasy"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_GREET))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_GREET).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Greet"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_NOBOT))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_NOBOT).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("No bot"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_SYMBIOSIS))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_SYMBIOSIS).c_str());
need_comma = 1;
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Symbiosis"));
need_comma = true;
}
u->SendMessage(BotServ, BOT_INFO_CHAN_OPTIONS, *buf ? buf : GetString(u, BOT_INFO_OPT_NONE).c_str());
source.Reply(_(" Options : %s"), *buf ? buf : _("None"));
}
else
u->SendMessage(BotServ, BOT_INFO_NOT_FOUND, query.c_str());
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_INFO);
source.Reply(_("Syntax: \002INFO {\037chan\037 | \037nick\037}\002\n"
" \n"
"Allows you to see %s information about a channel or a bot.\n"
"If the parameter is a channel, then you'll get information\n"
"such as enabled kickers. If the parameter is a nick,\n"
"you'll get information about a bot, such as creation\n"
"time or number of channels it is on."), NickServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "INFO", BOT_INFO_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_INFO);
SyntaxError(source, "INFO", _("INFO {\037chan\037 | \037nick\037}"));
}
};
+329 -127
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,27 +19,29 @@ class CommandBSKick : public Command
public:
CommandBSKick() : Command("KICK", 3, 6)
{
this->SetDesc(_("Configures kickers"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string option = params[1];
Anope::string value = params[2];
Anope::string ttb = params.size() > 3 ? params[3] : "";
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
const Anope::string &value = params[2];
const Anope::string &ttb = params.size() > 3 ? params[3] : "";
ChannelInfo *ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
u->SendMessage(BotServ, BOT_KICK_DISABLED);
source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
else if (chan.empty() || option.empty() || value.empty())
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
else if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
u->SendMessage(BotServ, ACCESS_DENIED);
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
source.Reply(_(ACCESS_DENIED));
else if (!ci->bi)
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
else
{
bool override = !check_access(u, ci, CA_SET);
@@ -51,31 +53,36 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_BADWORDS] = convertTo<int16>(ttb, error, false);
/* Only error if errno returns ERANGE or EINVAL or we are less then 0 - TSL */
if (!error.empty() || ci->ttb[TTB_BADWORDS] < 0)
try
{
ci->ttb[TTB_BADWORDS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_BADWORDS] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
/* leaving the debug behind since we might want to know what these are */
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BADWORDS];
/* reset the value back to 0 - TSL */
ci->ttb[TTB_BADWORDS] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_BADWORDS] = 0;
ci->botflags.SetFlag(BS_KICK_BADWORDS);
if (ci->ttb[TTB_BADWORDS])
u->SendMessage(BotServ, BOT_KICK_BADWORDS_ON_BAN, ci->ttb[TTB_BADWORDS]);
source.Reply(_("Bot will now kick \002bad words\002, and will place a ban after \n"
"%d kicks for the same user. Use the BADWORDS command\n"
"to add or remove a bad word."), ci->ttb[TTB_BADWORDS]);
else
u->SendMessage(BotServ, BOT_KICK_BADWORDS_ON);
source.Reply(_("Bot will now kick \002bad words\002. Use the BADWORDS command\n"
"to add or remove a bad word."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_BADWORDS);
u->SendMessage(BotServ, BOT_KICK_BADWORDS_OFF);
source.Reply(_("Bot won't kick \002bad words\002 anymore."));
}
}
else if (option.equals_ci("BOLDS"))
@@ -84,13 +91,16 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_BOLDS] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_BOLDS] < 0)
try
{
ci->ttb[TTB_BOLDS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_BOLDS] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BOLDS];
ci->ttb[TTB_BOLDS] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
@@ -98,14 +108,14 @@ class CommandBSKick : public Command
ci->ttb[TTB_BOLDS] = 0;
ci->botflags.SetFlag(BS_KICK_BOLDS);
if (ci->ttb[TTB_BOLDS])
u->SendMessage(BotServ, BOT_KICK_BOLDS_ON_BAN, ci->ttb[TTB_BOLDS]);
source.Reply(_("Bot will now kick \002bolds\002, and will place a ban after\n%d kicks to the same user."), ci->ttb[TTB_BOLDS]);
else
u->SendMessage(BotServ, BOT_KICK_BOLDS_ON);
source.Reply(_("Bot will now kick \002bolds\002."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_BOLDS);
u->SendMessage(BotServ, BOT_KICK_BOLDS_OFF);
source.Reply(_("Bot won't kick \002bolds\002 anymore."));
}
}
else if (option.equals_ci("CAPS"))
@@ -117,43 +127,53 @@ class CommandBSKick : public Command
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_CAPS] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_CAPS] < 0)
try
{
ci->ttb[TTB_CAPS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_CAPS] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_CAPS];
ci->ttb[TTB_CAPS] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_CAPS] = 0;
if (min.empty())
ci->capsmin = 10;
else
ci->capsmin = min.is_number_only() ? convertTo<int16>(min) : 10;
ci->capsmin = 10;
try
{
ci->capsmin = convertTo<int16>(min);
}
catch (const ConvertException &) { }
if (ci->capsmin < 1)
ci->capsmin = 10;
if (percent.empty())
ci->capspercent = 25;
else
ci->capspercent = percent.is_number_only() ? convertTo<int16>(percent) : 25;
ci->capspercent = 25;
try
{
ci->capspercent = convertTo<int16>(percent);
}
catch (const ConvertException &) { }
if (ci->capspercent < 1 || ci->capspercent > 100)
ci->capspercent = 25;
ci->botflags.SetFlag(BS_KICK_CAPS);
if (ci->ttb[TTB_CAPS])
u->SendMessage(BotServ, BOT_KICK_CAPS_ON_BAN, ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]);
source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n"
"%d characters and %d%% of the entire message), and will \n"
"place a ban after %d kicks for the same user."), ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]);
else
u->SendMessage(BotServ, BOT_KICK_CAPS_ON, ci->capsmin, ci->capspercent);
source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n"
"%d characters and %d%% of the entire message)."), ci->capsmin, ci->capspercent);
}
else
{
ci->botflags.UnsetFlag(BS_KICK_CAPS);
u->SendMessage(BotServ, BOT_KICK_CAPS_OFF);
source.Reply(_("Bot won't kick \002caps\002 anymore."));
}
}
else if (option.equals_ci("COLORS"))
@@ -162,28 +182,32 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_COLORS] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_COLORS] < 0)
try
{
ci->ttb[TTB_COLORS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_COLORS] < 1)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_COLORS];
ci->ttb[TTB_COLORS] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_COLORS] = 0;
ci->botflags.SetFlag(BS_KICK_COLORS);
if (ci->ttb[TTB_COLORS])
u->SendMessage(BotServ, BOT_KICK_COLORS_ON_BAN, ci->ttb[TTB_COLORS]);
source.Reply(_("Bot will now kick \002colors\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_COLORS]);
else
u->SendMessage(BotServ, BOT_KICK_COLORS_ON);
source.Reply(_("Bot will now kick \002colors\002."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_COLORS);
u->SendMessage(BotServ, BOT_KICK_COLORS_OFF);
source.Reply(_("Bot won't kick \002colors\002 anymore."));
}
}
else if (option.equals_ci("FLOOD"))
@@ -195,43 +219,52 @@ class CommandBSKick : public Command
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_FLOOD] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_FLOOD] < 0)
try
{
ci->ttb[TTB_FLOOD] = convertTo<int16>(ttb);
if (ci->ttb[TTB_FLOOD] < 1)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_FLOOD];
ci->ttb[TTB_FLOOD] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_FLOOD] = 0;
if (lines.empty())
ci->floodlines = 6;
else
ci->floodlines = lines.is_number_only() ? convertTo<int16>(lines) : 6;
ci->floodlines = 6;
try
{
ci->floodlines = convertTo<int16>(lines);
}
catch (const ConvertException &) { }
if (ci->floodlines < 2)
ci->floodlines = 6;
if (secs.empty())
ci->floodsecs = 10;
else
ci->floodsecs = secs.is_number_only() ? convertTo<int16>(secs) : 10;
if (ci->floodsecs < 1 || ci->floodsecs > Config->BSKeepData)
ci->floodsecs = 10;
try
{
ci->floodsecs = convertTo<int16>(secs);
}
catch (const ConvertException &) { }
if (ci->floodsecs < 1)
ci->floodsecs = 10;
if (ci->floodsecs > Config->BSKeepData)
ci->floodsecs = Config->BSKeepData;
ci->botflags.SetFlag(BS_KICK_FLOOD);
if (ci->ttb[TTB_FLOOD])
u->SendMessage(BotServ, BOT_KICK_FLOOD_ON_BAN, ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]);
source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds and\nwill place a ban after %d kicks for the same user."), ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]);
else
u->SendMessage(BotServ, BOT_KICK_FLOOD_ON, ci->floodlines, ci->floodsecs);
source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds)."), ci->floodlines, ci->floodsecs);
}
else
{
ci->botflags.UnsetFlag(BS_KICK_FLOOD);
u->SendMessage(BotServ, BOT_KICK_FLOOD_OFF);
source.Reply(_("Bot won't kick \002flood\002 anymore."));
}
}
else if (option.equals_ci("REPEAT"))
@@ -242,36 +275,44 @@ class CommandBSKick : public Command
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_REPEAT] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_REPEAT] < 0)
try
{
ci->ttb[TTB_REPEAT] = convertTo<int16>(ttb);
if (ci->ttb[TTB_REPEAT] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REPEAT];
ci->ttb[TTB_REPEAT] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_REPEAT] = 0;
if (times.empty())
ci->repeattimes = 3;
else
ci->repeattimes = times.is_number_only() ? convertTo<int16>(times) : 3;
ci->repeattimes = 3;
try
{
ci->repeattimes = convertTo<int16>(times);
}
catch (const ConvertException &) { }
if (ci->repeattimes < 2)
ci->repeattimes = 3;
ci->botflags.SetFlag(BS_KICK_REPEAT);
if (ci->ttb[TTB_REPEAT])
u->SendMessage(BotServ, BOT_KICK_REPEAT_ON_BAN, ci->repeattimes, ci->ttb[TTB_REPEAT]);
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
"the same thing), and will place a ban after %d \n"
"kicks for the same user."), ci->repeattimes, ci->ttb[TTB_REPEAT]);
else
u->SendMessage(BotServ, BOT_KICK_REPEAT_ON, ci->repeattimes);
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
"the same thing)."), ci->repeattimes);
}
else
{
ci->botflags.UnsetFlag(BS_KICK_REPEAT);
u->SendMessage(BotServ, BOT_KICK_REPEAT_OFF);
source.Reply(_("Bot won't kick \002repeats\002 anymore."));
}
}
else if (option.equals_ci("REVERSES"))
@@ -280,13 +321,16 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_REVERSES] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_REVERSES] < 0)
try
{
ci->ttb[TTB_REVERSES] = convertTo<int16>(ttb);
if (ci->ttb[TTB_REVERSES] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REVERSES];
ci->ttb[TTB_REVERSES] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
@@ -294,14 +338,14 @@ class CommandBSKick : public Command
ci->ttb[TTB_REVERSES] = 0;
ci->botflags.SetFlag(BS_KICK_REVERSES);
if (ci->ttb[TTB_REVERSES])
u->SendMessage(BotServ, BOT_KICK_REVERSES_ON_BAN, ci->ttb[TTB_REVERSES]);
source.Reply(_("Bot will now kick \002reverses\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_REVERSES]);
else
u->SendMessage(BotServ, BOT_KICK_REVERSES_ON);
source.Reply(_("Bot will now kick \002reverses\002."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_REVERSES);
u->SendMessage(BotServ, BOT_KICK_REVERSES_OFF);
source.Reply(_("Bot won't kick \002reverses\002 anymore."));
}
}
else if (option.equals_ci("UNDERLINES"))
@@ -310,28 +354,32 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_UNDERLINES] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_UNDERLINES] < 0)
try
{
ci->ttb[TTB_UNDERLINES] = convertTo<int16>(ttb);
if (ci->ttb[TTB_REVERSES] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_UNDERLINES];
ci->ttb[TTB_UNDERLINES] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_UNDERLINES] = 0;
ci->botflags.SetFlag(BS_KICK_UNDERLINES);
if (ci->ttb[TTB_UNDERLINES])
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_ON_BAN, ci->ttb[TTB_UNDERLINES]);
source.Reply(_("Bot will now kick \002underlines\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_UNDERLINES]);
else
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_ON);
source.Reply(_("Bot will now kick \002underlines\002."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_UNDERLINES);
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_OFF);
source.Reply(_("Bot won't kick \002underlines\002 anymore."));
}
}
else if (option.equals_ci("ITALICS"))
@@ -340,72 +388,192 @@ class CommandBSKick : public Command
{
if (!ttb.empty())
{
Anope::string error;
ci->ttb[TTB_ITALICS] = convertTo<int16>(ttb, error, false);
if (!error.empty() || ci->ttb[TTB_ITALICS] < 0)
try
{
ci->ttb[TTB_ITALICS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_ITALICS] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_ITALICS];
ci->ttb[TTB_ITALICS] = 0;
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_ITALICS] = 0;
ci->botflags.SetFlag(BS_KICK_ITALICS);
if (ci->ttb[TTB_ITALICS])
u->SendMessage(BotServ, BOT_KICK_ITALICS_ON_BAN, ci->ttb[TTB_ITALICS]);
source.Reply(_("Bot will now kick \002italics\002, and will place a ban after\n%d kicks for the same user."), ci->ttb[TTB_ITALICS]);
else
u->SendMessage(BotServ, BOT_KICK_ITALICS_ON);
source.Reply(_("Bot will now kick \002italics\002."));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_ITALICS);
u->SendMessage(BotServ, BOT_KICK_ITALICS_OFF);
source.Reply(_("Bot won't kick \002italics\002 anymore."));
}
}
else if (option.equals_ci("AMSGS"))
{
if (value.equals_ci("ON"))
{
if (!ttb.empty())
{
try
{
ci->ttb[TTB_AMSGS] = convertTo<int16>(ttb);
if (ci->ttb[TTB_AMSGS] < 0)
throw ConvertException();
}
catch (const ConvertException &)
{
ci->ttb[TTB_AMSGS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return MOD_CONT;
}
}
else
ci->ttb[TTB_AMSGS] = 0;
ci->botflags.SetFlag(BS_KICK_AMSGS);
if (ci->ttb[TTB_AMSGS])
source.Reply(_("Bot will now kick for \002amsgs\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_AMSGS]);
else
source.Reply(_("Bot will now kick for \002amsgs\002"));
}
else
{
ci->botflags.UnsetFlag(BS_KICK_AMSGS);
source.Reply(_("Bot won't kick for \002amsgs\002 anymore."));
}
}
else
u->SendMessage(BotServ, BOT_KICK_UNKNOWN, option.c_str());
source.Reply(_(UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
u->SendMessage(BotServ, BOT_HELP_KICK);
source.Reply(_("Syntax: \002KICK \037channel\037 \037option\037 \037parameters\037\002\n"
" \n"
"Configures bot kickers. \037option\037 can be one of:\n"
" \n"
" AMSGS Sets if the bot kicks for amsgs\n"
" BOLDS Sets if the bot kicks bolds\n"
" BADWORDS Sets if the bot kicks bad words\n"
" CAPS Sets if the bot kicks caps\n"
" COLORS Sets if the bot kicks colors\n"
" FLOOD Sets if the bot kicks flooding users\n"
" REPEAT Sets if the bot kicks users who repeat\n"
" themselves\n"
" REVERSES Sets if the bot kicks reverses\n"
" UNDERLINES Sets if the bot kicks underlines\n"
" ITALICS Sets if the bot kicks italics\n"
" \n"
"Type \002%s%s HELP KICK \037option\037\002 for more information\n"
"on a specific option.\n"
" \n"
"Note: access to this command is controlled by the\n"
"level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
else if (subcommand.equals_ci("BADWORDS"))
u->SendMessage(BotServ, BOT_HELP_KICK_BADWORDS);
source.Reply(_("Syntax: \002KICK \037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bad words kicker on or off. When enabled, this\n"
"option tells the bot to kick users who say certain words\n"
"on the channels.\n"
"You can define bad words for your channel using the\n"
"\002BADWORDS\002 command. Type \002%s%s HELP BADWORDS\002 for\n"
"more information.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
else if (subcommand.equals_ci("BOLDS"))
u->SendMessage(BotServ, BOT_HELP_KICK_BOLDS);
source.Reply(_("Syntax: \002KICK \037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bolds kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use bolds.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("CAPS"))
u->SendMessage(BotServ, BOT_HELP_KICK_CAPS);
source.Reply(_("Syntax: \002KICK \037channel\037 CAPS {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002\n"
"Sets the caps kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are talking in\n"
"CAPS.\n"
"The bot kicks only if there are at least \002min\002 caps\n"
"and they constitute at least \002percent\002%% of the total \n"
"text line (if not given, it defaults to 10 characters\n"
"and 25%%).\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("COLORS"))
u->SendMessage(BotServ, BOT_HELP_KICK_COLORS);
source.Reply(_("Syntax: \002KICK \037channel\037 COLORS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the colors kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use colors.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("FLOOD"))
u->SendMessage(BotServ, BOT_HELP_KICK_FLOOD);
source.Reply(_("Syntax: \002KICK \037channel\037 FLOOD {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002\n"
"Sets the flood kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are flooding\n"
"the channel using at least \002ln\002 lines in \002secs\002 seconds\n"
"(if not given, it defaults to 6 lines in 10 seconds).\n"
" \n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REPEAT"))
u->SendMessage(BotServ, BOT_HELP_KICK_REPEAT);
source.Reply(_("Syntax: \002KICK \037#channel\037 REPEAT {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002\n"
"Sets the repeat kicker on or off. When enabled, this\n"
"option tells the bot to kick users who are repeating\n"
"themselves \002num\002 times (if num is not given, it\n"
"defaults to 3).\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("REVERSES"))
u->SendMessage(BotServ, BOT_HELP_KICK_REVERSES);
source.Reply(_("Syntax: \002KICK \037channel\037 REVERSES {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the reverses kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use reverses.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("UNDERLINES"))
u->SendMessage(BotServ, BOT_HELP_KICK_UNDERLINES);
source.Reply(_("Syntax: \002KICK \037channel\037 UNDERLINES {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the underlines kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use underlines.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("ITALICS"))
u->SendMessage(BotServ, BOT_HELP_KICK_ITALICS);
source.Reply(_("Syntax: \002KICK \037channel\037 ITALICS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the italics kicker on or off. When enabled, this\n"
"option tells the bot to kick users who use italics.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else if (subcommand.equals_ci("AMSGS"))
source.Reply(_("Syntax: \002KICK \037channel\037 AMSGS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the amsg kicker on or off. When enabled, the bot will\n"
"kick users who send the same message to multiple channels\n"
"where BotServ bots are.\n"
"Ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
"the ban system once activated."));
else
return false;
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_KICK);
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
}
};
@@ -420,6 +588,40 @@ class BSKick : public Module
this->SetType(CORE);
this->AddCommand(BotServ, &commandbskick);
ModuleManager::Attach(I_OnPrivmsg, this);
}
EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow)
{
Anope::string m, ch;
time_t time;
if (u->GetExtRegular("bs_kick_lastmsg", m) && u->GetExtRegular("bs_kick_lasttime", time) && u->GetExtRegular("bs_kick_lastchan", ch))
{
if (time == Anope::CurTime && m == msg && ch != ci->name)
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *c = (*it)->chan;
++it;
if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS))
{
check_ban(c->ci, u, TTB_AMSGS);
bot_kick(c->ci, u, _("Don't use AMSGs!"));
}
}
return EVENT_CONTINUE;
}
}
u->Extend("bs_kick_lastmsg", new ExtensibleItemRegular<Anope::string>(msg));
u->Extend("bs_kick_lasttime", new ExtensibleItemRegular<time_t>(Anope::CurTime));
u->Extend("bs_kick_lastchan", new ExtensibleItemRegular<Anope::string>(ci->name));
return EVENT_CONTINUE;
}
};
+16 -20
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,38 +18,37 @@ class CommandBSSay : public Command
public:
CommandBSSay() : Command("SAY", 2, 2)
{
this->SetDesc(_("Makes the bot say the given text on the given channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci;
const Anope::string &text = params[1];
Anope::string chan = params[0];
Anope::string text = params[1];
ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_SAY))
{
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (!ci->bi)
{
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
return MOD_CONT;
}
if (!ci->c || !ci->c->FindUser(ci->bi))
{
u->SendMessage(BotServ, BOT_NOT_ON_CHANNEL, ci->name.c_str());
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
return MOD_CONT;
}
if (text[0] == '\001')
{
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
@@ -62,20 +61,17 @@ class CommandBSSay : public Command
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_SAY);
source.Reply(_("Syntax: \002SAY \037channel\037 \037text\037\002\n"
" \n"
"Makes the bot say the given text on the given channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "SAY", BOT_SAY_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_SAY);
SyntaxError(source, "SAY", _("SAY \037channel\037 \037text\037"));
}
};
+150 -56
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,49 +19,48 @@ class CommandBSSet : public Command
CommandBSSet() : Command("SET", 3, 3)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Configures bot options"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string option = params[1];
Anope::string value = params[2];
const Anope::string &chan = params[0];
const Anope::string &option = params[1];
const Anope::string &value = params[2];
User *u = source.u;
ChannelInfo *ci;
if (readonly)
{
u->SendMessage(BotServ, BOT_SET_DISABLED);
return MOD_CONT;
}
if (u->Account()->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE"))
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
else if (u->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE"))
{
BotInfo *bi;
if (!(bi = findbot(chan)))
{
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, chan.c_str());
source.Reply(_(BOT_DOES_NOT_EXIST), chan.c_str());
return MOD_CONT;
}
if (value.equals_ci("ON"))
{
bi->SetFlag(BI_PRIVATE);
u->SendMessage(BotServ, BOT_SET_PRIVATE_ON, bi->nick.c_str());
source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str());
}
else if (value.equals_ci("OFF"))
{
bi->UnsetFlag(BI_PRIVATE);
u->SendMessage(BotServ, BOT_SET_PRIVATE_OFF, bi->nick.c_str());
source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
}
else
SyntaxError(BotServ, u, "SET PRIVATE", BOT_SET_PRIVATE_SYNTAX);
SyntaxError(source, "SET PRIVATE", _("SET \037botname\037 PRIVATE {\037ON|\037}"));
return MOD_CONT;
}
else if (!(ci = cs_findchan(chan)))
u->SendMessage(BotServ, CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET))
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET))
source.Reply(_(ACCESS_DENIED));
else
{
bool override = !check_access(u, ci, CA_SET);
@@ -72,135 +71,230 @@ class CommandBSSet : public Command
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_DONTKICKOPS);
u->SendMessage(BotServ, BOT_SET_DONTKICKOPS_ON, ci->name.c_str());
source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_DONTKICKOPS);
u->SendMessage(BotServ, BOT_SET_DONTKICKOPS_OFF, ci->name.c_str());
source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET DONTKICKOPS", BOT_SET_DONTKICKOPS_SYNTAX);
SyntaxError(source, "SET DONTKICKOPS", _("SET \037channel\037 DONTKICKOPS {\037ON|\037}"));
}
else if (option.equals_ci("DONTKICKVOICES"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_DONTKICKVOICES);
u->SendMessage(BotServ, BOT_SET_DONTKICKVOICES_ON, ci->name.c_str());
source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_DONTKICKVOICES);
u->SendMessage(BotServ, BOT_SET_DONTKICKVOICES_OFF, ci->name.c_str());
source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET DONTKICKVOICES", BOT_SET_DONTKICKVOICES_SYNTAX);
SyntaxError(source, "SET DONTKICKVOICES", _("SET \037channel\037 DONTKICKVOICES {\037ON|\037}"));
}
else if (option.equals_ci("FANTASY"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_FANTASY);
u->SendMessage(BotServ, BOT_SET_FANTASY_ON, ci->name.c_str());
source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_FANTASY);
u->SendMessage(BotServ, BOT_SET_FANTASY_OFF, ci->name.c_str());
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET FANTASY", BOT_SET_FANTASY_SYNTAX);
SyntaxError(source, "SET FANTASY", _("SET \037channel\037 FANTASY {\037ON|\037}"));
}
else if (option.equals_ci("GREET"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_GREET);
u->SendMessage(BotServ, BOT_SET_GREET_ON, ci->name.c_str());
source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_GREET);
u->SendMessage(BotServ, BOT_SET_GREET_OFF, ci->name.c_str());
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET GREET", BOT_SET_GREET_SYNTAX);
SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}"));
}
else if (u->Account()->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_NOBOT);
if (ci->bi)
ci->bi->UnAssign(u, ci);
u->SendMessage(BotServ, BOT_SET_NOBOT_ON, ci->name.c_str());
source.Reply(_("No Bot mode is now \002on\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_NOBOT);
u->SendMessage(BotServ, BOT_SET_NOBOT_OFF, ci->name.c_str());
source.Reply(_("No Bot mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET NOBOT", BOT_SET_NOBOT_SYNTAX);
SyntaxError(source, "SET NOBOT", _("SET \037botname\037 NOBOT {\037ON|\037}"));
}
else if (option.equals_ci("SYMBIOSIS"))
{
if (value.equals_ci("ON"))
{
ci->botflags.SetFlag(BS_SYMBIOSIS);
u->SendMessage(BotServ, BOT_SET_SYMBIOSIS_ON, ci->name.c_str());
source.Reply(_("Symbiosis mode is now \002on\002 on channel %s."), ci->name.c_str());
}
else if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_SYMBIOSIS);
u->SendMessage(BotServ, BOT_SET_SYMBIOSIS_OFF, ci->name.c_str());
source.Reply(_("Symbiosis mode is now \002off\002 on channel %s."), ci->name.c_str());
}
else
SyntaxError(BotServ, u, "SET SYMBIOSIS", BOT_SET_SYMBIOSIS_SYNTAX);
SyntaxError(source, "SET SYMBIOSIS", _("SET \037channel\037 SYMBIOSIS {\037ON|\037}"));
}
else if (option.equals_ci("MSG"))
{
if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will no longer be sent to %s."), ci->name.c_str());
}
else if (value.equals_ci("PRIVMSG"))
{
ci->botflags.SetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via PRIVMSG to %s."), ci->name.c_str());
}
else if (value.equals_ci("NOTICE"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.SetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via NOTICE to %s."), ci->name.c_str());
}
else if (value.equals_ci("NOTICEOPS"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.SetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via NOTICE to channel ops on %s."), ci->name.c_str());
}
else
SyntaxError(source, "SET MSG", _("SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|\037}"));
}
else
u->SendMessage(BotServ, BOT_SET_UNKNOWN, option.c_str());
source.Reply(_(UNKNOWN_OPTION), option.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(), this->name.c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
{
u->SendMessage(BotServ, BOT_HELP_SET);
if (u->Account() && u->Account()->IsServicesOper())
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET);
source.Reply(_("Syntax: \002SET \037(channel | bot)\037 \037option\037 \037parameters\037\002\n"
" \n"
"Configures bot options. \037option\037 can be one of:\n"
" \n"
" DONTKICKOPS To protect ops against bot kicks\n"
" DONTKICKVOICES To protect voices against bot kicks\n"
" GREET Enable greet messages\n"
" FANTASY Enable fantaisist commands\n"
" SYMBIOSIS Allow the bot to act as a real bot\n"
" MSG Configure how fantasy commands should be replied to\n"
" \n"
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
"on a specific option.\n"
"Note: access to this command is controlled by the\n"
"level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
User *u = source.u;
if (u->IsServicesOper())
source.Reply(_("These options are reserved to Services Operators:\n"
" \n"
" NOBOT Prevent a bot from being assigned to \n"
" a channel\n"
" PRIVATE Prevent a bot from being assigned by\n"
" non IRC operators"));
}
else if (subcommand.equals_ci("DONTKICKOPS"))
u->SendMessage(BotServ, BOT_HELP_SET_DONTKICKOPS);
source.Reply(_("Syntax: \002SET \037channel\037 DONTKICKOPS {\037ON|OFF\037}\n"
" \n"
"Enables or disables \002ops protection\002 mode on a channel.\n"
"When it is enabled, ops won't be kicked by the bot\n"
"even if they don't match the NOKICK level."));
else if (subcommand.equals_ci("DONTKICKVOICES"))
u->SendMessage(BotServ, BOT_HELP_SET_DONTKICKVOICES);
source.Reply(_("Syntax: \002SET \037channel\037 DONTKICKVOICES {\037ON|OFF\037}\n"
" \n"
"Enables or disables \002voices protection\002 mode on a channel.\n"
"When it is enabled, voices won't be kicked by the bot\n"
"even if they don't match the NOKICK level."));
else if (subcommand.equals_ci("FANTASY"))
u->SendMessage(BotServ, BOT_HELP_SET_FANTASY);
source.Reply(_("Syntax: \002SET \037channel\037 FANTASY {\037ON|OFF\037}\n"
"Enables or disables \002fantasy\002 mode on a channel.\n"
"When it is enabled, users will be able to use\n"
"commands !op, !deop, !voice, !devoice,\n"
"!kick, !kb, !unban, !seen on a channel (find how \n"
"to use them; try with or without nick for each, \n"
"and with a reason for some?).\n"
" \n"
"Note that users wanting to use fantaisist\n"
"commands MUST have enough level for both\n"
"the FANTASIA and another level depending\n"
"of the command if required (for example, to use \n"
"!op, user must have enough access for the OPDEOP\n"
"level)."));
else if (subcommand.equals_ci("GREET"))
u->SendMessage(BotServ, BOT_HELP_SET_GREET);
source.Reply(_("Syntax: \002SET \037channel\037 GREET {\037ON|OFF\037}\n"
" \n"
"Enables or disables \002greet\002 mode on a channel.\n"
"When it is enabled, the bot will display greet\n"
"messages of users joining the channel, provided\n"
"they have enough access to the channel."));
else if (subcommand.equals_ci("SYMBIOSIS"))
u->SendMessage(BotServ, BOT_HELP_SET_SYMBIOSIS, Config->s_ChanServ.c_str());
source.Reply(_("Syntax: \002SET \037channel\037 SYMBIOSIS {\037ON|OFF\037}\n"
" \n"
"Enables or disables \002symbiosis\002 mode on a channel.\n"
"When it is enabled, the bot will do everything\n"
"normally done by %s on channels, such as MODEs,\n"
"KICKs, and even the entry message."), Config->s_ChanServ.c_str());
else if (subcommand.equals_ci("NOBOT"))
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET_NOBOT);
source.Reply(_("Syntax: \002SET \037channel\037 NOBOT {\037ON|OFF\037}\002\n"
" \n"
"This option makes a channel be unassignable. If a bot \n"
"is already assigned to the channel, it is unassigned\n"
"automatically when you enable the option."));
else if (subcommand.equals_ci("PRIVATE"))
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET_PRIVATE);
source.Reply(_("Syntax: \002SET \037bot-nick\037 PRIVATE {\037ON|OFF\037}\002\n"
"This option prevents a bot from being assigned to a\n"
"channel by users that aren't IRC operators."));
else if (subcommand.equals_ci("MSG"))
source.Reply(_("Syntax: \002SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|NOTICEOPS\037}\002\n"
" \n"
"Configures how fantasy commands should be returned to the channel. Off disables\n"
"fantasy from replying to the channel. Privmsg, notice, and noticeops message the\n"
"channel, notice the channel, and notice the channel ops respectively.\n"
" \n"
"Note that replies over one line will not use this setting to prevent spam, and will\n"
"go directly to the user who executed it."));
else
return false;
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "SET", BOT_SET_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_SET);
SyntaxError(source, "SET", _("SET \037(channel | bot)\037 \037option\037 \037settings\037"));
}
};
+22 -19
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,47 +18,50 @@ class CommandBSUnassign : public Command
public:
CommandBSUnassign() : Command("UNASSIGN", 1, 1)
{
this->SetDesc(_("Unassigns a bot from a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
ChannelInfo *ci = cs_findchan(chan);
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
u->SendMessage(BotServ, BOT_ASSIGN_READONLY);
else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
u->SendMessage(BotServ, ACCESS_DENIED);
source.Reply(_(BOT_ASSIGN_READONLY));
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
source.Reply(_(ACCESS_DENIED));
else if (!ci->bi)
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
else if (ci->HasFlag(CI_PERSIST) && !cm)
u->SendMessage(BotServ, BOT_UNASSIGN_PERSISTANT_CHAN);
source.Reply(_("You can not unassign bots while persist is set on the channel."));
else
{
bool override = !check_access(u, ci, CA_ASSIGN);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick;
ci->bi->UnAssign(u, ci);
u->SendMessage(BotServ, BOT_UNASSIGN_UNASSIGNED, ci->name.c_str());
source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(BotServ, BOT_HELP_UNASSIGN);
source.Reply(_("Syntax: \002UNASSIGN \037chan\037\002\n"
" \n"
"Unassigns a bot from a channel. When you use this command,\n"
"the bot won't join the channel anymore. However, bot\n"
"configuration for the channel is kept, so you will always\n"
"be able to reassign a bot later without have to reconfigure\n"
"it entirely."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(BotServ, u, "UNASSIGN", BOT_UNASSIGN_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(BotServ, BOT_HELP_CMD_UNASSIGN);
SyntaxError(source, "UNASSIGN", _("UNASSIGN \037chan\037"));
}
};
+320 -203
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,71 +16,71 @@
class AccessListCallback : public NumberList
{
protected:
User *u;
ChannelInfo *ci;
CommandSource &source;
bool SentHeader;
public:
AccessListCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
AccessListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
{
}
~AccessListCallback()
{
if (SentHeader)
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
source.Reply(_("End of access list."), source.ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
if (!Number || Number > source.ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
}
DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
}
static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
{
if (ci->HasFlag(CI_XOP))
if (source.ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str());
source.Reply(_(" %3d %s %s"), Number + 1, xop.c_str(), access->GetMask().c_str());
}
else
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str());
source.Reply(_(" %3d %4d %s"), Number + 1, access->level, access->GetMask().c_str());
}
};
class AccessViewCallback : public AccessListCallback
{
public:
AccessViewCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_u, _ci, numlist)
AccessViewCallback(CommandSource &_source, const Anope::string &numlist) : AccessListCallback(_source, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
if (!Number || Number > source.ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
}
DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
}
static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
{
ChannelInfo *ci = source.ci;
Anope::string timebuf;
if (ci->c && nc_on_chan(ci->c, access->nc))
timebuf = "Now";
@@ -92,54 +92,58 @@ class AccessViewCallback : public AccessListCallback
if (ci->HasFlag(CI_XOP))
{
Anope::string xop = get_xop_level(access->level);
u->SendMessage(ChanServ, CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
source.Reply(_(CHAN_ACCESS_VIEW_XOP_FORMAT), Number + 1, xop.c_str(), access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
}
else
u->SendMessage(ChanServ, CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
source.Reply(_(CHAN_ACCESS_VIEW_AXS_FORMAT), Number + 1, access->level, access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
}
};
class AccessDelCallback : public NumberList
{
User *u;
ChannelInfo *ci;
CommandSource &source;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool Denied;
bool override;
public:
AccessDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), c(_c), Deleted(0), Denied(false)
AccessDelCallback(CommandSource &_source, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), Denied(false)
{
if (!check_access(u, ci, CA_ACCESS_CHANGE) && u->Account()->HasPriv("chanserv/access/modify"))
if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
this->override = true;
}
~AccessDelCallback()
{
if (Denied && !Deleted)
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
else if (!Deleted)
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
if (Deleted == 1)
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s access list."), source.ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED_SEVERAL, Deleted, ci->name.c_str());
source.Reply(_("Deleted %d entries from %s access list."), Deleted, source.ci->name.c_str());
}
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
if (!Number || Number > source.ci->GetAccessCount())
return;
User *u = source.u;
ChannelInfo *ci = source.ci;
ChanAccess *access = ci->GetAccess(Number - 1);
if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
ChanAccess *u_access = ci->GetAccess(u);
int16 u_level = u_access ? u_access->level : 0;
if (u_level <= access->level && !u->HasPriv("chanserv/access/modify"))
{
Denied = true;
return;
@@ -147,11 +151,11 @@ class AccessDelCallback : public NumberList
++Deleted;
if (!Nicks.empty())
Nicks += ", " + access->nc->display;
Nicks += ", " + access->GetMask();
else
Nicks = access->nc->display;
Nicks = access->GetMask();
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(Number - 1);
}
@@ -159,143 +163,138 @@ class AccessDelCallback : public NumberList
class CommandCSAccess : public Command
{
CommandReturn DoAdd(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params[2];
int level = params[3].is_number_only() ? convertTo<int>(params[3]) : ACCESS_INVALID;
int ulev = get_access(u, ci);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
Anope::string mask = params[2];
int level = ACCESS_INVALID;
try
{
u->SendMessage(ChanServ, ACCESS_DENIED);
level = convertTo<int>(params[3]);
}
catch (const ConvertException &) { }
ChanAccess *u_access = ci->GetAccess(u);
int16 u_level = u_access ? u_access->level : 0;
if (level >= u_level && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (!level)
{
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_NONZERO);
source.Reply(_("Access level must be non-zero."));
return MOD_CONT;
}
else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
{
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
source.Reply(_(CHAN_ACCESS_LEVEL_RANGE), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
return MOD_CONT;
}
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= ulev;
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= u_level;
NickAlias *na = findnick(nick);
if (!na)
NickAlias *na = findnick(mask);
if (!na && mask.find_first_of("!@*") == Anope::string::npos)
mask += "!*@*";
else if (na && na->HasFlag(NS_FORBIDDEN))
{
u->SendMessage(ChanServ, CHAN_ACCESS_NICKS_ONLY);
return MOD_CONT;
}
else if (na->HasFlag(NS_FORBIDDEN))
{
u->SendMessage(ChanServ, NICK_X_FORBIDDEN, nick.c_str());
source.Reply(_(NICK_X_FORBIDDEN), mask.c_str());
return MOD_CONT;
}
NickCore *nc = na->nc;
ChanAccess *access = ci->GetAccess(nc);
ChanAccess *access = ci->GetAccess(mask, 0, false);
if (access)
{
/* Don't allow lowering from a level >= ulev */
if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
/* Don't allow lowering from a level >= u_level */
if (access->level >= u_level && !u->HasPriv("chanserv/access/modify"))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (access->level == level)
{
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display.c_str(), ci->name.c_str(), level);
source.Reply(_("Access level for \002%s\002 on %s unchanged from \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
access->level = level;
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_CHANGED, nc->display.c_str(), ci->name.c_str(), level);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
source.Reply(_("Access level for \002%s\002 on %s changed to \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
if (ci->GetAccessCount() >= Config->CSAccessMax)
{
u->SendMessage(ChanServ, CHAN_ACCESS_REACHED_LIMIT, Config->CSAccessMax);
source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
return MOD_CONT;
}
ci->AddAccess(nc, level, u->nick);
access = ci->AddAccess(mask, level, u->nick);
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
u->SendMessage(ChanServ, CHAN_ACCESS_ADDED, nc->display.c_str(), ci->name.c_str(), level);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
CommandReturn DoDel(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params[2];
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params[2];
if (!ci->GetAccessCount())
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
else if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessDelCallback list(u, ci, this, nick);
AccessDelCallback list(source, this, mask);
list.Process();
}
else
{
NickAlias *na = findnick(nick);
if (!na)
{
u->SendMessage(ChanServ, NICK_X_NOT_REGISTERED, nick.c_str());
return MOD_CONT;
}
NickCore *nc = na->nc;
unsigned i, end;
ChanAccess *access = NULL;
for (i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
access = ci->GetAccess(i);
if (access->nc == nc)
break;
}
if (i == end)
u->SendMessage(ChanServ, CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str());
else if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
u->SendMessage(ChanServ, ACCESS_DENIED);
ChanAccess *access = ci->GetAccess(mask, 0, false);
ChanAccess *u_access = ci->GetAccess(u);
int16 u_level = u_access ? u_access->level : 0;
if (!access)
source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else
{
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str());
bool override = !check_access(u, ci, CA_ACCESS_CHANGE);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << " (group: " << access->nc->display << ") from level " << access->level;
source.Reply(_("\002%s\002 deleted from %s access list."), access->GetMask().c_str(), ci->name.c_str());
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && access->nc != u->Account();
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->GetMask() << " from level " << access->level;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(i);
ci->EraseAccess(access);
}
}
return MOD_CONT;
}
CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoList(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params.size() > 2 ? params[2] : "";
ChannelInfo *ci = source.ci;
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessListCallback list(u, ci, nick);
AccessListCallback list(source, nick);
list.Process();
}
else
@@ -306,36 +305,38 @@ class CommandCSAccess : public Command
{
ChanAccess *access = ci->GetAccess(i);
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
continue;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
}
AccessListCallback::DoList(u, ci, i, access);
AccessListCallback::DoList(source, i, access);
}
if (SentHeader)
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
source.Reply(_("End of access list."), ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return MOD_CONT;
}
CommandReturn DoView(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoView(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string nick = params.size() > 2 ? params[2] : "";
ChannelInfo *ci = source.ci;
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessViewCallback list(u, ci, nick);
AccessViewCallback list(source, nick);
list.Process();
}
else
@@ -346,38 +347,41 @@ class CommandCSAccess : public Command
{
ChanAccess *access = ci->GetAccess(i);
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
continue;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
}
AccessViewCallback::DoList(u, ci, i, access);
AccessViewCallback::DoList(source, i, access);
}
if (SentHeader)
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
source.Reply(_("End of access list."), ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
return MOD_CONT;
}
CommandReturn DoClear(User *u, ChannelInfo *ci)
CommandReturn DoClear(CommandSource &source)
{
if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
u->SendMessage(ChanServ, ACCESS_DENIED);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else
{
ci->ClearAccess();
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
u->SendMessage(ChanServ, CHAN_ACCESS_CLEAR, ci->name.c_str());
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
@@ -389,88 +393,176 @@ class CommandCSAccess : public Command
public:
CommandCSAccess() : Command("ACCESS", 2, 4)
{
this->SetDesc(_("Modify the list of privileged users"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string cmd = params[1];
Anope::string nick = params.size() > 2 ? params[2] : "";
Anope::string s = params.size() > 3 ? params[3] : "";
const Anope::string &cmd = params[1];
const Anope::string &nick = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
ChannelInfo *ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
bool is_clear = cmd.equals_ci("CLEAR");
bool is_del = cmd.equals_ci("DEL");
bool has_access = false;
if (is_list && check_access(u, ci, CA_ACCESS_LIST))
has_access = true;
else if (check_access(u, ci, CA_ACCESS_CHANGE))
has_access = true;
else if (is_del)
{
NickAlias *na = findnick(nick);
if (na && na->nc == u->Account())
has_access = true;
}
/* If LIST, we don't *require* any parameters, but we can take any.
* If DEL, we require a nick and no level.
* Else (ADD), we require a level (which implies a nick). */
if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
this->OnSyntaxError(u, cmd);
/* We still allow LIST in xOP mode, but not others */
this->OnSyntaxError(source, cmd);
else if (!has_access)
source.Reply(_(ACCESS_DENIED));
/* We still allow LIST and CLEAR in xOP mode, but not others */
else if (ci->HasFlag(CI_XOP) && !is_list && !is_clear)
{
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
u->SendMessage(ChanServ, CHAN_ACCESS_XOP_HOP, Config->s_ChanServ.c_str());
source.Reply(_("You can't use this command. \n"
"Use the AOP, SOP, HOP and VOP commands instead.\n"
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
else
u->SendMessage(ChanServ, CHAN_ACCESS_XOP, Config->s_ChanServ.c_str());
source.Reply(_("You can't use this command. \n"
"Use the AOP, SOP and VOP commands instead.\n"
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
}
else if ((is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list")) || (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify")))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (readonly && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL") || cmd.equals_ci("CLEAR")))
u->SendMessage(ChanServ, CHAN_ACCESS_DISABLED);
else if (readonly && !is_list)
source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
else if (cmd.equals_ci("ADD"))
this->DoAdd(u, ci, params);
this->DoAdd(source, params);
else if (cmd.equals_ci("DEL"))
this->DoDel(u, ci, params);
this->DoDel(source, params);
else if (cmd.equals_ci("LIST"))
this->DoList(u, ci, params);
this->DoList(source, params);
else if (cmd.equals_ci("VIEW"))
this->DoView(u, ci, params);
this->DoView(source, params);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(u, ci);
this->DoClear(source);
else
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_ACCESS);
u->SendMessage(ChanServ, CHAN_HELP_ACCESS_LEVELS);
source.Reply(_("Syntax: \002ACCESS \037channel\037 ADD \037mask\037 \037level\037\002\n"
" \002ACCESS \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002ACCESS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
" \002ACCESS \037channel\037 VIEW [\037mask\037 | \037list\037]\002\n"
" \002ACCESS \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002access list\002 for a channel. The access\n"
"list specifies which users are allowed chanop status or\n"
"access to %s commands on the channel. Different\n"
"user levels allow for access to different subsets of\n"
"privileges; \002%s%s HELP ACCESS LEVELS\002 for more\n"
"specific information. Any nick not on the access list has\n"
"a user level of 0.\n"
" \n"
"The \002ACCESS ADD\002 command adds the given mask to the\n"
"access list with the given user level; if the mask is\n"
"already present on the list, its access level is changed to\n"
"the level specified in the command. The \037level\037 specified\n"
"must be less than that of the user giving the command, and\n"
"if the \037mask\037 is already on the access list, the current\n"
"access level of that nick must be less than the access level\n"
"of the user giving the command. When a user joins the channel\n"
"the access they receive is from the highest level entry in the\n"
"access list.\n"
" \n"
"The \002ACCESS DEL\002 command removes the given nick from the\n"
"access list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
"You may remove yourself from an access list, even if you\n"
"do not have access to modify that list otherwise.\n"
" \n"
"The \002ACCESS LIST\002 command displays the access list. If\n"
"a wildcard mask is given, only those entries matching the\n"
"mask are displayed. If a list of entry numbers is given,\n"
"only those entries are shown; for example:\n"
" \002ACCESS #channel LIST 2-5,7-9\002\n"
" Lists access entries numbered 2 through 5 and\n"
" 7 through 9.\n"
" \n"
"The \002ACCESS VIEW\002 command displays the access list similar\n"
"to \002ACCESS LIST\002 but shows the creator and last used time.\n"
" \n"
"The \002ACCESS CLEAR\002 command clears all entries of the\n"
"access list."),
ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
source.Reply(_("\002User access levels\002\n"
" \n"
"By default, the following access levels are defined:\n"
" \n"
" \002Founder\002 Full access to %s functions; automatic\n"
" opping upon entering channel. Note\n"
" that only one person may have founder\n"
" status (it cannot be given using the\n"
" \002ACCESS\002 command).\n"
" \002 10\002 Access to AKICK command; automatic opping.\n"
" \002 5\002 Automatic opping.\n"
" \002 3\002 Automatic voicing.\n"
" \002 0\002 No special privileges; can be opped by other\n"
" ops (unless \002secure-ops\002 is set).\n"
" \002 <0\002 May not be opped.\n"
" \n"
"These levels may be changed, or new ones added, using the\n"
"\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n"
"information."), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
SyntaxError(source, "ACCESS", _("ACCESS \037channel\037 {ADD|DEL|LIST|VIEW|CLEAR} [\037mask\037 [\037level\037] | \037entry-list\037]"));
}
};
class CommandCSLevels : public Command
{
CommandReturn DoSet(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoSet(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string what = params[2];
Anope::string lev = params[3];
User *u = source.u;
ChannelInfo *ci = source.ci;
Anope::string error;
int level = (lev.is_number_only() ? convertTo<int>(lev, error, false) : 0);
if (!lev.is_number_only())
error = "1";
const Anope::string &what = params[2];
const Anope::string &lev = params[3];
int level;
if (lev.equals_ci("FOUNDER"))
{
level = ACCESS_FOUNDER;
error.clear();
else
{
level = 1;
try
{
level = convertTo<int>(lev);
}
catch (const ConvertException &)
{
this->OnSyntaxError(source, "SET");
return MOD_CONT;
}
}
if (!error.empty())
this->OnSyntaxError(u, "SET");
else if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
u->SendMessage(ChanServ, CHAN_LEVELS_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
else
{
for (int i = 0; levelinfo[i].what >= 0; ++i)
@@ -484,25 +576,28 @@ class CommandCSLevels : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << levelinfo[i].name << " to " << level;
if (level == ACCESS_FOUNDER)
u->SendMessage(ChanServ, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name.c_str(), ci->name.c_str());
source.Reply(_("Level for %s on channel %s changed to founder only."), levelinfo[i].name.c_str(), ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_LEVELS_CHANGED, levelinfo[i].name.c_str(), ci->name.c_str(), level);
source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), levelinfo[i].name.c_str(), ci->name.c_str(), level);
return MOD_CONT;
}
}
u->SendMessage(ChanServ, CHAN_LEVELS_UNKNOWN, what.c_str(), Config->s_ChanServ.c_str());
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
}
return MOD_CONT;
}
CommandReturn DoDisable(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
CommandReturn DoDisable(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string what = params[2];
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &what = params[2];
/* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
if (what.equals_ci("FOUNDER"))
if (!what.equals_ci("FOUNDER"))
for (int i = 0; levelinfo[i].what >= 0; ++i)
{
if (what.equals_ci(levelinfo[i].name))
@@ -513,19 +608,21 @@ class CommandCSLevels : public Command
bool override = !check_access(u, ci, CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << levelinfo[i].name;
u->SendMessage(ChanServ, CHAN_LEVELS_DISABLED, levelinfo[i].name.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 disabled on channel %s."), levelinfo[i].name.c_str(), ci->name.c_str());
return MOD_CONT;
}
}
u->SendMessage(ChanServ, CHAN_LEVELS_UNKNOWN, what.c_str(), Config->s_ChanServ.c_str());
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return MOD_CONT;
}
CommandReturn DoList(User *u, ChannelInfo *ci)
CommandReturn DoList(CommandSource &source)
{
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_HEADER, ci->name.c_str());
ChannelInfo *ci = source.ci;
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
if (!levelinfo_maxwidth)
for (int i = 0; levelinfo[i].what >= 0; ++i)
@@ -543,75 +640,78 @@ class CommandCSLevels : public Command
{
j = levelinfo[i].what;
if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE || j == CA_NOJOIN)
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name.c_str());
else
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name.c_str());
source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, levelinfo[i].name.c_str());
}
else if (j == ACCESS_FOUNDER)
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_FOUNDER, levelinfo_maxwidth, levelinfo[i].name.c_str());
source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, levelinfo[i].name.c_str());
else
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_NORMAL, levelinfo_maxwidth, levelinfo[i].name.c_str(), j);
source.Reply(_(" %-*s %d"), levelinfo_maxwidth, levelinfo[i].name.c_str(), j);
}
return MOD_CONT;
}
CommandReturn DoReset(User *u, ChannelInfo *ci)
CommandReturn DoReset(CommandSource &source)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
reset_levels(ci);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
bool override = !check_access(u, ci, CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
u->SendMessage(ChanServ, CHAN_LEVELS_RESET, ci->name.c_str());
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
return MOD_CONT;
}
public:
CommandCSLevels() : Command("LEVELS", 2, 4)
{
this->SetDesc(_("Redefine the meanings of access levels"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string cmd = params[1];
Anope::string what = params.size() > 2 ? params[2] : "";
Anope::string s = params.size() > 3 ? params[3] : "";
const Anope::string &cmd = params[1];
const Anope::string &what = params.size() > 2 ? params[2] : "";
const Anope::string &s = params.size() > 3 ? params[3] : "";
ChannelInfo *ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
/* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
* one; else, we want none.
*/
if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
this->OnSyntaxError(u, cmd);
this->OnSyntaxError(source, cmd);
else if (ci->HasFlag(CI_XOP))
u->SendMessage(ChanServ, CHAN_LEVELS_XOP);
else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_("Levels are not available as xOP is enabled on this channel."));
else if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else if (cmd.equals_ci("SET"))
this->DoSet(u, ci, params);
this->DoSet(source, params);
else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
this->DoDisable(u, ci, params);
this->DoDisable(source, params);
else if (cmd.equals_ci("LIST"))
this->DoList(u, ci);
this->DoList(source);
else if (cmd.equals_ci("RESET"))
this->DoReset(u, ci);
this->DoReset(source);
else
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.equals_ci("DESC"))
{
int i;
u->SendMessage(ChanServ, CHAN_HELP_LEVELS_DESC);
source.Reply(_("The following feature/function names are understood. Note\n"
"that the leves for NOJOIN is the maximum level,\n"
"while all others are minimum levels."));
if (!levelinfo_maxwidth)
for (i = 0; levelinfo[i].what >= 0; ++i)
{
@@ -620,22 +720,39 @@ class CommandCSLevels : public Command
levelinfo_maxwidth = len;
}
for (i = 0; levelinfo[i].what >= 0; ++i)
u->SendMessage(ChanServ, CHAN_HELP_LEVELS_DESC_FORMAT, levelinfo_maxwidth, levelinfo[i].name.c_str(), GetString(u, levelinfo[i].desc).c_str());
source.Reply(_(" %-*s %s"), levelinfo_maxwidth, levelinfo[i].name.c_str(), GetString(source.u->Account(), levelinfo[i].desc).c_str());
}
else
u->SendMessage(ChanServ, CHAN_HELP_LEVELS);
source.Reply(_("Syntax: \002LEVELS \037channel\037 SET \037type\037 \037level\037\002\n"
" \002LEVELS \037channel\037 {DIS | DISABLE} \037type\037\002\n"
" \002LEVELS \037channel\037 LIST\002\n"
" \002LEVELS \037channel\037 RESET\002\n"
" \n"
"The \002LEVELS\002 command allows fine control over the meaning of\n"
"the numeric access levels used for channels. With this\n"
"command, you can define the access level required for most\n"
"of %s's functions. (The \002SET FOUNDER\002 and this command\n"
"are always restricted to the channel founder.)\n"
" \n"
"\002LEVELS SET\002 allows the access level for a function or group of\n"
"functions to be changed. \002LEVELS DISABLE\002 (or \002DIS\002 for short)\n"
"disables an automatic feature or disallows access to a\n"
"function by anyone, INCLUDING the founder (although, the founder\n"
"can always reenable it).\n"
" \n"
"\002LEVELS LIST\002 shows the current levels for each function or\n"
"group of functions. \002LEVELS RESET\002 resets the levels to the\n"
"default levels of a newly-created channel (see\n"
"\002HELP ACCESS LEVELS\002).\n"
" \n"
"For a list of the features and functions whose levels can be\n"
"set, see \002HELP LEVELS DESC\002."), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_ACCESS);
u->SendMessage(ChanServ, CHAN_HELP_CMD_LEVELS);
SyntaxError(source, "LEVELS", _("LEVELS \037channel\037 {SET | DIS[ABLE] | LIST | RESET} [\037item\037 [\037level\037]]"));
}
};
+149 -174
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -54,114 +54,118 @@ static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope
class AkickListCallback : public NumberList
{
protected:
User *u;
ChannelInfo *ci;
CommandSource &source;
bool SentHeader;
public:
AkickListCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
AkickListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
{
}
~AkickListCallback()
{
if (!SentHeader)
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), source.ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
if (!Number || Number > source.ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
}
DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
}
static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() :akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : GetString(u, NO_REASON).c_str());
source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
}
};
class AkickViewCallback : public AkickListCallback
{
public:
AkickViewCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_u, _ci, numlist)
AkickViewCallback(CommandSource &_source, const Anope::string &numlist) : AkickListCallback(_source, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
if (!Number || Number > source.ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
}
DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
}
static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
{
Anope::string timebuf;
if (akick->addtime)
timebuf = do_strftime(akick->addtime);
else
timebuf = GetString(u, UNKNOWN);
timebuf = _(UNKNOWN);
u->SendMessage(ChanServ, akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : GetString(u, UNKNOWN).c_str(), timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : GetString(u, NO_REASON).c_str());
source.Reply(_(CHAN_AKICK_VIEW_FORMAT), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
if (akick->last_used)
u->SendMessage(ChanServ, CHAN_AKICK_LAST_USED, do_strftime(akick->last_used).c_str());
source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str());
}
};
class AkickDelCallback : public NumberList
{
User *u;
ChannelInfo *ci;
CommandSource &source;
Command *c;
unsigned Deleted;
public:
AkickDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0)
AkickDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0)
{
}
~AkickDelCallback()
{
User *u = source.u;
ChannelInfo *ci = source.ci;
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users";
if (!Deleted)
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
else if (Deleted == 1)
u->SendMessage(ChanServ, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
else
u->SendMessage(ChanServ, CHAN_AKICK_DELETED_SEVERAL, Deleted, ci->name.c_str());
source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
if (!Number || Number > source.ci->GetAkickCount())
return;
++Deleted;
ci->EraseAkick(Number - 1);
source.ci->EraseAkick(Number - 1);
}
};
class CommandCSAKick : public Command
{
void DoAdd(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
void DoAdd(CommandSource &source, 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] : "";
NickAlias *na = findnick(mask);
@@ -179,7 +183,7 @@ class CommandCSAKick : public Command
{
if (na->HasFlag(NS_FORBIDDEN))
{
u->SendMessage(ChanServ, NICK_X_FORBIDDEN, mask.c_str());
source.Reply(_(NICK_X_FORBIDDEN), mask.c_str());
return;
}
@@ -189,7 +193,7 @@ class CommandCSAKick : public Command
/* Check excepts BEFORE we get this far */
if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted_mask(ci, mask))
{
u->SendMessage(ChanServ, CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
source.Reply(_(CHAN_EXCEPTED), mask.c_str(), ci->name.c_str());
return;
}
@@ -197,9 +201,11 @@ class CommandCSAKick : public Command
* or whether the mask matches a user with higher/equal access - Viper */
if (ci->HasFlag(CI_PEACE) && nc)
{
if (nc == ci->founder || get_access_level(ci, nc) >= get_access(u, ci))
ChanAccess *nc_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0;
if (nc == ci->founder || nc_level >= u_level)
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return;
}
}
@@ -207,13 +213,17 @@ class CommandCSAKick : public Command
{
/* Match against all currently online users with equal or
* higher access. - Viper */
for (user_map::const_iterator it = UserListByNick.begin(), it_end = UserListByNick.end(); it != it_end; ++it)
for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(), it_end = UserListByNick.end(); it != it_end; ++it)
{
User *u2 = it->second;
if ((check_access(u2, ci, CA_FOUNDER) || get_access(u2, ci) >= get_access(u, ci)) && match_usermask(mask, u2))
ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0;
Entry entry_mask(CMODE_BEGIN, mask);
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && entry_mask.Matches(u2))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return;
}
}
@@ -227,12 +237,14 @@ class CommandCSAKick : public Command
if (na2->HasFlag(NS_FORBIDDEN))
continue;
if (na2->nc && (na2->nc == ci->founder || get_access_level(ci, na2->nc) >= get_access(u, ci)))
ChanAccess *na2_access = ci->GetAccess(na2->nc), *u_access = ci->GetAccess(u);
int16 na2_level = na2_access ? na2_access->level : 0, u_level = u_access ? u_access->level : 0;
if (na2->nc && (na2->nc == ci->founder || na2_level >= u_level))
{
Anope::string buf = na2->nick + "!" + na2->last_usermask;
if (Anope::Match(buf, mask))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return;
}
}
@@ -244,14 +256,14 @@ class CommandCSAKick : public Command
akick = ci->GetAkick(j);
if (akick->HasFlag(AK_ISNICK) ? akick->nc == nc : mask.equals_ci(akick->mask))
{
u->SendMessage(ChanServ, CHAN_AKICK_ALREADY_EXISTS, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
return;
}
}
if (ci->GetAkickCount() >= Config->CSAutokickMax)
{
u->SendMessage(ChanServ, CHAN_AKICK_REACHED_LIMIT, Config->CSAutokickMax);
source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->CSAutokickMax);
return;
}
@@ -265,110 +277,30 @@ class CommandCSAKick : public Command
FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
u->SendMessage(ChanServ, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
this->DoEnforce(u, ci);
this->DoEnforce(source);
}
void DoStick(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
{
NickAlias *na;
NickCore *nc;
Anope::string mask = params[2];
unsigned i, end;
AutoKick *akick;
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
return;
}
na = findnick(mask);
nc = na ? na->nc : NULL;
for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
{
akick = ci->GetAkick(i);
if (akick->HasFlag(AK_ISNICK))
continue;
if (mask.equals_ci(akick->mask))
break;
}
if (i == end)
{
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
return;
}
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "STICK " << akick->mask;
akick->SetFlag(AK_STUCK);
u->SendMessage(ChanServ, CHAN_AKICK_STUCK, akick->mask.c_str(), ci->name.c_str());
if (ci->c)
stick_mask(ci, akick);
}
void DoUnStick(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
NickAlias *na;
NickCore *nc;
AutoKick *akick;
unsigned i, end;
Anope::string mask = params[2];
if (!ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
return;
}
na = findnick(mask);
nc = na ? na->nc : NULL;
for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
{
akick = ci->GetAkick(i);
if (akick->HasFlag(AK_ISNICK))
continue;
if (mask.equals_ci(akick->mask))
break;
}
if (i == end)
{
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
return;
}
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "UNSTICK " << akick->mask;
akick->UnsetFlag(AK_STUCK);
u->SendMessage(ChanServ, CHAN_AKICK_UNSTUCK, akick->mask.c_str(), ci->name.c_str());
}
void DoDel(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
Anope::string mask = params[2];
const Anope::string &mask = params[2];
AutoKick *akick;
unsigned i, end;
if (!ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickDelCallback list(u, ci, this, mask);
AkickDelCallback list(source, this, mask);
list.Process();
}
else
@@ -386,7 +318,7 @@ class CommandCSAKick : public Command
if (i == ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
return;
}
@@ -395,26 +327,29 @@ class CommandCSAKick : public Command
ci->EraseAkick(i);
u->SendMessage(ChanServ, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str());
source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
}
}
void DoList(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
void DoList(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string mask = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
if (!ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickListCallback list(u, ci, mask);
AkickListCallback list(source, mask);
list.Process();
}
else
@@ -436,33 +371,36 @@ class CommandCSAKick : public Command
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickListCallback::DoList(u, ci, i, akick);
AkickListCallback::DoList(source, i, akick);
}
if (!SentHeader)
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
}
void DoView(User *u, ChannelInfo *ci, const std::vector<Anope::string> &params)
void DoView(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string mask = params.size() > 2 ? params[2] : "";
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW";
if (!ci->GetAkickCount())
{
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickViewCallback list(u, ci, mask);
AkickViewCallback list(source, mask);
list.Process();
}
else
@@ -484,25 +422,27 @@ class CommandCSAKick : public Command
if (!SentHeader)
{
SentHeader = true;
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickViewCallback::DoList(u, ci, i, akick);
AkickViewCallback::DoList(source, i, akick);
}
if (!SentHeader)
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
}
void DoEnforce(User *u, ChannelInfo *ci)
void DoEnforce(CommandSource &source)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
int count = 0;
if (!c)
{
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, ci->name.c_str());
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
return;
}
@@ -517,73 +457,108 @@ class CommandCSAKick : public Command
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ENFORCE, affects " << count << " users";
u->SendMessage(ChanServ, CHAN_AKICK_ENFORCE_DONE, ci->name.c_str(), count);
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
}
void DoClear(User *u, ChannelInfo *ci)
void DoClear(CommandSource &source)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
bool override = !check_access(u, ci, CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
ci->ClearAkick();
u->SendMessage(ChanServ, CHAN_AKICK_CLEAR, ci->name.c_str());
source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
}
public:
CommandCSAKick() : Command("AKICK", 2, 4)
{
this->SetDesc(_("Maintain the AutoKick list"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn 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] : "";
ChannelInfo *ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("STICK") || cmd.equals_ci("UNSTICK") || cmd.equals_ci("DEL")))
this->OnSyntaxError(u, cmd);
else if (!check_access(u, ci, CA_AKICK) && !u->Account()->HasPriv("chanserv/access/modify"))
u->SendMessage(ChanServ, ACCESS_DENIED);
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
this->OnSyntaxError(source, cmd);
else if (!check_access(u, ci, CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
u->SendMessage(ChanServ, CHAN_AKICK_DISABLED);
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
else if (cmd.equals_ci("ADD"))
this->DoAdd(u, ci, params);
else if (cmd.equals_ci("STICK"))
this->DoStick(u, ci, params);
else if (cmd.equals_ci("UNSTICK"))
this->DoUnStick(u, ci, params);
this->DoAdd(source, params);
else if (cmd.equals_ci("DEL"))
this->DoDel(u, ci, params);
this->DoDel(source, params);
else if (cmd.equals_ci("LIST"))
this->DoList(u, ci, params);
this->DoList(source, params);
else if (cmd.equals_ci("VIEW"))
this->DoView(u, ci, params);
this->DoView(source, params);
else if (cmd.equals_ci("ENFORCE"))
this->DoEnforce(u, ci);
this->DoEnforce(source);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(u, ci);
this->DoClear(source);
else
this->OnSyntaxError(u, "");
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_AKICK);
source.Reply(_("Syntax: \002AKICK \037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]\002\n"
" \002AKICK \037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}\002\n"
" \002AKICK \037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
" \002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
" \002AKICK \037channel\037 ENFORCE\002\n"
" \002AKICK \037channel\037 CLEAR\002\n"
" \n"
"Maintains the \002AutoKick list\002 for a channel. If a user\n"
"on the AutoKick list attempts to join the channel,\n"
"%s will ban that user from the channel, then kick\n"
"the user.\n"
" \n"
"The \002AKICK ADD\002 command adds the given nick or usermask\n"
"to the AutoKick list. If a \037reason\037 is given with\n"
"the command, that reason will be used when the user is\n"
"kicked; if not, the default reason is \"You have been\n"
"banned from the channel\".\n"
"When akicking a \037registered nick\037 the nickserv account\n"
"will be added to the akick list instead of the mask.\n"
"All users within that nickgroup will then be akicked.\n"),
ChanServ->nick.c_str());
source.Reply(_(
" \n"
"The \002AKICK DEL\002 command removes the given nick or mask\n"
"from the AutoKick list. It does not, however, remove any\n"
"bans placed by an AutoKick; those must be removed\n"
"manually.\n"
" \n"
"The \002AKICK LIST\002 command displays the AutoKick list, or\n"
"optionally only those AutoKick entries which match the\n"
"given mask.\n"
" \n"
"The \002AKICK VIEW\002 command is a more verbose version of\n"
"\002AKICK LIST\002 command.\n"
" \n"
"The \002AKICK ENFORCE\002 command causes %s to enforce the\n"
"current AKICK list by removing those users who match an\n"
"AKICK mask.\n"
" \n"
"The \002AKICK CLEAR\002 command clears all entries of the\n"
"akick list."), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_AKICK);
SyntaxError(source, "AKICK", _("AKICK \037channel\037 {ADD | DEL | LIST | VIEW | ENFORCE | CLEAR} [\037nick-or-usermask\037] [\037reason\037]"));
}
};
+34 -37
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,43 +16,42 @@
class CommandCSBan : public Command
{
public:
CommandCSBan(const Anope::string &cname) : Command(cname, 2, 3)
CommandCSBan(const Anope::string &cname) : Command("BAN", 2, 3)
{
this->SetDesc(_("Bans a selected nick on a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string target = params[1];
Anope::string reason = params.size() > 2 ? params[2] : "Requested";
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
Channel *c = findchan(chan);
ChannelInfo *ci;
User *u2;
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
int is_same;
is_same = target.equals_ci(u->nick);
if (c)
ci = c->ci;
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, target.c_str());
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
/*
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2))
u->SendMessage(ChanServ, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
source.Reply(_(CHAN_EXCEPTED), u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
else
{
Anope::string mask;
@@ -76,36 +75,34 @@ class CommandCSBan : public Command
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_BAN);
source.Reply(_("Syntax: \002BAN \037#channel\037 \037nick\037 [\037reason\037]\002\n"
" \n"
"Bans a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "BAN", CHAN_BAN_SYNTAX);
}
void OnServHelp(User *u)
{
if (this->name.equals_ci("BAN"))
u->SendMessage(ChanServ, CHAN_HELP_CMD_BAN);
SyntaxError(source, "BAN", _("BAN \037#channel\037 \037nick\037 [\037reason\037]"));
}
};
class CSBan : public Module
{
CommandCSBan commandcsban, commandcskb;
CommandCSBan commandcsban;
public:
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcsban("BAN"), commandcskb("KB")
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcsban("BAN")
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsban);
this->AddCommand(ChanServ, &commandcskb);
}
};
-181
View File
@@ -1,181 +0,0 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSClear : public Command
{
public:
CommandCSClear() : Command("CLEAR", 2, 2)
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string what = params[1];
Channel *c = findchan(chan);
ChannelInfo *ci = c ? c->ci : NULL;
Anope::string modebuf;
ChannelMode *owner = ModeManager::FindChannelModeByName(CMODE_OWNER);
ChannelMode *admin = ModeManager::FindChannelModeByName(CMODE_PROTECT);
ChannelMode *op = ModeManager::FindChannelModeByName(CMODE_OP);
ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
ChannelMode *voice = ModeManager::FindChannelModeByName(CMODE_VOICE);
if (c)
// XXX
Log(LOG_COMMAND, u, this, ci) << what;
if (!c)
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
else if (!check_access(u, ci, CA_CLEAR))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (what.equals_ci("bans"))
{
c->ClearBans();
u->SendMessage(ChanServ, CHAN_CLEARED_BANS, chan.c_str());
}
else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && what.equals_ci("excepts"))
{
c->ClearExcepts();
u->SendMessage(ChanServ, CHAN_CLEARED_EXCEPTS, chan.c_str());
}
else if (ModeManager::FindChannelModeByName(CMODE_INVITE) && what.equals_ci("invites"))
{
c->ClearInvites();
u->SendMessage(ChanServ, CHAN_CLEARED_INVITES, chan.c_str());
}
else if (what.equals_ci("modes"))
{
c->ClearModes();
check_modes(c);
u->SendMessage(ChanServ, CHAN_CLEARED_MODES, chan.c_str());
}
else if (what.equals_ci("ops"))
{
if (ircd->svsmode_ucmode)
{
if (owner)
{
modebuf = "-" + owner->ModeChar;
ircdproto->SendSVSModeChan(c, modebuf, "");
}
if (admin)
{
modebuf = "-" + admin->ModeChar;
ircdproto->SendSVSModeChan(c, modebuf, "");
}
if (op)
{
modebuf = "-" + op->ModeChar;
ircdproto->SendSVSModeChan(c, modebuf, "");
}
}
else
{
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
{
UserContainer *uc = *it;
if (uc->Status->HasFlag(CMODE_OWNER))
c->RemoveMode(NULL, owner, uc->user->nick);
if (uc->Status->HasFlag(CMODE_PROTECT))
c->RemoveMode(NULL, admin, uc->user->nick);
if (uc->Status->HasFlag(CMODE_OP))
c->RemoveMode(NULL, op, uc->user->nick);
}
}
u->SendMessage(ChanServ, CHAN_CLEARED_OPS, chan.c_str());
}
else if ((halfop && what.equals_ci("hops")) || (voice && what.equals_ci("voices")))
{
ChannelMode *cm = what.equals_ci("hops") ? halfop : voice;
if (ircd->svsmode_ucmode)
{
modebuf = "-" + cm->ModeChar;
ircdproto->SendSVSModeChan(c, modebuf, "");
}
else
{
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
{
UserContainer *uc = *it;
if (uc->Status->HasFlag(cm->Name))
c->RemoveMode(NULL, cm, uc->user->nick);
}
}
}
else if (what.equals_ci("users"))
{
Anope::string buf = "CLEAR USERS command from " + u->nick;
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
UserContainer *uc = *it++;
c->Kick(NULL, uc->user, "%s", buf.c_str());
}
u->SendMessage(ChanServ, CHAN_CLEARED_USERS, chan.c_str());
}
else
SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_CLEAR);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_CLEAR);
}
};
class CSClear : public Module
{
CommandCSClear commandcsclear;
public:
CSClear(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsclear);
}
};
MODULE_INIT(CSClear)
+84
View File
@@ -0,0 +1,84 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSClearUsers : public Command
{
public:
CommandCSClearUsers() : Command("CLEARUSERS", 1, 1)
{
this->SetDesc(_("Tells ChanServ to clear (kick) all users on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
Anope::string modebuf;
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!check_access(u, ci, CA_FOUNDER))
source.Reply(_(ACCESS_DENIED));
Anope::string buf = "CLEARUSERS command from " + u->nick + " (" + u->Account()->display + ")";
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
UserContainer *uc = *it++;
c->Kick(NULL, uc->user, "%s", buf.c_str());
}
source.Reply(_("All users have been kicked from \2%s\2."), chan.c_str());
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CLEARUSERS \037channel\037\002\n"
" \n"
"Tells %s to clear (kick) all users certain settings on a channel."
" \n"
"By default, limited to those with founder access on the\n"
"channel."), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CLEAR", _("CLEARUSERS \037channel\037"));
}
};
class CSClearUsers : public Module
{
CommandCSClearUsers commandcsclearusers;
public:
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsclearusers);
}
};
MODULE_INIT(CSClearUsers)
+184
View File
@@ -0,0 +1,184 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSClone : public Command
{
public:
CommandCSClone() : Command("CLONE", 2, 3)
{
this->SetDesc(_("Copy all settings from one channel to another"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &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))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
ChannelInfo *target_ci = cs_findchan(target);
if (!target_ci)
{
source.Reply(_(CHAN_X_NOT_REGISTERED), target.c_str());
return MOD_CONT;
}
if (!IsFounder(u, ci) || !IsFounder(u, target_ci))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return MOD_CONT;
}
if (what.equals_ci("ALL"))
what.clear();
if (what.empty())
{
delete target_ci;
target_ci = new ChannelInfo(ci);
target_ci->name = target;
RegisteredChannelList[target_ci->name] = target_ci;
target_ci->c = findchan(target_ci->name);
if (target_ci->c)
{
target_ci->c->ci = target_ci;
check_modes(target_ci->c);
ChannelMode *cm;
if (u->FindChannel(target_ci->c) != NULL)
{
/* On most ircds you do not receive the admin/owner mode till its registered */
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
target_ci->c->SetMode(NULL, cm, u->nick);
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
target_ci->c->RemoveMode(NULL, cm, u->nick);
}
/* Mark the channel as persistant */
if (target_ci->c->HasMode(CMODE_PERM))
target_ci->SetFlag(CI_PERSIST);
/* Persist may be in def cflags, set it here */
else if (target_ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM)))
target_ci->c->SetMode(NULL, CMODE_PERM);
if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL)
target_ci->bi->Join(target_ci->c);
}
if (target_ci->c && !target_ci->c->topic.empty())
{
target_ci->last_topic = target_ci->c->topic;
target_ci->last_topic_setter = target_ci->c->topic_setter;
target_ci->last_topic_time = target_ci->c->topic_time;
}
else
target_ci->last_topic_setter = Config->s_ChanServ;
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci));
source.Reply(_("All settings from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("ACCESS"))
{
target_ci->ClearAccess();
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanAccess *access = ci->GetAccess(i);
target_ci->AddAccess(access->GetMask(), access->level, access->creator, access->last_seen);
}
source.Reply(_("All access entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("AKICK"))
{
target_ci->ClearAkick();
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
AutoKick *akick = ci->GetAkick(i);
if (akick->HasFlag(AK_ISNICK))
target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
else
target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
}
source.Reply(_("All akick entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("BADWORDS"))
{
target_ci->ClearBadWords();
for (unsigned i = 0; i < ci->GetBadWordCount(); ++i)
{
BadWord *bw = ci->GetBadWord(i);
target_ci->AddBadWord(bw->word, bw->type);
}
source.Reply(_("All badword entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
}
else
{
this->OnSyntaxError(source, "");
return MOD_CONT;
}
Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name;
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002CLONE \037channel\037 \037target\037 [all | access | akick | badwords]\002\n"
" \n"
"Copies all settings, access, akicks, etc from channel to the\n"
"target channel. If access, akick, or badwords is specified then only\n"
"the respective settings are transferred. You must have founder level\n"
"access to \037channel\037 and \037target\037."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "CLONE", _("CLONE \037channel\037 \037target\037"));
}
};
class CSClone : public Module
{
CommandCSClone commandcsclone;
public:
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsclone);
}
};
MODULE_INIT(CSClone)
+28 -23
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -20,36 +20,39 @@ class CommandCSDrop : public Command
{
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetDesc(_("Cancel the registration of a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
ChannelInfo *ci;
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (readonly)
{
u->SendMessage(ChanServ, CHAN_DROP_DISABLED); // XXX: READ_ONLY_MODE?
source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
return MOD_CONT;
}
ci = cs_findchan(chan);
if (ci->HasFlag(CI_FORBIDDEN) && !u->Account()->HasCommand("chanserv/drop"))
if (ci->HasFlag(CI_FORBIDDEN) && !u->HasCommand("chanserv/drop"))
{
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
if (ci->HasFlag(CI_SUSPENDED) && !u->Account()->HasCommand("chanserv/drop"))
if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop"))
{
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop"))
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
@@ -69,31 +72,33 @@ class CommandCSDrop : public Command
delete ci;
u->SendMessage(ChanServ, CHAN_DROPPED, chan.c_str());
source.Reply(_("Channel \002%s\002 has been dropped."), chan.c_str());
FOREACH_MOD(I_OnChanDrop, OnChanDrop(chan));
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (u->Account() && u->Account()->IsServicesOper())
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_DROP);
User *u = source.u;
if (u->IsServicesOper())
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Only \002Services Operators\002\n"
"can drop a channel for which they have not identified."));
else
u->SendMessage(ChanServ, CHAN_HELP_DROP);
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Can only be used by\n"
"\002channel founder\002."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DROP", CHAN_DROP_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DROP);
SyntaxError(source, "DROP", _("DROP \037channel\037"));
}
};
+31 -35
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,31 +19,32 @@ class CommandCSForbid : public Command
CommandCSForbid() : Command("FORBID", 1, 2, "chanserv/forbid")
{
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
this->SetDesc(_("Prevent a channel from being used"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci;
Anope::string chan = params[0];
Anope::string reason = params.size() > 1 ? params[1] : "";
const Anope::string &chan = params[0];
const Anope::string &reason = params.size() > 1 ? params[1] : "";
Channel *c;
User *u = source.u;
ChannelInfo *ci = source.ci;
if (Config->ForceForbidReason && reason.empty())
{
SyntaxError(ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX_REASON);
SyntaxError(source, "FORBID", _("FORBID \037channel\037 \037reason\037"));
return MOD_CONT;
}
if (chan[0] != '#')
{
u->SendMessage(ChanServ, CHAN_SYMBOL_REQUIRED);
source.Reply(_(CHAN_SYMBOL_REQUIRED));
return MOD_CONT;
}
if (readonly)
{
u->SendMessage(ChanServ, READ_ONLY_MODE);
source.Reply(_(READ_ONLY_MODE));
return MOD_CONT;
}
@@ -51,67 +52,62 @@ class CommandCSForbid : public Command
delete ci;
ci = new ChannelInfo(chan);
if (!ci)
{
// this cant happen?
//Alog() << Config->s_ChanServ << ": Valid FORBID for " << ci->name << " by " << u->nick << " failed";
u->SendMessage(ChanServ, CHAN_FORBID_FAILED, chan.c_str());
return MOD_CONT;
}
ci->SetFlag(CI_FORBIDDEN);
ci->forbidby = u->nick;
ci->forbidreason = reason;
if ((c = findchan(ci->name)))
Channel *c = ci->c;
if (c)
{
/* Before banning everyone, it might be prudent to clear +e and +I lists..
* to prevent ppl from rejoining.. ~ Viper */
c->ClearExcepts();
c->ClearInvites();
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = c->GetModeList(CMODE_EXCEPT);
for (; modes.first != modes.second; ++modes.first)
c->RemoveMode(NULL, CMODE_EXCEPT, modes.first->second);
modes = c->GetModeList(CMODE_INVITEOVERRIDE);
for (; modes.first != modes.second; ++modes.first)
c->RemoveMode(NULL, CMODE_INVITEOVERRIDE, modes.first->second);
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
UserContainer *uc = *it++;
if (is_oper(uc->user))
if (uc->user->HasMode(UMODE_OPER))
continue;
c->Kick(ChanServ, uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user, CHAN_FORBID_REASON).c_str());
c->Kick(ChanServ, uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user->Account(), "This channel has been forbidden.").c_str());
}
}
if (ircd->chansqline)
{
XLine x(chan, "Forbidden");
ircdproto->SendSQLine(&x);
ircdproto->SendSQLine(NULL, &x);
}
if (Config->WallForbid)
ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
Log(LOG_ADMIN, u, this, ci) << (!ci->forbidreason.empty() ? ci->forbidreason : "No reason");
u->SendMessage(ChanServ, CHAN_FORBID_SUCCEEDED, chan.c_str());
source.Reply(_("Channel \002%s\002 is now forbidden."), chan.c_str());
FOREACH_MOD(I_OnChanForbidden, OnChanForbidden(ci));
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_FORBID);
source.Reply(_("Syntax: \002FORBID \037channel\037 [\037reason\037]\002\n"
" \n"
"Disallows anyone from registering or using the given\n"
"channel. May be cancelled by dropping the channel.\n"
" \n"
"Reason may be required on certain networks."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_FORBID);
SyntaxError(source, "FORBID", _("FORBID \037channel\037 [\037reason\037]"));
}
};
+17 -19
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,49 +18,47 @@ class CommandCSGetKey : public Command
public:
CommandCSGetKey() : Command("GETKEY", 1, 1)
{
this->SetDesc(_("Returns the key of the given channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
ChannelInfo *ci;
Anope::string key;
const Anope::string &chan = params[0];
ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!check_access(u, ci, CA_GETKEY) && !u->Account()->HasCommand("chanserv/getkey"))
if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
Anope::string key;
if (!ci->c || !ci->c->GetParam(CMODE_KEY, key))
{
u->SendMessage(ChanServ, CHAN_GETKEY_NOKEY, chan.c_str());
source.Reply(_("The channel \002%s\002 has no key."), chan.c_str());
return MOD_CONT;
}
bool override = !check_access(u, ci, CA_GETKEY);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
u->SendMessage(ChanServ, CHAN_GETKEY_KEY, chan.c_str(), key.c_str());
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_GETKEY);
source.Reply(_("Syntax: \002GETKEY \037channel\037\002\n"
" \n"
"Returns the key of the given channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "GETKEY", CHAN_GETKEY_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_GETKEY);
SyntaxError(source, "GETKEY", _("GETKEY \037channel\037"));
}
};
+25 -10
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -20,25 +20,40 @@ class CommandCSHelp : public Command
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays this list and give information about commands"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
mod_help_cmd(ChanServ, u, params[0]);
mod_help_cmd(ChanServ, source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP);
User *u = source.u;
source.Reply(_("\002%s\002 allows you to register and control various\n"
"aspects of channels. %s can often prevent\n"
"malicious users from \"taking over\" channels by limiting\n"
"who is allowed channel operator privileges. Available\n"
"commands are listed below; to use them, type\n"
"\002%s%s \037command\037\002. For more information on a\n"
"specific command, type \002%s%s HELP \037command\037\002."),
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
ChanServ->nick.c_str());
for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission)))
it->second->OnServHelp(u);
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
if (Config->CSExpire >= 86400)
u->SendMessage(ChanServ, CHAN_HELP_EXPIRES, Config->CSExpire / 86400);
if (u->Account() && u->Account()->IsServicesOper())
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP);
source.Reply(_("Note that any channel which is not used for %d days\n"
"(i.e. which no user on the channel's access list enters\n"
"for that period of time) will be automatically dropped."), Config->CSExpire / 86400);
if (u->IsServicesOper())
source.Reply(_(" \n"
"Services Operators can also drop any channel without needing\n"
"to identify via password, and may view the access, AKICK,\n"
"and level setting lists for any channel."));
}
};
+54 -55
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -27,27 +27,30 @@ class CommandCSInfo : public Command
}
public:
CommandCSInfo() : Command("INFO", 1, 1)
CommandCSInfo() : Command("INFO", 1, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
this->SetDesc(_("Lists information about the named registered channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex");
bool show_all = false;
const Anope::string &chan = params[0];
ChannelInfo *ci = cs_findchan(chan);
User *u = source.u;
ChannelInfo *ci = source.ci;
bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex");
bool show_all = false;
if (ci->HasFlag(CI_FORBIDDEN))
{
if (is_oper(u) && !ci->forbidby.empty())
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN_OPER, chan.c_str(), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : GetString(u, NO_REASON).c_str());
if (u->HasMode(UMODE_OPER) && !ci->forbidby.empty())
source.Reply(_(CHAN_X_FORBIDDEN_OPER), chan.c_str(), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
else
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
@@ -56,78 +59,74 @@ class CommandCSInfo : public Command
if (has_auspex || check_access(u, ci, CA_INFO))
show_all = true;
u->SendMessage(ChanServ, CHAN_INFO_HEADER, chan.c_str());
u->SendMessage(ChanServ, CHAN_INFO_NO_FOUNDER, ci->founder->display.c_str());
source.Reply(_(CHAN_INFO_HEADER), chan.c_str());
source.Reply(_(" Founder: %s"), ci->founder->display.c_str());
if (show_all && ci->successor)
u->SendMessage(ChanServ, CHAN_INFO_NO_SUCCESSOR, ci->successor->display.c_str());
source.Reply(_(" Successor: %s"), ci->successor->display.c_str());
u->SendMessage(ChanServ, CHAN_INFO_DESCRIPTION, ci->desc.c_str());
u->SendMessage(ChanServ, CHAN_INFO_TIME_REGGED, do_strftime(ci->time_registered).c_str());
u->SendMessage(ChanServ, CHAN_INFO_LAST_USED, do_strftime(ci->last_used).c_str());
source.Reply(_(" Description: %s"), ci->desc.c_str());
source.Reply(_(" Registered: %s"), do_strftime(ci->time_registered).c_str());
source.Reply(_(" Last used: %s"), do_strftime(ci->last_used).c_str());
if (!ci->last_topic.empty() && (show_all || (!ci->HasMLock(CMODE_SECRET, true) && (!ci->c || !ci->c->HasMode(CMODE_SECRET)))))
ModeLock *secret = ci->GetMLock(CMODE_SECRET);
if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode(CMODE_SECRET)))))
{
u->SendMessage(ChanServ, CHAN_INFO_LAST_TOPIC, ci->last_topic.c_str());
u->SendMessage(ChanServ, CHAN_INFO_TOPIC_SET_BY, ci->last_topic_setter.c_str());
source.Reply(_(" Last topic: %s"), ci->last_topic.c_str());
source.Reply(_(" Topic set by: %s"), ci->last_topic_setter.c_str());
}
if (!ci->entry_message.empty() && show_all)
u->SendMessage(ChanServ, CHAN_INFO_ENTRYMSG, ci->entry_message.c_str());
if (show_all)
{
u->SendMessage(ChanServ, CHAN_INFO_BANTYPE, ci->bantype);
source.Reply(_(" Ban type: %d"), ci->bantype);
Anope::string optbuf;
CheckOptStr(optbuf, CI_KEEPTOPIC, GetString(u, CHAN_INFO_OPT_KEEPTOPIC), ci, u->Account());
CheckOptStr(optbuf, CI_OPNOTICE, GetString(u, CHAN_INFO_OPT_OPNOTICE), ci, u->Account());
CheckOptStr(optbuf, CI_PEACE, GetString(u, CHAN_INFO_OPT_PEACE), ci, u->Account());
CheckOptStr(optbuf, CI_PRIVATE, GetString(u, NICK_INFO_OPT_PRIVATE), ci, u->Account());
CheckOptStr(optbuf, CI_RESTRICTED, GetString(u, CHAN_INFO_OPT_RESTRICTED), ci, u->Account());
CheckOptStr(optbuf, CI_SECURE, GetString(u, CHAN_INFO_OPT_SECURE), ci, u->Account());
CheckOptStr(optbuf, CI_SECUREFOUNDER, GetString(u, CHAN_INFO_OPT_SECUREFOUNDER), ci, u->Account());
CheckOptStr(optbuf, CI_SECUREOPS, GetString(u, CHAN_INFO_OPT_SECUREOPS), ci, u->Account());
CheckOptStr(optbuf, CI_KEEPTOPIC, _("Topic Retention"), ci, u->Account());
CheckOptStr(optbuf, CI_OPNOTICE, _("OP Notice"), ci, u->Account());
CheckOptStr(optbuf, CI_PEACE, _("Peace"), ci, u->Account());
CheckOptStr(optbuf, CI_PRIVATE, _("Private"), ci, u->Account());
CheckOptStr(optbuf, CI_RESTRICTED, _("Restricted Access"), ci, u->Account());
CheckOptStr(optbuf, CI_SECURE, _("Secure"), ci, u->Account());
CheckOptStr(optbuf, CI_SECUREFOUNDER, _("Secure Founder"), ci, u->Account());
CheckOptStr(optbuf, CI_SECUREOPS, _("Secure Ops"), ci, u->Account());
if (ci->HasFlag(CI_SIGNKICK))
CheckOptStr(optbuf, CI_SIGNKICK, GetString(u, CHAN_INFO_OPT_SIGNKICK), ci, u->Account());
CheckOptStr(optbuf, CI_SIGNKICK, _("Signed kicks"), ci, u->Account());
else
CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, GetString(u, CHAN_INFO_OPT_SIGNKICK), ci, u->Account());
CheckOptStr(optbuf, CI_TOPICLOCK, GetString(u, CHAN_INFO_OPT_TOPICLOCK), ci, u->Account());
CheckOptStr(optbuf, CI_XOP, GetString(u, CHAN_INFO_OPT_XOP), ci, u->Account());
CheckOptStr(optbuf, CI_PERSIST, GetString(u, CHAN_INFO_OPT_PERSIST), ci, u->Account());
CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, _("Signed kicks"), ci, u->Account());
CheckOptStr(optbuf, CI_TOPICLOCK, _("Topic Lock"), ci, u->Account());
CheckOptStr(optbuf, CI_XOP, _("xOP lists system"), ci, u->Account());
CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, u->Account());
CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, u->Account());
u->SendMessage(ChanServ, NICK_INFO_OPTIONS, optbuf.empty() ? GetString(u, NICK_INFO_OPT_NONE).c_str() : optbuf.c_str());
u->SendMessage(ChanServ, CHAN_INFO_MODE_LOCK, get_mlock_modes(ci, 1).c_str());
source.Reply(_(NICK_INFO_OPTIONS), optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(_(" Mode lock: %s"), get_mlock_modes(ci, 1).c_str());
// XXX: we could just as easily (and tidily) merge this in with the flags display above.
if (ci->HasFlag(CI_NO_EXPIRE))
u->SendMessage(ChanServ, CHAN_INFO_NO_EXPIRE);
else
u->SendMessage(ChanServ, CHAN_INFO_EXPIRE, do_strftime(ci->last_used + Config->CSExpire).c_str());
if (!ci->HasFlag(CI_NO_EXPIRE))
source.Reply(_(" Expires on: %s"), do_strftime(ci->last_used + Config->CSExpire).c_str());
}
if (ci->HasFlag(CI_SUSPENDED))
u->SendMessage(ChanServ, CHAN_X_SUSPENDED, ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : GetString(u, NO_REASON).c_str());
source.Reply(_(" Suspended: [%s] %s"), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
FOREACH_MOD(I_OnChanInfo, OnChanInfo(u, ci, show_all));
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_INFO);
source.Reply(_("Syntax: \002INFO \037channel\037\002\n"
" \n"
"Lists information about the named registered channel,\n"
"including its founder, time of registration, last time\n"
"used, description, and mode lock, if any. If \002ALL\002 is \n"
"specified, the entry message and successor will also \n"
"be displayed."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "INFO", CHAN_INFO_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_INFO);
SyntaxError(source, "INFO", _("INFO \037channel\037"));
}
};
+24 -21
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,18 +18,20 @@ class CommandCSInvite : public Command
public:
CommandCSInvite() : Command("INVITE", 1, 3)
{
this->SetDesc(_("Tells ChanServ to invite you into a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Channel *c;
ChannelInfo *ci;
User *u2;
const Anope::string &chan = params[0];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
if (!(c = findchan(chan)))
{
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
return MOD_CONT;
}
@@ -37,17 +39,18 @@ class CommandCSInvite : public Command
if (!check_access(u, ci, CA_INVITE))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
User *u2;
if (params.size() == 1)
u2 = u;
else
{
if (!(u2 = finduser(params[1])))
{
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, params[1].c_str());
source.Reply(_(NICK_X_NOT_IN_USE), params[1].c_str());
return MOD_CONT;
}
}
@@ -56,30 +59,30 @@ class CommandCSInvite : public Command
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (c->FindUser(u2))
u->SendMessage(ChanServ, CHAN_INVITE_ALREADY_IN, c->name.c_str());
source.Reply(_("You are already in \002%s\002! "), c->name.c_str());
else
{
ircdproto->SendInvite(whosends(ci), chan, u2->nick);
u->SendMessage(whosends(ci), CHAN_INVITE_OTHER_SUCCESS, u2->nick.c_str(), c->name.c_str());
u2->SendMessage(whosends(ci), CHAN_INVITE_SUCCESS, c->name.c_str());
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
u2->SendMessage(whosends(ci), _("You have been invited to \002%s\002."), c->name.c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_INVITE);
source.Reply(_("Syntax: \002INVITE \037channel\037\002\n"
" \n"
"Tells %s to invite you into the given channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "INVITE", CHAN_INVITE_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_INVITE);
SyntaxError(source, "INVITE", _("INVITE \037channel\037"));
}
};
+33 -36
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,39 +16,38 @@
class CommandCSKick : public Command
{
public:
CommandCSKick(const Anope::string &cname) : Command(cname, 2, 3)
CommandCSKick() : Command("KICK", 2, 3)
{
this->SetDesc(_("Kicks a selected nick from a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string target = params[1];
Anope::string reason = params.size() > 2 ? params[2] : "Requested";
const Anope::string &chan = params[0];
const Anope::string &target = params[1];
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
Channel *c = findchan(chan);
ChannelInfo *ci;
User *u2;
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = ci->c;
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
int is_same;
is_same = target.equals_cs(u->nick) ? 1 : target.equals_ci(u->nick);
if (c)
ci = c->ci;
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
if (!c)
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, target.c_str());
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
else if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && get_access(u2, ci) >= get_access(u, ci))
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
else if (u2->IsProtected())
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
else if (!c->FindUser(u2))
u->SendMessage(ChanServ, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
source.Reply(_(NICK_X_NOT_ON_CHAN), u2->nick.c_str(), c->name.c_str());
else
{
// XXX
@@ -62,36 +61,34 @@ class CommandCSKick : public Command
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_KICK);
source.Reply(_("Syntax: \002KICK \037#channel\037 \037nick\037 [\037reason\037]\002\n"
" \n"
"Kicks a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "KICK", CHAN_KICK_SYNTAX);
}
void OnServHelp(User *u)
{
if (this->name.equals_ci("KICK"))
u->SendMessage(ChanServ, CHAN_HELP_CMD_KICK);
SyntaxError(source, "KICK", _("KICK \037#channel\037 \037nick\037 [\037reason\037]"));
}
};
class CSKick : public Module
{
CommandCSKick commandcskick, commandcsk;
CommandCSKick commandcskick;
public:
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcskick("KICK"), commandcsk("K")
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcskick);
this->AddCommand(ChanServ, &commandcsk);
}
};
+35 -44
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,57 +16,48 @@
class CommandCSList : public Command
{
public:
public:
CommandCSList() : Command("LIST", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Lists all registered channels matching the given pattern"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn 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->Account()->HasCommand("chanserv/list");
bool is_servadmin = u->HasCommand("chanserv/list");
int count = 0, from = 0, to = 0;
bool forbidden = false, suspended = false, channoexpire = false;
if (Config->CSListOpersOnly && !is_oper(u))
if (Config->CSListOpersOnly && !u->HasMode(UMODE_OPER))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
return MOD_STOP;
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
if (pattern[0] == '#')
{
Anope::string tmp = myStrGetToken(pattern.substr(1), '-', 0); /* Read FROM out */
if (tmp.empty())
Anope::string n1 = myStrGetToken(pattern.substr(1), '-', 0), /* Read FROM out */
n2 = myStrGetTokenRemainder(pattern, '-', 1);
try
{
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
from = convertTo<int>(n1);
to = convertTo<int>(n2);
}
catch (const ConvertException &)
{
source.Reply(_(LIST_INCORRECT_RANGE));
source.Reply(_("To search for channels starting with #, search for the channel\n"
"name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
return MOD_CONT;
}
if (!tmp.is_number_only())
{
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
return MOD_CONT;
}
from = convertTo<int>(tmp);
tmp = myStrGetTokenRemainder(pattern, '-', 1); /* Read TO out */
if (tmp.empty())
{
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
return MOD_CONT;
}
if (!tmp.is_number_only())
{
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
return MOD_CONT;
}
to = convertTo<int>(tmp);
pattern = "*";
}
@@ -89,7 +80,7 @@ public:
Anope::string spattern = "#" + pattern;
u->SendMessage(ChanServ, NICK_LIST_HEADER, pattern.c_str());
source.Reply(_(LIST_HEADER), pattern.c_str());
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
{
@@ -119,30 +110,30 @@ public:
else
snprintf(buf, sizeof(buf), "%-20s %s", ci->name.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
u->SendMessage(Config->s_ChanServ, " %c%s", noexpire_char, buf);
source.Reply(" %c%s", noexpire_char, buf);
}
++count;
}
}
u->SendMessage(ChanServ, CHAN_LIST_END, nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_LIST);
source.Reply(_("Syntax: \002LIST \037pattern\037\002\n"
" \n"
"Lists all registered channels matching the given pattern.\n"
"(Channels with the \002PRIVATE\002 option set are not listed.)\n"
"Note that a preceding '#' specifies a range, channel names\n"
"are to be written without '#'."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "LIST", NICK_LIST_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_LIST);
SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX));
}
};
+373
View File
@@ -0,0 +1,373 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandCSMode : public Command
{
bool CanSet(User *u, ChannelInfo *ci, ChannelModeName mode)
{
switch (mode)
{
case CMODE_OWNER:
return check_access(u, ci, CA_OWNER);
case CMODE_PROTECT:
return check_access(u, ci, CA_PROTECT);
case CMODE_OP:
return check_access(u, ci, CA_OPDEOP);
case CMODE_HALFOP:
return check_access(u, ci, CA_HALFOP);
case CMODE_VOICE:
return check_access(u, ci, CA_VOICE);
default:
break;
}
return false;
}
void DoLock(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
const Anope::string &subcommand = params[2];
const Anope::string &param = params.size() > 3 ? params[3] : "";
if (subcommand.equals_ci("ADD") && !param.empty())
{
spacesepstream sep(param);
Anope::string modes;
sep.GetToken(modes);
int adding = -1;
for (size_t i = 0; i < modes.length(); ++i)
{
switch (modes[i])
{
case '+':
adding = 1;
break;
case '-':
adding = 0;
break;
default:
if (adding == -1)
break;
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (!cm || !cm->CanSet(u))
{
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
break;
}
Anope::string mode_param;
if (((cm->Type == MODE_STATUS || cm->Type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->Type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
else
{
ci->SetMLock(cm, adding, mode_param, u->nick);
if (!mode_param.empty())
mode_param = " " + mode_param;
source.Reply(_("%c%c%s locked on %s"), adding ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
}
}
}
if (ci->c)
check_modes(ci->c);
}
else if (subcommand.equals_ci("DEL") && !param.empty())
{
spacesepstream sep(param);
Anope::string modes;
sep.GetToken(modes);
int adding = -1;
for (size_t i = 0; i < modes.length(); ++i)
{
switch (modes[i])
{
case '+':
adding = 1;
break;
case '-':
adding = 0;
break;
default:
if (adding == -1)
break;
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (!cm || !cm->CanSet(u))
{
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
break;
}
Anope::string mode_param;
if (!cm->Type == MODE_REGULAR && !sep.GetToken(mode_param))
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
else
{
if (ci->RemoveMLock(cm, mode_param))
{
if (!mode_param.empty())
mode_param = " " + mode_param;
source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
}
else
source.Reply(_("%c is not locked on %s."), cm->ModeChar, ci->name.c_str());
}
}
}
}
else if (subcommand.equals_ci("LIST"))
{
const std::multimap<ChannelModeName, ModeLock> &mlocks = ci->GetMLock();
if (mlocks.empty())
{
source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
}
else
{
source.Reply(_("Mode locks for %s:"), ci->name.c_str());
for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
{
const ModeLock &ml = it->second;
ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
if (!cm)
continue;
Anope::string modeparam = ml.param;
if (!modeparam.empty())
modeparam = " " + modeparam;
source.Reply(_("%c%c%s, by %s on %s"), ml.set ? '+' : '-', cm->ModeChar, modeparam.c_str(), ml.setter.c_str(), do_strftime(ml.created).c_str());
}
}
}
else
this->OnSyntaxError(source, subcommand);
}
void DoSet(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
ChannelInfo *ci = source.ci;
spacesepstream sep(params.size() > 3 ? params[3] : "");
Anope::string modes = params[2], param;
Log(LOG_COMMAND, u, this, ci) << "to set " << params[2];
int adding = -1;
for (size_t i = 0; i < modes.length(); ++i)
{
switch (modes[i])
{
case '+':
adding = 1;
break;
case '-':
adding = 0;
break;
case '*':
if (adding == -1)
break;
for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j)
{
ChannelMode *cm = ModeManager::ChannelModes[j];
if (cm->CanSet(u))
{
if (cm->Type == MODE_REGULAR || (!adding && cm->Type == MODE_PARAM))
{
if (adding)
ci->c->SetMode(NULL, cm);
else
ci->c->RemoveMode(NULL, cm);
}
}
}
break;
default:
if (adding == -1)
break;
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (!cm || !cm->CanSet(u))
continue;
switch (cm->Type)
{
case MODE_REGULAR:
if (adding)
ci->c->SetMode(NULL, cm);
else
ci->c->RemoveMode(NULL, cm);
break;
case MODE_PARAM:
if (adding && !sep.GetToken(param))
break;
if (adding)
ci->c->SetMode(NULL, cm, param);
else
ci->c->RemoveMode(NULL, cm);
break;
case MODE_STATUS:
{
if (!sep.GetToken(param))
break;
if (!this->CanSet(u, ci, cm->Name))
{
source.Reply(_("You do not have access to set mode %c."), cm->ModeChar);
break;
}
ChanAccess *u_access = ci->GetAccess(u);
int16 u_level = u_access ? u_access->level : 0;
if (str_is_wildcard(param))
{
for (CUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
UserContainer *uc = *it;
ChanAccess *targ_access = ci->GetAccess(uc->user);
int16 t_level = targ_access ? targ_access->level : 0;
if (t_level > u_level)
{
source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
continue;
}
if (Anope::Match(uc->user->GetMask(), param))
{
if (adding)
ci->c->SetMode(NULL, cm, uc->user->nick);
else
ci->c->RemoveMode(NULL, cm, uc->user->nick);
}
}
}
else
{
User *target = finduser(param);
if (target != NULL)
{
ChanAccess *targ_access = ci->GetAccess(target);
int16 t_level = targ_access ? targ_access->level : 0;
if (t_level > u_level)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
}
if (adding)
ci->c->SetMode(NULL, cm, param);
else
ci->c->RemoveMode(NULL, cm, param);
}
break;
}
case MODE_LIST:
if (!sep.GetToken(param))
break;
if (adding)
ci->c->SetMode(NULL, cm, param);
else
{
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = ci->c->GetModeList(cm->Name);
for (; its.first != its.second;)
{
const Anope::string &mask = its.first->second;
++its.first;
if (Anope::Match(mask, param))
ci->c->RemoveMode(NULL, cm, mask);
}
}
}
}
}
}
public:
CommandCSMode() : Command("MODE", 3, 4)
{
this->SetDesc(_("Control modes and mode locks on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &subcommand = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
if (!ci || !ci->c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/mode"))
source.Reply(_(ACCESS_DENIED));
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, params);
else if (subcommand.equals_ci("SET"))
this->DoSet(source, params);
else
this->OnSyntaxError(source, "");
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002MODE \037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]\002\n"
" \002MODE \037channel\037 SET \037modes\037\002\n"
" \n"
"Mainly controls mode locks and mode access (which is different from channel access)\n"
"on a channel.\n"
" \n"
"The \002MODE LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
"If a mode is locked on or off, services will not allow that mode to be changed.\n"
"Example:\n"
" \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n"
" \n"
"The \002MODE SET\002 command allows you to set modes through services. Wildcards * and ? may\n"
"be given as parameters for list and status modes.\n"
"Example:\n"
" \002MODE #channel SET +v *\002\n"
" Sets voice status to all users in the channel.\n"
" \n"
" \002MODE #channel SET -b ~c:*\n"
" Clears all extended bans that start with ~c:"));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "MODE", _("MODE \037channel\037 {LOCK|SET} [\037modes\037 | {ADD|DEL|LIST} [\037what\037]]"));
}
};
class CSMode : public Module
{
CommandCSMode commandcsmode;
public:
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->AddCommand(ChanServ, &commandcsmode);
}
};
MODULE_INIT(CSMode)
+304 -252
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -13,381 +13,433 @@
#include "module.h"
/** do_util: not a command, but does the job of others
* @param u The user doing the command
* @param com The command calling this function
* @param cm A channel mode class
* @param chan The channel its being set on
* @param nick The nick the modes being set on
* @param set Is the mode being set or removed
* @param level The acecss level required to set this mode on someone else
* @param levelself The access level required to set this mode on yourself
* @param name The name, eg "OP" or "HALFOP"
* @param notice Flag required on a channel to send a notice
*/
static CommandReturn do_util(User *u, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, const Anope::string &name, ChannelInfoFlag notice)
class CommandModeBase : public Command
{
Channel *c = findchan(chan);
ChannelInfo *ci = c ? c->ci : NULL;
User *u2;
Anope::string realnick = (!nick.empty() ? nick : u->nick);
bool is_same = u->nick.equals_ci(realnick);
if (!c)
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
else if (is_same ? !(u2 = u) : !(u2 = finduser(realnick)))
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, realnick.c_str());
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (!set && u2->IsProtected() && !is_same)
u->SendMessage(ChanServ, ACCESS_DENIED);
else if (!c->FindUser(u2))
u->SendMessage(ChanServ, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else
protected:
/** do_util: not a command, but does the job of others
* @param source The source of the command
* @param com The command calling this function
* @param cm A channel mode class
* @param chan The channel its being set on
* @param nick The nick the modes being set on
* @param set Is the mode being set or removed
* @param level The acecss level required to set this mode on someone else
* @param levelself The access level required to set this mode on yourself
* @param notice Flag required on a channel to send a notice
*/
CommandReturn do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
{
if (set)
c->SetMode(NULL, cm, u2->nick);
User *u = source.u;
if (chan.empty())
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it)
do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself, notice);
else
c->RemoveMode(NULL, cm, u2->nick);
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself, notice);
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", name.c_str(), u2->nick.c_str(), u->nick.c_str());
return MOD_CONT;
}
return MOD_CONT;
}
class CommandCSOp : public Command
{
public:
CommandCSOp() : Command("OP", 1, 2)
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
{
}
User *u = source.u;
User *u2 = finduser(nick);
Channel *c = findchan(chan);
ChannelInfo *ci = c ? c->ci : NULL;
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
bool is_same = u == u2;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, "OP", CI_OPNOTICE);
}
ChanAccess *u_access = ci ? ci->GetAccess(u) : NULL, *u2_access = ci && u2 ? ci->GetAccess(u2) : NULL;
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_OP);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "OP", CHAN_OP_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_OP);
}
};
class CommandCSDeOp : public Command
{
public:
CommandCSDeOp() : Command("DEOP", 1, 2)
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, "DEOP", CI_OPNOTICE);
}
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_DEOP);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DEOP", CHAN_DEOP_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEOP);
}
};
class CommandCSVoice : public Command
{
public:
CommandCSVoice() : Command("VOICE", 1, 2)
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, "VOICE", CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_VOICE);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "VOICE", CHAN_VOICE_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_VOICE);
}
};
class CommandCSDeVoice : public Command
{
public:
CommandCSDeVoice() : Command("DEVOICE", 1, 2)
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, "DEVOICE", CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_DEVOICE);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DEVOICE", CHAN_DEVOICE_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEVOICE);
}
};
class CommandCSHalfOp : public Command
{
public:
CommandCSHalfOp() : Command("HALFOP", 1, 2)
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
else if (!ci)
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
else if (!u2)
source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str());
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
source.Reply(_(ACCESS_DENIED));
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
source.Reply(_(ACCESS_DENIED));
else if (!set && u2->IsProtected() && !is_same)
source.Reply(_(ACCESS_DENIED));
else if (!c->FindUser(u2))
source.Reply(_(NICK_X_NOT_ON_CHAN), u2->nick.c_str(), c->name.c_str());
else
{
return MOD_CONT;
}
if (set)
c->SetMode(NULL, cm, u2->nick);
else
c->RemoveMode(NULL, cm, u2->nick);
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, "HALFOP", CI_BEGIN);
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
}
}
bool OnHelp(User *u, const Anope::string &subcommand)
public:
CommandModeBase(const Anope::string &cname) : Command(cname, 0, 2) { }
};
class CommandCSOp : public CommandModeBase
{
public:
CommandCSOp() : CommandModeBase("OP")
{
u->SendMessage(ChanServ, CHAN_HELP_HALFOP);
this->SetDesc(_("Gives Op status to a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002OP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Ops a selected nick on a channel. If nick is not given,\n"
"it will op you. If channel is not given, it will op you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "HALFOP", CHAN_HALFOP_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_HALFOP);
SyntaxError(source, "OP", _("OP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeHalfOp : public Command
class CommandCSDeOp : public CommandModeBase
{
public:
CommandCSDeHalfOp() : Command("DEHALFOP", 1, 2)
CommandCSDeOp() : CommandModeBase("DEOP")
{
this->SetDesc(_("Deops a selected nick on a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Deops a selected nick on a channel. If nick is not given,\n"
"it will deop you. If channel is not given, it will deop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEOP", _("DEOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSVoice : public CommandModeBase
{
public:
CommandCSVoice() : CommandModeBase("VOICE")
{
this->SetDesc(_("Voices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002VOICE [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Voices a selected nick on a channel. If nick is not given,\n"
"it will voice you. If channel is not given, it will voice you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel, or to VOPs or those with level 3 \n"
"and above for self voicing."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "VOICE", _("VOICE [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeVoice : public CommandModeBase
{
public:
CommandCSDeVoice() : CommandModeBase("DEVOICE")
{
this->SetDesc(_("Devoices a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEVOICE [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Devoices a selected nick on a channel. If nick is not given,\n"
"it will devoice you. If channel is not given, it will devoice\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel, or to VOPs or those with level 3 \n"
"and above for self devoicing."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEVOICE", _("DEVOICE [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSHalfOp : public CommandModeBase
{
public:
CommandCSHalfOp() : CommandModeBase("HALFOP")
{
this->SetDesc(_("Halfops a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, "DEHALFOP", CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_DEHALFOP);
source.Reply(_("Syntax: \002HALFOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Halfops a selected nick on a channel. If nick is not given,\n"
"it will halfop you. If channel is not given, it will halfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access \n"
"and above on the channel, or to HOPs or those with level 4 \n"));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DEHALFOP", CHAN_DEHALFOP_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEHALFOP);
SyntaxError(source, "HALFOP", _("HALFOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSProtect : public Command
class CommandCSDeHalfOp : public CommandModeBase
{
public:
CommandCSProtect() : Command("PROTECT", 1, 2)
CommandCSDeHalfOp() : CommandModeBase("DEHALFOP")
{
this->SetDesc(_("Dehalfops a selected nick on a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return MOD_CONT;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: \002DEHALFOP [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Dehalfops a selected nick on a channel. If nick is not given,\n"
"it will dehalfop you. If channel is not given, it will dehalfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access \n"
"and above on the channel, or to HOPs or those with level 4 \n"
"and above for self dehalfopping."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(source, "DEHALFOP", _("DEHALFOP [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSProtect : public CommandModeBase
{
public:
CommandCSProtect() : CommandModeBase("PROTECT")
{
this->SetDesc(_("Protects a selected nick on a channel"));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, "PROTECT", CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_PROTECT);
source.Reply(_("Syntax: \002PROTECT [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Protects a selected nick on a channel. If nick is not given,\n"
"it will protect you. If channel is not given, it will protect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with \n"
"level 10 and above on the channel for self protecting."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "PROTECT", CHAN_PROTECT_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_PROTECT);
SyntaxError(source, "PROTECT", _("PROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeProtect : public Command
class CommandCSDeProtect : public CommandModeBase
{
public:
CommandCSDeProtect() : Command("DEPROTECT", 1, 2)
CommandCSDeProtect() : CommandModeBase("DEPROTECT")
{
this->SetDesc(_("Deprotects a selected nick on a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return MOD_CONT;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, "DEPROTECT", CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_DEPROTECT);
source.Reply(_("Syntax: \002DEPROTECT [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Deprotects a selected nick on a channel. If nick is not given,\n"
"it will deprotect you. If channel is not given, it will deprotect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with \n"));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DEPROTECT", CHAN_DEPROTECT_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEPROTECT);
SyntaxError(source, "DEPROTECT", _("DEROTECT [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSOwner : public Command
class CommandCSOwner : public CommandModeBase
{
public:
CommandCSOwner() : Command("OWNER", 1, 2)
CommandCSOwner() : CommandModeBase("OWNER")
{
this->SetDesc(_("Gives you owner status on channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, "OWNER", CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_OWNER);
source.Reply(_("Syntax: \002OWNER [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Gives the selected nick owner status on \002channel\002. If nick is not\n"
"given, it will give you owner. If channel is not given, it will\n"
"give you owner on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "OWNER", CHAN_OWNER_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_OWNER);
SyntaxError(source, "OWNER", _("OWNER [\037#channel\037] [\037nick\037]\002"));
}
};
class CommandCSDeOwner : public Command
class CommandCSDeOwner : public CommandModeBase
{
public:
CommandCSDeOwner() : Command("DEOWNER", 1, 2)
CommandCSDeOwner() : CommandModeBase("DEOWNER")
{
this->SetDesc(_("Removes your owner status on a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return MOD_CONT;
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, "DEOWNER", CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, CI_BEGIN);
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_DEOWNER);
source.Reply(_("Syntax: \002DEOWNER [\037#channel\037] [\037nick\037]\002\n"
" \n"
"Removes owner status from the selected nick on \002channel\002. If nick\n"
"is not given, it will deowner you. If channel is not given, it will\n"
"deowner you on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "DEOWNER", CHAN_DEOWNER_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEOWNER);
SyntaxError(source, "DEOWNER", _("DEOWNER [\037#channel\037] [\037nick\037]\002"));
}
};
+56 -31
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,39 +19,39 @@ class CommandCSRegister : public Command
CommandCSRegister() : Command("REGISTER", 2, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
this->SetDesc(_("Register a channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string chan = params[0];
Anope::string desc = params[1];
const Anope::string &chan = params[0];
const Anope::string &chdesc = params[1];
User *u = source.u;
ChannelInfo *ci = source.ci;
Channel *c = findchan(chan);
ChannelInfo *ci;
ChannelMode *cm;
if (readonly)
{
u->SendMessage(ChanServ, CHAN_REGISTER_DISABLED);
return MOD_CONT;
}
if (chan[0] == '&')
u->SendMessage(ChanServ, CHAN_REGISTER_NOT_LOCAL);
source.Reply(_("Sorry, channel registration is temporarily disabled."));
else if (u->Account()->HasFlag(NI_UNCONFIRMED))
source.Reply(_("You must confirm your account before you can register a channel."));
else if (chan[0] == '&')
source.Reply(_("Local channels cannot be registered."));
else if (chan[0] != '#')
u->SendMessage(ChanServ, CHAN_SYMBOL_REQUIRED);
source.Reply(_(CHAN_SYMBOL_REQUIRED));
else if (!ircdproto->IsChannelValid(chan))
u->SendMessage(ChanServ, CHAN_X_INVALID, chan.c_str());
else if ((ci = cs_findchan(chan)))
u->SendMessage(ChanServ, CHAN_ALREADY_REGISTERED, chan.c_str());
source.Reply(_(CHAN_X_INVALID), chan.c_str());
else if (ci)
source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
else if (c && !c->HasUserStatus(u, CMODE_OP))
u->SendMessage(ChanServ, CHAN_MUST_BE_CHANOP);
else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
u->SendMessage(ChanServ, u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg);
source.Reply(_("You must be a channel operator to register the channel."));
else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
else
{
ci = new ChannelInfo(chan);
ci->founder = u->Account();
ci->desc = desc;
ci->desc = chdesc;
if (c && !c->topic.empty())
{
@@ -65,17 +65,22 @@ class CommandCSRegister : public Command
ci->bi = NULL;
++ci->founder->channelcount;
Log(LOG_COMMAND, u, this, ci);
u->SendMessage(ChanServ, CHAN_REGISTERED, chan.c_str(), u->nick.c_str());
source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str());
/* Implement new mode lock */
if (c)
{
check_modes(c);
/* On most ircds you do not receive the admin/owner mode till its registered */
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
c->SetMode(NULL, cm, u->nick);
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
c->RemoveMode(NULL, cm, u->nick);
ChannelMode *cm;
if (u->FindChannel(c) != NULL)
{
/* On most ircds you do not receive the admin/owner mode till its registered */
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
c->SetMode(NULL, cm, u->nick);
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
c->RemoveMode(NULL, cm, u->nick);
}
/* Mark the channel as persistant */
if (c->HasMode(CMODE_PERM))
@@ -90,15 +95,35 @@ class CommandCSRegister : public Command
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
u->SendMessage(ChanServ, CHAN_HELP_REGISTER, Config->s_ChanServ.c_str());
source.Reply(_("Syntax: \002REGISTER \037channel\037 \037description\037\002\n"
" \n"
"Registers a channel in the %s database. In order\n"
"to use this command, you must first be a channel operator\n"
"on the channel you're trying to register.\n"
"The description, which \002must\002 be included, is a\n"
"general description of the channel's purpose.\n"
" \n"
"When you register a channel, you are recorded as the\n"
"\"founder\" of the channel. The channel founder is allowed\n"
"to change all of the channel settings for the channel;\n"
"%s will also automatically give the founder\n"
"channel-operator privileges when s/he enters the channel.\n"
"See the \002ACCESS\002 command (\002%s%s HELP ACCESS\002) for\n"
"information on giving a subset of these privileges to\n"
"other channel users.\n"
" \n"
"NOTICE: In order to register a channel, you must have\n"
"first registered your nickname. If you haven't,\n"
"\002%s%s HELP\002 for information on how to do so."),
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX);
SyntaxError(source, "REGISTER", _("REGISTER \037channel\037 \037description\037"));
}
};
+33 -20
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -21,6 +21,7 @@ class CommandCSSASet : public Command
public:
CommandCSSASet() : Command("SASET", 2, 3)
{
this->SetDesc(_("Forcefully set channel options and information"));
}
~CommandCSSASet()
@@ -28,11 +29,20 @@ class CommandCSSASet : public Command
this->subcommands.clear();
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
if (readonly)
{
u->SendMessage(ChanServ, CHAN_SET_DISABLED);
source.Reply(_(CHAN_SET_DISABLED));
return MOD_CONT;
}
// XXX Remove after 1.9.4 release
if (params[1].equals_ci("MLOCK"))
{
source.Reply(_(CHAN_SET_MLOCK_DEPRECATED), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return MOD_CONT;
}
@@ -40,30 +50,36 @@ class CommandCSSASet : public Command
if (c)
{
ChannelInfo *ci = cs_findchan(params[0]);
ChannelInfo *ci = source.ci;
Anope::string cmdparams = ci->name;
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
cmdparams += " " + *it;
Log(LOG_ADMIN, u, this, ci) << params[1] << " " << cmdparams;
mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
}
else
{
u->SendMessage(ChanServ, NICK_SET_UNKNOWN_OPTION, params[1].c_str());
u->SendMessage(ChanServ, MORE_INFO, Config->s_ChanServ.c_str(), "SET");
source.Reply(_("Unknown SASET option \002%s\002."), params[1].c_str());
source.Reply(_(MORE_INFO), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), "SET");
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
{
u->SendMessage(ChanServ, CHAN_HELP_SASET_HEAD);
source.Reply(_("Syntax: SASET \002channel\002 \037option\037 \037parameters\037\n"
" \n"
"Allows Services Operators to forcefully change settings\n"
"on channels.\n"
" \n"
"Available options:"));
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
it->second->OnServHelp(u);
u->SendMessage(ChanServ, CHAN_HELP_SASET_TAIL);
it->second->OnServHelp(source);
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
return true;
}
else
@@ -71,24 +87,21 @@ class CommandCSSASet : public Command
Command *c = this->FindCommand(subcommand);
if (c)
return c->OnHelp(u, subcommand);
return c->OnHelp(source, subcommand);
}
return false;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_SASET);
}
bool AddSubcommand(Command *c)
bool AddSubcommand(Module *creator, Command *c)
{
c->module = creator;
c->service = this->service;
return this->subcommands.insert(std::make_pair(c->name, c)).second;
}
+15 -16
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,44 +18,43 @@ class CommandCSSASetNoexpire : public Command
public:
CommandCSSASetNoexpire() : Command("NOEXPIRE", 2, 2, "chanserv/saset/noexpire")
{
this->SetDesc(_("Prevent the channel from expiring"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = cs_findchan(params[0]);
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSASetNoexpire");
if (params[1].equals_ci("ON"))
{
ci->SetFlag(CI_NO_EXPIRE);
u->SendMessage(ChanServ, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str());
}
else if (params[1].equals_ci("OFF"))
{
ci->UnsetFlag(CI_NO_EXPIRE);
u->SendMessage(ChanServ, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str());
}
else
this->OnSyntaxError(u, "NOEXPIRE");
this->OnSyntaxError(source, "NOEXPIRE");
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &)
bool OnHelp(CommandSource &source, const Anope::string &)
{
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
source.Reply(_("Syntax: \002SET \037channel\037 NOEXPIRE {ON | OFF}\002\n"
" \n"
"Sets whether the given channel will expire. Setting this\n"
"to ON prevents the channel from expiring."));
return true;
}
void OnSyntaxError(User *u, const Anope::string &)
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
SyntaxError(ChanServ, u, "SET NOEXPIRE", CHAN_SET_NOEXPIRE_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_NOEXPIRE);
SyntaxError(source, "SET NOEXPIRE", _("SET \037channel\037 NOEXPIRE {ON | OFF}"));
}
};
@@ -71,7 +70,7 @@ class CSSetNoexpire : public Module
Command *c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(&commandcssasetnoexpire);
c->AddSubcommand(this, &commandcssasetnoexpire);
}
~CSSetNoexpire()
+34 -21
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -21,6 +21,7 @@ class CommandCSSet : public Command
public:
CommandCSSet() : Command("SET", 2, 3)
{
this->SetDesc(_("Set channel options and information"));
}
~CommandCSSet()
@@ -28,16 +29,25 @@ class CommandCSSet : public Command
this->subcommands.clear();
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
User *u = source.u;
if (readonly)
{
u->SendMessage(ChanServ, CHAN_SET_DISABLED);
source.Reply(_(CHAN_SET_DISABLED));
return MOD_CONT;
}
if (!check_access(u, cs_findchan(params[0]), CA_SET))
{
u->SendMessage(ChanServ, ACCESS_DENIED);
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
}
// XXX Remove after 1.9.4 release
if (params[1].equals_ci("MLOCK"))
{
source.Reply(_(CHAN_SET_MLOCK_DEPRECATED), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return MOD_CONT;
}
@@ -45,29 +55,35 @@ class CommandCSSet : public Command
if (c)
{
ChannelInfo *ci = cs_findchan(params[0]);
ChannelInfo *ci = source.ci;
Anope::string cmdparams = ci->name;
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
cmdparams += " " + *it;
mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
}
else
{
u->SendMessage(ChanServ, NICK_SET_UNKNOWN_OPTION, params[1].c_str());
u->SendMessage(ChanServ, MORE_INFO, Config->s_ChanServ.c_str(), "SET");
source.Reply(_(NICK_SET_UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), params[1].c_str());
source.Reply(_(MORE_INFO), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), "SET");
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
if (subcommand.empty())
{
u->SendMessage(ChanServ, CHAN_HELP_SET_HEAD);
source.Reply(_("Syntax: \002SET \037channel\037 \037option\037 \037parameters\037\002\n"
" \n"
"Allows the channel founder to set various channel options\n"
"and other information.\n"
" \n"
"Available options:"));
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
it->second->OnServHelp(u);
u->SendMessage(ChanServ, CHAN_HELP_SET_TAIL);
it->second->OnServHelp(source);
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
"particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
return true;
}
else
@@ -75,24 +91,21 @@ class CommandCSSet : public Command
Command *c = this->FindCommand(subcommand);
if (c)
return c->OnHelp(u, subcommand);
return c->OnHelp(source, subcommand);
}
return false;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET);
}
bool AddSubcommand(Command *c)
bool AddSubcommand(Module *creator, Command *c)
{
c->module = creator;
c->service = this->service;
return this->subcommands.insert(std::make_pair(c->name, c)).second;
}
+29 -31
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,44 +18,48 @@ class CommandCSSetBanType : public Command
public:
CommandCSSetBanType(const Anope::string &cpermission = "") : Command("BANTYPE", 2, 2, cpermission)
{
this->SetDesc(_("Set how Services make bans on the channel"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = cs_findchan(params[0]);
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetBanType");
Anope::string end;
int16 bantype = convertTo<int16>(params[1], end, false);
if (!end.empty() || bantype < 0 || bantype > 3)
u->SendMessage(ChanServ, CHAN_SET_BANTYPE_INVALID, params[1].c_str());
else
try
{
ci->bantype = bantype;
u->SendMessage(ChanServ, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), ci->bantype);
ci->bantype = convertTo<int16>(params[1]);
source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
}
catch (const ConvertException &)
{
source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &)
bool OnHelp(CommandSource &source, const Anope::string &)
{
u->SendMessage(ChanServ, CHAN_HELP_SET_BANTYPE, "SET");
source.Reply(_("Syntax: \002%s \037channel\037 BANTYPE \037bantype\037\002\n"
" \n"
"Sets the ban type that will be used by services whenever\n"
"they need to ban someone from your channel.\n"
" \n"
"bantype is a number between 0 and 3 that means:\n"
" \n"
"0: ban in the form *!user@host\n"
"1: ban in the form *!*user@host\n"
"2: ban in the form *!*@host\n"
"3: ban in the form *!*user@*.domain"), this->name.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &)
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_BANTYPE);
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
@@ -66,16 +70,10 @@ class CommandCSSASetBanType : public CommandCSSetBanType
{
}
bool OnHelp(User *u, const Anope::string &)
{
u->SendMessage(ChanServ, CHAN_HELP_SET_BANTYPE, "SASET");
return true;
}
void OnSyntaxError(User *u, const Anope::string &)
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
@@ -92,11 +90,11 @@ class CSSetBanType : public Module
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(&commandcssetbantype);
c->AddSubcommand(this, &commandcssetbantype);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(&commandcssasetbantype);
c->AddSubcommand(this, &commandcssasetbantype);
}
~CSSetBanType()
+16 -23
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2010 Anope Team
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,36 +18,35 @@ class CommandCSSetDescription : public Command
public:
CommandCSSetDescription(const Anope::string &cpermission = "") : Command("DESC", 2, 2, cpermission)
{
this->SetDesc(_("Set the channel description"));
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
ChannelInfo *ci = cs_findchan(params[0]);
ChannelInfo *ci = source.ci;
if (!ci)
throw CoreException("NULL ci in CommandCSSetDescription");
ci->desc = params[1];
u->SendMessage(ChanServ, CHAN_DESC_CHANGED, ci->name.c_str(), ci->desc.c_str());
source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &)
bool OnHelp(CommandSource &source, const Anope::string &)
{
u->SendMessage(ChanServ, CHAN_HELP_SET_DESC, "SET");
source.Reply(_("Syntax: \002%s \037channel\037 DESC \037description\037\002\n"
" \n"
"Sets the description for the channel, which shows up with\n"
"the \002LIST\002 and \002INFO\002 commands."), this->name.c_str());
return true;
}
void OnSyntaxError(User *u, const Anope::string &)
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_DESC);
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
}
};
@@ -58,16 +57,10 @@ class CommandCSSASetDescription : public CommandCSSetDescription
{
}
bool OnHelp(User *u, const Anope::string &)
{
u->SendMessage(ChanServ, CHAN_HELP_SET_DESC, "SASET");
return true;
}
void OnSyntaxError(User *u, const Anope::string &)
void OnSyntaxError(CommandSource &source, const Anope::string &)
{
// XXX
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
}
};
@@ -84,11 +77,11 @@ class CSSetDescription : public Module
Command *c = FindCommand(ChanServ, "SET");
if (c)
c->AddSubcommand(&commandcssetdescription);
c->AddSubcommand(this, &commandcssetdescription);
c = FindCommand(ChanServ, "SASET");
if (c)
c->AddSubcommand(&commandcssasetdescription);
c->AddSubcommand(this, &commandcssasetdescription);
}
~CSSetDescription()

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